From 40301e9ae5f23391634853fff2daff60ae99aedd Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Fri, 4 Aug 2023 09:46:22 +0200 Subject: [PATCH 01/39] copy all types --- .gitignore | 3 +- src/types/Address.ts | 35 ++++++++++ src/types/Attestation.ts | 19 ++++++ src/types/CType.ts | 62 +++++++++++++++++ src/types/Claim.ts | 22 +++++++ src/types/Credential.ts | 31 +++++++++ src/types/Delegation.ts | 32 +++++++++ src/types/DidDocument.ts | 29 ++++++++ src/types/Imported.ts | 17 +++++ src/types/Message.ts | 139 +++++++++++++++++++++++++++++++++++++++ src/types/Quote.ts | 34 ++++++++++ src/types/Terms.ts | 20 ++++++ src/types/index.ts | 2 + 13 files changed, 444 insertions(+), 1 deletion(-) create mode 100644 src/types/Address.ts create mode 100644 src/types/Attestation.ts create mode 100644 src/types/CType.ts create mode 100644 src/types/Claim.ts create mode 100644 src/types/Credential.ts create mode 100644 src/types/Delegation.ts create mode 100644 src/types/DidDocument.ts create mode 100644 src/types/Imported.ts create mode 100644 src/types/Message.ts create mode 100644 src/types/Quote.ts create mode 100644 src/types/Terms.ts diff --git a/.gitignore b/.gitignore index 7422952..c044059 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ /node_modules yarn.lock yarn-error.log +/.vscode *.js -*.d.ts \ No newline at end of file +*.d.ts diff --git a/src/types/Address.ts b/src/types/Address.ts new file mode 100644 index 0000000..9ee9edf --- /dev/null +++ b/src/types/Address.ts @@ -0,0 +1,35 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import '@polkadot/keyring' // TS needs this for the augmentation below + +import type { HexString, KeyringPair, Prefix } from './Imported' + +export interface KiltEncryptionKeypair { + secretKey: Uint8Array + publicKey: Uint8Array + type: 'x25519' +} + +export interface KiltKeyringPair extends KeyringPair { + address: `4${string}` + type: Exclude +} + +/// A KILT-chain specific address, encoded with the KILT 38 network prefix. +export type KiltAddress = KiltKeyringPair['address'] + +declare module '@polkadot/keyring' { + function encodeAddress( + key: HexString | Uint8Array | string, + ss58Format?: Prefix + ): string + function encodeAddress( + key: HexString | Uint8Array | string, + ss58Format?: 38 + ): KiltAddress +} diff --git a/src/types/Attestation.ts b/src/types/Attestation.ts new file mode 100644 index 0000000..0f42f89 --- /dev/null +++ b/src/types/Attestation.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import type { DidUri } from './DidDocument' +import type { IDelegationNode } from './Delegation' +import type { ICredential } from './Credential' +import type { CTypeHash } from './CType' + +export interface IAttestation { + claimHash: ICredential['rootHash'] + cTypeHash: CTypeHash + owner: DidUri + delegationId: IDelegationNode['id'] | null + revoked: boolean +} diff --git a/src/types/CType.ts b/src/types/CType.ts new file mode 100644 index 0000000..7ab4452 --- /dev/null +++ b/src/types/CType.ts @@ -0,0 +1,62 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import type { HexString } from './Imported' + +export type InstanceType = 'boolean' | 'integer' | 'number' | 'string' | 'array' + +export type CTypeHash = HexString + +interface TypePattern { + type: InstanceType +} + +interface StringPattern extends TypePattern { + type: 'string' + format?: 'date' | 'time' | 'uri' + enum?: string[] + minLength?: number + maxLength?: number +} + +interface NumberPattern extends TypePattern { + type: 'integer' | 'number' + enum?: number[] + minimum?: number + maximum?: number +} + +interface BooleanPattern extends TypePattern { + type: 'boolean' +} + +interface RefPattern { + $ref: string +} + +interface ArrayPattern extends TypePattern { + type: 'array' + items: BooleanPattern | NumberPattern | StringPattern | RefPattern + minItems?: number + maxItems?: number +} + +export interface ICType { + $id: `kilt:ctype:${CTypeHash}` + $schema: string + title: string + properties: { + [key: string]: + | BooleanPattern + | NumberPattern + | StringPattern + | ArrayPattern + | RefPattern + } + type: 'object' + additionalProperties?: false +} diff --git a/src/types/Claim.ts b/src/types/Claim.ts new file mode 100644 index 0000000..3a22efb --- /dev/null +++ b/src/types/Claim.ts @@ -0,0 +1,22 @@ +import type { CTypeHash } from './CType' +import type { DidUri } from './DidDocument' + +type ClaimPrimitives = string | number | boolean + +export interface IClaimContents { + [key: string]: + | ClaimPrimitives + | IClaimContents + | Array +} + +export interface IClaim { + cTypeHash: CTypeHash + contents: IClaimContents + owner: DidUri +} + +/** + * The minimal partial claim from which a JSON-LD representation can be built. + */ +export type PartialClaim = Partial & Pick diff --git a/src/types/Credential.ts b/src/types/Credential.ts new file mode 100644 index 0000000..7ea232f --- /dev/null +++ b/src/types/Credential.ts @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import type { IClaim } from './Claim' +import type { IDelegationNode } from './Delegation' +import type { HexString } from './Imported' +import type { DidSignature } from './DidDocument' + +export type Hash = HexString + +export type NonceHash = { + hash: Hash + nonce?: string +} + +export interface ICredential { + claim: IClaim + claimNonceMap: Record + claimHashes: Hash[] + delegationId: IDelegationNode['id'] | null + legitimations: ICredential[] + rootHash: Hash +} + +export interface ICredentialPresentation extends ICredential { + claimerSignature: DidSignature & { challenge?: string } +} diff --git a/src/types/Delegation.ts b/src/types/Delegation.ts new file mode 100644 index 0000000..046b256 --- /dev/null +++ b/src/types/Delegation.ts @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import type { CTypeHash } from './CType' +import type { DidUri } from './DidDocument' + +/* eslint-disable no-bitwise */ +export const Permission = { + ATTEST: 1 << 0, // 0001 + DELEGATE: 1 << 1, // 0010 +} as const + +export type PermissionType = (typeof Permission)[keyof typeof Permission] + +export interface IDelegationNode { + id: string + hierarchyId: IDelegationNode['id'] + parentId?: IDelegationNode['id'] + childrenIds: Array + account: DidUri + permissions: PermissionType[] + revoked: boolean +} + +export interface IDelegationHierarchyDetails { + id: IDelegationNode['id'] + cTypeHash: CTypeHash +} diff --git a/src/types/DidDocument.ts b/src/types/DidDocument.ts new file mode 100644 index 0000000..bada33a --- /dev/null +++ b/src/types/DidDocument.ts @@ -0,0 +1,29 @@ +import type { KiltAddress } from './Address' + +/** + * A string containing a KILT DID Uri. + */ + + +type DidUriVersion = '' | `v${string}:` +type AuthenticationKeyType = '00' | '01' +type LightDidEncodedData = '' | `:${string}` + +export type DidUri = + | `did:kilt:${DidUriVersion}${KiltAddress}` + | `did:kilt:light:${DidUriVersion}${AuthenticationKeyType}${KiltAddress}${LightDidEncodedData}` + +/** + * The fragment part of the DID URI including the `#` character. + */ +export type UriFragment = `#${string}` +/** + * URI for DID resources like keys or service endpoints. + */ +export type DidResourceUri = `${DidUri}${UriFragment}` + + +export type DidSignature = { + keyUri: DidResourceUri + signature: string + } diff --git a/src/types/Imported.ts b/src/types/Imported.ts new file mode 100644 index 0000000..f832284 --- /dev/null +++ b/src/types/Imported.ts @@ -0,0 +1,17 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +export type { + ISubmittableResult, + AnyNumber, + AnyJson, +} from '@polkadot/types/types' +export type { BN } from '@polkadot/util' +export type { HexString } from '@polkadot/util/types' +export type { Prefix } from '@polkadot/util-crypto/address/types' +export type { SubmittableExtrinsic } from '@polkadot/api/promise/types' +export type { KeyringPair } from '@polkadot/keyring/types' diff --git a/src/types/Message.ts b/src/types/Message.ts new file mode 100644 index 0000000..42620cb --- /dev/null +++ b/src/types/Message.ts @@ -0,0 +1,139 @@ +import type { ITerms } from './Terms' +import type { ICredential, ICredentialPresentation } from './Credential' +import type { IQuoteAgreement } from './Quote' +import type { IAttestation } from './Attestation' +import type { CTypeHash } from './CType' +import type { DidUri } from './DidDocument' + +export type MessageBodyType = + | 'error' + | 'reject' + | 'submit-terms' + | 'request-attestation' + | 'request-payment' + | 'confirm-payment' + | 'submit-attestation' + | 'reject-attestation' + | 'request-credential' + | 'submit-credential' + +interface IMessageBodyBase { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + content: any + type: MessageBodyType +} + +export interface IError extends IMessageBodyBase { + content: { + /** Optional machine-readable type of the error. */ + name?: string + /** Optional human-readable description of the error. */ + message?: string + } + type: 'error' +} + +export interface IReject extends IMessageBodyBase { + content: { + /** Optional machine-readable type of the rejection. */ + name?: string + /** Optional human-readable description of the rejection. */ + message?: string + } + type: 'reject' +} + +export interface ISubmitTerms extends IMessageBodyBase { + content: ITerms + type: 'submit-terms' +} + +export interface IRequestAttestationContent { + credential: ICredential + quote?: IQuoteAgreement +} + +export interface IRequestAttestation extends IMessageBodyBase { + content: IRequestAttestationContent + type: 'request-attestation' +} + +export interface IRequestPaymentContent { + // Same as the `rootHash` value of the `'request-attestation'` message */ + claimHash: string +} + +export interface IRequestPayment extends IMessageBodyBase { + content: IRequestPaymentContent + type: 'request-payment' +} + +export interface ISubmitAttestationContent { + attestation: IAttestation +} + +export interface ISubmitAttestation extends IMessageBodyBase { + content: ISubmitAttestationContent + type: 'submit-attestation' +} + +export interface IRejectAttestation extends IMessageBodyBase { + content: ICredential['rootHash'] + type: 'reject-attestation' +} + +export interface IRequestCredentialContent { + cTypes: Array<{ + cTypeHash: CTypeHash + trustedAttesters?: DidUri[] + requiredProperties?: string[] + }> + challenge?: string +} + +export interface ISubmitCredential extends IMessageBodyBase { + content: ICredentialPresentation[] + type: 'submit-credential' +} + +export interface IRequestCredential extends IMessageBodyBase { + content: IRequestCredentialContent + type: 'request-credential' +} + +export interface IConfirmPaymentContent { + // Same as the `rootHash` value of the `'request-attestation'` message + claimHash: string + // Hash of the payment transaction */ + txHash: string + // hash of the block which includes the payment transaction + blockHash: string +} + +export interface IConfirmPayment extends IMessageBodyBase { + content: IConfirmPaymentContent + type: 'confirm-payment' +} + +export type MessageBody = + | IError + | IReject + | ISubmitTerms + | IRequestAttestation + | IRequestPayment + | IConfirmPayment + | ISubmitAttestation + | IRejectAttestation + | IRequestCredential + | ISubmitCredential + +export interface IMessage { + body: MessageBody + createdAt: number + sender: DidUri + receiver: DidUri + messageId?: string + receivedAt?: number + inReplyTo?: IMessage['messageId'] + references?: Array +} diff --git a/src/types/Quote.ts b/src/types/Quote.ts new file mode 100644 index 0000000..256b30c --- /dev/null +++ b/src/types/Quote.ts @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import type { DidSignature, DidUri } from './DidDocument' +import type { ICredential } from './Credential' +import type { CTypeHash } from './CType' + +export interface ICostBreakdown { + tax: Record + net: number + gross: number +} +export interface IQuote { + attesterDid: DidUri + cTypeHash: CTypeHash + cost: ICostBreakdown + currency: string + timeframe: string + termsAndConditions: string +} +export interface IQuoteAttesterSigned extends IQuote { + attesterSignature: DidSignature +} + +export interface IQuoteAgreement extends IQuoteAttesterSigned { + rootHash: ICredential['rootHash'] + claimerDid: DidUri + claimerSignature: DidSignature +} + diff --git a/src/types/Terms.ts b/src/types/Terms.ts new file mode 100644 index 0000000..e4578aa --- /dev/null +++ b/src/types/Terms.ts @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import type { ICType } from './CType' +import type { IDelegationNode } from './Delegation' +import type { IQuoteAttesterSigned } from './Quote' +import type { PartialClaim } from './Claim' +import type { ICredential } from './Credential' + +export interface ITerms { + claim: PartialClaim + legitimations: ICredential[] + delegationId?: IDelegationNode['id'] + quote?: IQuoteAttesterSigned + cTypes?: ICType[] +} diff --git a/src/types/index.ts b/src/types/index.ts index c1c3899..033c323 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,7 +1,9 @@ import type { IEncryptedMessage, DidUri, KiltAddress, DidResourceUri } from '@kiltprotocol/types' import type { HexString } from '@polkadot/util/types' import type { CredentialDigestProof, SelfSignedProof, VerifiableCredential, constants } from '@kiltprotocol/vc-export' +import type * as IMessage from "./Message"; +export type Message = typeof IMessage; export type This = typeof globalThis export interface IEncryptedMessageV1 { From e6d2f3dbcaeb80f2138e91ba8a32a7d4a3730aa0 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Fri, 4 Aug 2023 14:06:30 +0200 Subject: [PATCH 02/39] integrated messaging --- src/tests/index.ts | 2 + src/tests/jest.setup.ts | 5 + src/tests/messageUtils.ts | 279 ++++++++++++++++++++++++++++++++++++++ src/tests/utils.ts | 1 + 4 files changed, 287 insertions(+) create mode 100644 src/tests/index.ts create mode 100644 src/tests/jest.setup.ts create mode 100644 src/tests/messageUtils.ts diff --git a/src/tests/index.ts b/src/tests/index.ts new file mode 100644 index 0000000..68a3e17 --- /dev/null +++ b/src/tests/index.ts @@ -0,0 +1,2 @@ +export * from './messageUtils' +export * from './utils' diff --git a/src/tests/jest.setup.ts b/src/tests/jest.setup.ts new file mode 100644 index 0000000..51e36b5 --- /dev/null +++ b/src/tests/jest.setup.ts @@ -0,0 +1,5 @@ +import { cryptoWaitReady } from '@polkadot/util-crypto' + +beforeAll(async () => { + await cryptoWaitReady() +}) diff --git a/src/tests/messageUtils.ts b/src/tests/messageUtils.ts new file mode 100644 index 0000000..029cf13 --- /dev/null +++ b/src/tests/messageUtils.ts @@ -0,0 +1,279 @@ +import { + KiltKeyringPair, + KeyringPair, + KiltEncryptionKeypair, + DidDocument, + NewLightDidVerificationKey, + KeyRelationship, + DidServiceEndpoint, + DidKey, + DidVerificationKey, + DecryptCallback, + EncryptCallback } from '../types' +import { + Did, + SignCallback, +} from '@kiltprotocol/sdk-js' +import { Crypto } from '@kiltprotocol/utils' +import { + blake2AsU8a, + blake2AsHex, +} from '@polkadot/util-crypto' + + + + +/** + * Generates a callback that can be used for signing. + * + * @param keypair The keypair to use for signing. + * @returns The callback. + */ +export function makeSignCallback(keypair: KeyringPair): KeyToolSignCallback { + return (didDocument) => + async function sign({ data, keyRelationship }) { + const keyId = didDocument[keyRelationship]?.[0].id + const keyType = didDocument[keyRelationship]?.[0].type + if (keyId === undefined || keyType === undefined) { + throw new Error( + `Key for purpose "${keyRelationship}" not found in did "${didDocument.uri}"` + ) + } + const signature = keypair.sign(data, { withType: false }) + + return { + signature, + keyUri: `${didDocument.uri}${keyId}`, + keyType, + } + } +} + +/** + * Generates a callback that can be used for signing. + * + * @param keypair The keypair to use for signing. + * @returns The callback. + */ +export function makeStoreDidCallback( + keypair: KiltKeyringPair +): StoreDidCallback { + return async function sign({ data }) { + const signature = keypair.sign(data, { withType: false }) + return { + signature, + keyType: keypair.type, + } + } +} + + +/** + * Generates a keypair usable for signing and a few related values. + * + * @param type The type to use for the keypair. + * @returns The keypair, matching sign callback, a key usable as DID authentication key. + */ +export function makeSigningKeyTool( + type: KiltKeyringPair['type'] = 'sr25519' +): KeyTool { + const keypair = Crypto.makeKeypairFromSeed(undefined, type) + const getSignCallback = makeSignCallback(keypair) + const storeDidCallback = makeStoreDidCallback(keypair) + + return { + keypair, + getSignCallback, + storeDidCallback, + authentication: [keypair as NewLightDidVerificationKey], + } +} + + +/** + * Creates a full DID from a light DID where the verification keypair is enabled for all verification purposes (authentication, assertionMethod, capabilityDelegation). + * This is not recommended, use for demo purposes only! + * + * @param lightDid The light DID whose keys will be used on the full DID. + * @returns A full DID instance that is not yet written to the blockchain. + */ +export async function createLocalDemoFullDidFromLightDid( + lightDid: DidDocument +): Promise { + const { uri, authentication } = lightDid + + return { + uri: Did.getFullDidUri(uri), + authentication, + assertionMethod: authentication, + capabilityDelegation: authentication, + keyAgreement: lightDid.keyAgreement, + } +} + + +/** + * Generates a callback that can be used for decryption. + * + * @param secretKey The options parameter. + * @param secretKey.secretKey The key to use for decryption. + * @returns The callback. + */ +export function makeDecryptCallback({ + secretKey, +}: KiltEncryptionKeypair): DecryptCallback { + return async function decryptCallback({ data, nonce, peerPublicKey }) { + const decrypted = Crypto.decryptAsymmetric( + { box: data, nonce }, + peerPublicKey, + secretKey + ) + if (decrypted === false) throw new Error('Decryption failed') + return { data: decrypted } + } +} + +export type EncryptionKeyToolCallback = ( + didDocument: DidDocument + ) => EncryptCallback + + + +/** + * Generates a callback that can be used for encryption. + * + * @param secretKey The options parameter. + * @param secretKey.secretKey The key to use for encryption. + * @returns The callback. + */ +export function makeEncryptCallback({ + secretKey, +}: KiltEncryptionKeypair): EncryptionKeyToolCallback { + return (didDocument) => { + return async function encryptCallback({ data, peerPublicKey }) { + const keyId = didDocument.keyAgreement?.[0].id + if (!keyId) { + throw new Error(`Encryption key not found in did "${didDocument.uri}"`) + } + const { box, nonce } = Crypto.encryptAsymmetric( + data, + peerPublicKey, + secretKey + ) + return { + nonce, + data: box, + keyUri: `${didDocument.uri}${keyId}`, + } + } + } +} + +export interface EncryptionKeyTool { + keyAgreement: [KiltEncryptionKeypair] + encrypt: EncryptionKeyToolCallback + decrypt: DecryptCallback + } + +/** + * Generates a keypair suitable for encryption. + * + * @param seed {string} Input to generate the keypair from. + * @returns Object with secret and public key and the key type. + */ +export function makeEncryptionKeyTool(seed: string): EncryptionKeyTool { + const keypair = Crypto.makeEncryptionKeypairFromSeed(blake2AsU8a(seed, 256)) + + const encrypt = makeEncryptCallback(keypair) + const decrypt = makeDecryptCallback(keypair) + + return { + keyAgreement: [keypair], + encrypt, + decrypt, + } +} + +// Mock function to generate a key ID without having to rely on a real chain metadata. +export function computeKeyId(key: DidKey['publicKey']): DidKey['id'] { + return `#${blake2AsHex(key, 256)}` +} + +function makeDidKeyFromKeypair({ + publicKey, + type, +}: KiltKeyringPair): DidVerificationKey { + return { + id: computeKeyId(publicKey), + publicKey, + type, + } +} + +/** + * Creates [[DidDocument]] for local use, e.g., in testing. Will not work on-chain because key IDs are generated ad-hoc. + * + * @param keypair The KeyringPair for authentication key, other keys derived from it. + * @param generationOptions The additional options for generation. + * @param generationOptions.keyRelationships The set of key relationships to indicate which keys must be added to the DID. + * @param generationOptions.endpoints The set of service endpoints that must be added to the DID. + * + * @returns A promise resolving to a [[DidDocument]] object. The resulting object is NOT stored on chain. + */ +export async function createLocalDemoFullDidFromKeypair( + keypair: KiltKeyringPair, + { + keyRelationships = new Set([ + 'assertionMethod', + 'capabilityDelegation', + 'keyAgreement', + ]), + endpoints = [], + }: { + keyRelationships?: Set> + endpoints?: DidServiceEndpoint[] + } = {} +): Promise { + const authKey = makeDidKeyFromKeypair(keypair) + const uri = Did.getFullDidUriFromKey(authKey) + + const result: DidDocument = { + uri, + authentication: [authKey], + service: endpoints, + } + + if (keyRelationships.has('keyAgreement')) { + const encryptionKeypair = makeEncryptionKeyTool(`${keypair.publicKey}//enc`) + .keyAgreement[0] + const encKey = { + ...encryptionKeypair, + id: computeKeyId(encryptionKeypair.publicKey), + } + result.keyAgreement = [encKey] + } + if (keyRelationships.has('assertionMethod')) { + const attKey = makeDidKeyFromKeypair( + keypair.derive('//att') as KiltKeyringPair + ) + result.assertionMethod = [attKey] + } + if (keyRelationships.has('capabilityDelegation')) { + const delKey = makeDidKeyFromKeypair( + keypair.derive('//del') as KiltKeyringPair + ) + result.capabilityDelegation = [delKey] + } + + return result +} + +export type KeyToolSignCallback = (didDocument: DidDocument) => SignCallback + type StoreDidCallback = Parameters['2'] + +export interface KeyTool { + keypair: KiltKeyringPair + getSignCallback: KeyToolSignCallback + storeDidCallback: StoreDidCallback + authentication: [NewLightDidVerificationKey] + } diff --git a/src/tests/utils.ts b/src/tests/utils.ts index ec5c2b9..a2816f1 100644 --- a/src/tests/utils.ts +++ b/src/tests/utils.ts @@ -153,3 +153,4 @@ export async function startContainer(): Promise { const WS_ADDRESS = `ws://${host}:${port}` return WS_ADDRESS } + From f4423178bf40f4cc9775833e8d0446474dfac994 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Fri, 4 Aug 2023 14:10:25 +0200 Subject: [PATCH 03/39] with messaging --- jest.config.js | 1 + src/messaging/Message.test.ts | 869 +++++++++++++++++++++++++++++++ src/messaging/index.ts | 366 +++++++++++++ src/types/CryptoCallbacks.ts | 91 ++++ src/types/DidDocument.ts | 114 +++- src/types/DidDocumentExporter.ts | 95 ++++ src/types/DidResolver.ts | 69 +++ src/types/Message.ts | 51 +- src/types/index.ts | 15 +- 9 files changed, 1662 insertions(+), 9 deletions(-) create mode 100644 src/messaging/Message.test.ts create mode 100644 src/messaging/index.ts create mode 100644 src/types/CryptoCallbacks.ts create mode 100644 src/types/DidDocumentExporter.ts create mode 100644 src/types/DidResolver.ts diff --git a/jest.config.js b/jest.config.js index 4f4865e..43d4510 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,6 +1,7 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', + setupFilesAfterEnv: ['/tests/jest.setup.ts'], clearMocks: true, // Parachain block time is 12s testTimeout: 12000, diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts new file mode 100644 index 0000000..62a8253 --- /dev/null +++ b/src/messaging/Message.test.ts @@ -0,0 +1,869 @@ +/* eslint-disable @typescript-eslint/ban-ts-comment */ + +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import { u8aToHex } from '@polkadot/util' +import { Attestation, CType, Claim, Credential, Quote } from '@kiltprotocol/core' +import * as Did from '@kiltprotocol/did' +import type { + DidDocument, + DidKey, + DidResourceUri, + DidUri, + IAttestation, + ICType, + IClaim, + ICredential, + ICredentialPresentation, + IEncryptedMessage, + IMessage, + IQuote, + IQuoteAgreement, + IQuoteAttesterSigned, + IRejectAttestation, + IRequestAttestation, + IRequestAttestationContent, + IRequestCredential, + IRequestCredentialContent, + ISubmitAttestation, + ISubmitAttestationContent, + ISubmitCredential, + ISubmitTerms, + ITerms, + MessageBody, + ResolvedDidKey, +} from '../types' + +import type { + ISubmitDelegationApproval, + IRequestDelegationApproval, + ISubmitAcceptDelegation, + IRequestAcceptDelegation, +} from '@kiltprotocol/types' + +import { Crypto, SDKErrors } from '@kiltprotocol/utils' + +import { + KeyTool, + KeyToolSignCallback, + createLocalDemoFullDidFromKeypair, + createLocalDemoFullDidFromLightDid, + makeEncryptionKeyTool, + makeSigningKeyTool, +} from '../tests' +import * as Message from './index' + +describe('Messaging', () => { + let aliceLightDid: DidDocument + let aliceLightDidWithDetails: DidDocument + let aliceFullDid: DidDocument + let aliceSign: KeyToolSignCallback + const aliceEncKey = makeEncryptionKeyTool('Alice//enc') + + let bobLightDid: DidDocument + let bobLightDidWithDetails: DidDocument + let bobFullDid: DidDocument + let bobSign: KeyToolSignCallback + const bobEncKey = makeEncryptionKeyTool('Bob//enc') + + async function resolveKey(keyUri: DidResourceUri, keyRelationship = 'authentication'): Promise { + const { did } = Did.parse(keyUri) + const document = [ + aliceLightDidWithDetails, + aliceLightDid, + aliceFullDid, + bobLightDidWithDetails, + bobLightDid, + bobFullDid, + ].find(({ uri }) => uri === did) + if (!document) throw new Error('Cannot resolve mocked DID') + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return Did.keyToResolvedKey(document[keyRelationship as keyof DidDocument]![0] as DidKey, did) + } + + beforeAll(async () => { + const aliceAuthKey = makeSigningKeyTool('ed25519') + aliceSign = aliceAuthKey.getSignCallback + aliceLightDid = Did.createLightDidDocument({ + authentication: aliceAuthKey.authentication, + keyAgreement: aliceEncKey.keyAgreement, + }) + aliceLightDidWithDetails = Did.createLightDidDocument({ + authentication: aliceAuthKey.authentication, + keyAgreement: aliceEncKey.keyAgreement, + service: [{ id: '#id-1', type: ['type-1'], serviceEndpoint: ['x:url-1'] }], + }) + aliceFullDid = await createLocalDemoFullDidFromLightDid(aliceLightDid) + + const bobAuthKey = makeSigningKeyTool('ed25519') + bobSign = bobAuthKey.getSignCallback + bobLightDid = Did.createLightDidDocument({ + authentication: bobAuthKey.authentication, + keyAgreement: bobEncKey.keyAgreement, + }) + bobLightDidWithDetails = Did.createLightDidDocument({ + authentication: bobAuthKey.authentication, + keyAgreement: bobEncKey.keyAgreement, + service: [{ id: '#id-1', type: ['type-1'], serviceEndpoint: ['x:url-1'] }], + }) + bobFullDid = await createLocalDemoFullDidFromLightDid(bobLightDid) + }) + it('verify message encryption and signing', async () => { + const message = Message.fromBody( + { + type: 'request-credential', + content: { + cTypes: [{ cTypeHash: `${Crypto.hashStr('0x12345678')}` }], + }, + }, + aliceLightDid.uri, + bobLightDid.uri + ) + const encryptedMessage = await Message.encrypt( + message, + aliceEncKey.encrypt(aliceLightDid), + `${bobLightDid.uri}#encryption`, + { resolveKey } + ) + + const decryptedMessage = await Message.decrypt(encryptedMessage, bobEncKey.decrypt, { resolveKey }) + expect(JSON.stringify(message.body)).toEqual(JSON.stringify(decryptedMessage.body)) + + expect(() => Message.verify(decryptedMessage)).not.toThrow() + + const encryptedMessageWrongContent = JSON.parse(JSON.stringify(encryptedMessage)) as IEncryptedMessage + const messedUpContent = Crypto.coToUInt8(encryptedMessageWrongContent.ciphertext) + messedUpContent.set(Crypto.hash('1234'), 10) + encryptedMessageWrongContent.ciphertext = u8aToHex(messedUpContent) + + await expect(() => + Message.decrypt(encryptedMessageWrongContent, bobEncKey.decrypt, { + resolveKey, + }) + ).rejects.toThrowError(SDKErrors.DecodingMessageError) + + const encryptedWrongBody = await aliceEncKey.encrypt(aliceLightDid)({ + data: Crypto.coToUInt8('{ wrong JSON'), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + peerPublicKey: bobLightDid.keyAgreement![0].publicKey, + did: aliceLightDid.uri, + }) + const encryptedMessageWrongBody: IEncryptedMessage = { + ciphertext: u8aToHex(encryptedWrongBody.data), + nonce: u8aToHex(encryptedWrongBody.nonce), + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + senderKeyUri: `${aliceLightDid.uri}${aliceLightDid.keyAgreement![0].id}`, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + receiverKeyUri: `${bobLightDid.uri}${bobLightDid.keyAgreement![0].id}`, + } + await expect(() => + Message.decrypt(encryptedMessageWrongBody, bobEncKey.decrypt, { + resolveKey, + }) + ).rejects.toThrowError(SyntaxError) + }) + + it('verifies the message with sender is the owner (as full DID)', async () => { + const credential = Credential.fromClaim({ + cTypeHash: `${Crypto.hashStr('0x12345678')}`, + owner: aliceFullDid.uri, + contents: {}, + }) + + const presentation = await Credential.createPresentation({ + credential, + signCallback: aliceSign(aliceFullDid), + }) + + const date = new Date(2019, 11, 10).toISOString() + + const quoteData: IQuote = { + attesterDid: bobFullDid.uri, + cTypeHash: `${Crypto.hashStr('0x12345678')}`, + cost: { + tax: { vat: 3.3 }, + net: 23.4, + gross: 23.5, + }, + currency: 'Euro', + termsAndConditions: 'https://coolcompany.io/terms.pdf', + timeframe: date, + } + const quoteAttesterSigned = await Quote.createAttesterSignedQuote(quoteData, bobSign(bobFullDid)) + const bothSigned = await Quote.createQuoteAgreement( + quoteAttesterSigned, + credential.rootHash, + aliceSign(aliceFullDid), + aliceFullDid.uri, + { didResolveKey: resolveKey } + ) + const requestAttestationBody: IRequestAttestation = { + content: { + credential, + quote: bothSigned, + }, + type: 'request-attestation', + } + + // Should not throw if the owner and sender DID is the same. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, aliceFullDid.uri, bobFullDid.uri)) + ).not.toThrow() + + // Should not throw if the sender is the light DID version of the owner. + // This is technically not to be allowed but message verification is not concerned with that. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, aliceLightDid.uri, bobFullDid.uri)) + ).not.toThrow() + + // Should throw if the sender and the owner are two different entities. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, bobFullDid.uri, aliceFullDid.uri)) + ).toThrowError(SDKErrors.IdentityMismatchError) + + const attestation = { + delegationId: null, + claimHash: requestAttestationBody.content.credential.rootHash, + cTypeHash: Crypto.hashStr('0x12345678'), + owner: bobFullDid.uri, + revoked: false, + } + + const submitAttestationBody: ISubmitAttestation = { + content: { + attestation, + }, + type: 'submit-attestation', + } + + // Should not throw if the owner and sender DID is the same. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, bobFullDid.uri, aliceFullDid.uri)) + ).not.toThrow() + + // Should not throw if the sender is the light DID version of the owner. + // This is technically not to be allowed but message verification is not concerned with that. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, bobLightDid.uri, aliceFullDid.uri)) + ).not.toThrow() + + // Should throw if the sender and the owner are two different entities. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, aliceFullDid.uri, bobFullDid.uri)) + ).toThrowError(SDKErrors.IdentityMismatchError) + + const submitClaimsForCTypeBody: ISubmitCredential = { + content: [presentation], + type: 'submit-credential', + } + + // Should not throw if the owner and sender DID is the same. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, aliceFullDid.uri, bobFullDid.uri)) + ).not.toThrow() + + // Should not throw if the sender is the light DID version of the owner. + // This is technically not to be allowed but message verification is not concerned with that. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, aliceLightDid.uri, bobFullDid.uri)) + ).not.toThrow() + + // Should throw if the sender and the owner are two different entities. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, bobFullDid.uri, aliceFullDid.uri)) + ).toThrowError(SDKErrors.IdentityMismatchError) + }) + + it('verifies the message with sender is the owner (as light DID)', async () => { + // Create request for attestation to the light DID with no encoded details + const credential = Credential.fromClaim({ + cTypeHash: `${Crypto.hashStr('0x12345678')}`, + owner: aliceLightDid.uri, + contents: {}, + }) + + const presentation = await Credential.createPresentation({ + credential, + signCallback: aliceSign(aliceLightDid), + }) + + const date = new Date(2019, 11, 10).toISOString() + const quoteData: IQuote = { + attesterDid: bobLightDid.uri, + cTypeHash: `${Crypto.hashStr('0x12345678')}`, + cost: { + tax: { vat: 3.3 }, + net: 23.4, + gross: 23.5, + }, + currency: 'Euro', + termsAndConditions: 'https://coolcompany.io/terms.pdf', + timeframe: date, + } + const quoteAttesterSigned = await Quote.createAttesterSignedQuote(quoteData, bobSign(bobLightDid)) + const bothSigned = await Quote.createQuoteAgreement( + quoteAttesterSigned, + credential.rootHash, + aliceSign(aliceLightDid), + aliceLightDid.uri, + { didResolveKey: resolveKey } + ) + const requestAttestationBody: IRequestAttestation = { + content: { + credential, + quote: bothSigned, + }, + type: 'request-attestation', + } + + // Create request for attestation to the light DID with encoded details + const contentWithEncodedDetails = await Credential.createPresentation({ + credential: Credential.fromClaim({ + cTypeHash: `${Crypto.hashStr('0x12345678')}`, + owner: aliceLightDidWithDetails.uri, + contents: {}, + }), + signCallback: aliceSign(aliceLightDidWithDetails), + }) + + const quoteDataEncodedDetails: IQuote = { + attesterDid: bobLightDidWithDetails.uri, + cTypeHash: `${Crypto.hashStr('0x12345678')}`, + cost: { + tax: { vat: 3.3 }, + net: 23.4, + gross: 23.5, + }, + currency: 'Euro', + termsAndConditions: 'https://coolcompany.io/terms.pdf', + timeframe: date, + } + const quoteAttesterSignedEncodedDetails = await Quote.createAttesterSignedQuote( + quoteDataEncodedDetails, + bobSign(bobLightDidWithDetails) + ) + const bothSignedEncodedDetails = await Quote.createQuoteAgreement( + quoteAttesterSignedEncodedDetails, + credential.rootHash, + aliceSign(aliceLightDidWithDetails), + aliceLightDidWithDetails.uri, + { didResolveKey: resolveKey } + ) + const requestAttestationBodyWithEncodedDetails: IRequestAttestation = { + content: { + credential: contentWithEncodedDetails, + quote: bothSignedEncodedDetails, + }, + type: 'request-attestation', + } + + // Should not throw if the owner and sender DID is the same. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, aliceLightDid.uri, bobLightDid.uri)) + ).not.toThrow() + + // Should not throw if the owner has no additional details and the sender does. + expect(() => + Message.ensureOwnerIsSender( + Message.fromBody(requestAttestationBodyWithEncodedDetails, aliceLightDidWithDetails.uri, bobLightDid.uri) + ) + ).not.toThrow() + + // Should not throw if the owner has additional details and the sender does not. + expect(() => + Message.ensureOwnerIsSender( + Message.fromBody(requestAttestationBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri) + ) + ).not.toThrow() + + // Should not throw if the sender is the full DID version of the owner. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, aliceFullDid.uri, bobLightDid.uri)) + ).not.toThrow() + + // Should throw if the sender and the owner are two different entities. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, bobLightDid.uri, aliceLightDid.uri)) + ).toThrowError(SDKErrors.IdentityMismatchError) + + const attestation = { + delegationId: null, + claimHash: requestAttestationBody.content.credential.rootHash, + cTypeHash: Crypto.hashStr('0x12345678'), + owner: bobLightDid.uri, + revoked: false, + } + + const submitAttestationBody: ISubmitAttestation = { + content: { + attestation, + }, + type: 'submit-attestation', + } + + const attestationWithEncodedDetails = { + delegationId: null, + claimHash: requestAttestationBody.content.credential.rootHash, + cTypeHash: Crypto.hashStr('0x12345678'), + owner: bobLightDidWithDetails.uri, + revoked: false, + } + + const submitAttestationBodyWithEncodedDetails: ISubmitAttestation = { + content: { + attestation: attestationWithEncodedDetails, + }, + type: 'submit-attestation', + } + + // Should not throw if the owner and sender DID is the same. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, bobLightDid.uri, aliceLightDid.uri)) + ).not.toThrow() + + // Should not throw if the owner has no additional details and the sender does. + expect(() => + Message.ensureOwnerIsSender( + Message.fromBody(submitAttestationBody, bobLightDidWithDetails.uri, aliceLightDid.uri) + ) + ).not.toThrow() + + // Should not throw if the owner has additional details and the sender does not. + expect(() => + Message.ensureOwnerIsSender( + Message.fromBody(submitAttestationBodyWithEncodedDetails, bobLightDid.uri, aliceLightDid.uri) + ) + ).not.toThrow() + + // Should not throw if the sender is the full DID version of the owner. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, bobFullDid.uri, aliceLightDid.uri)) + ).not.toThrow() + + // Should throw if the sender and the owner are two different entities. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, aliceLightDid.uri, bobLightDid.uri)) + ).toThrowError(SDKErrors.IdentityMismatchError) + + const submitClaimsForCTypeBody: ISubmitCredential = { + content: [presentation], + type: 'submit-credential', + } + + const submitClaimsForCTypeBodyWithEncodedDetails: ISubmitCredential = { + content: [contentWithEncodedDetails], + type: 'submit-credential', + } + + // Should not throw if the owner and sender DID is the same. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, aliceLightDid.uri, bobLightDid.uri)) + ).not.toThrow() + + // Should not throw if the owner has no additional details and the sender does. + expect(() => + Message.ensureOwnerIsSender( + Message.fromBody(submitClaimsForCTypeBody, aliceLightDidWithDetails.uri, bobLightDid.uri) + ) + ).not.toThrow() + + // Should not throw if the owner has additional details and the sender does not. + expect(() => + Message.ensureOwnerIsSender( + Message.fromBody(submitClaimsForCTypeBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri) + ) + ).not.toThrow() + + // Should not throw if the sender is the full DID version of the owner. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, aliceFullDid.uri, bobLightDid.uri)) + ).not.toThrow() + + // Should throw if the sender and the owner are two different entities. + expect(() => + Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, bobLightDid.uri, aliceLightDid.uri)) + ).toThrowError(SDKErrors.IdentityMismatchError) + }) +}) + +describe('Error checking / Verification', () => { + // TODO: Duplicated code, would be nice to have as a seperated test package with similar helpers + async function buildCredential( + claimerDid: DidUri, + attesterDid: DidUri, + contents: IClaim['contents'], + legitimations: ICredential[] + ): Promise<[ICredential, IAttestation]> { + // create claim + + const testCType = CType.fromProperties('Credential', { + name: { type: 'string' }, + }) + + const claim = Claim.fromCTypeAndClaimContents(testCType, contents, claimerDid) + // build credential with legitimations + const credential = Credential.fromClaim(claim, { + legitimations, + }) + // build attestation + const testAttestation = Attestation.fromCredentialAndDid(credential, attesterDid) + return [credential, testAttestation] + } + + let identityAlice: DidDocument + let keyAlice: KeyTool + + let identityBob: DidDocument + let keyBob: KeyTool + + let date: string + let testCType: ICType + let testCTypeWithMultipleProperties: ICType + let claim: IClaim + let claimContents: IClaim['contents'] + let quoteData: IQuote + let quoteAttesterSigned: IQuoteAttesterSigned + let bothSigned: IQuoteAgreement + let legitimation: ICredential + let submitTermsBody: ISubmitTerms + let submitTermsContent: ITerms + let requestAttestationBody: IRequestAttestation + let requestAttestationContent: IRequestAttestationContent + let submitAttestationContent: ISubmitAttestationContent + let submitAttestationBody: ISubmitAttestation + let rejectAttestationForClaimBody: IRejectAttestation + let requestCredentialBody: IRequestCredential + let requestCredentialContent: IRequestCredentialContent + let submitCredentialBody: ISubmitCredential + let submitCredentialContent: ICredentialPresentation[] + let requestAcceptDelegationBody: IRequestAcceptDelegation + let requestAcceptDelegationContent: IRequestDelegationApproval + let submitAcceptDelegationBody: ISubmitAcceptDelegation + let submitAcceptDelegationContent: ISubmitDelegationApproval + + let messageSubmitTerms: IMessage + let messageRequestAttestationForClaim: IMessage + let messageSubmitAttestationForClaim: IMessage + let messageRequestCredential: IMessage + let messageRejectAttestationForClaim: IMessage + let messageSubmitCredential: IMessage + + beforeAll(async () => { + keyAlice = makeSigningKeyTool() + identityAlice = await createLocalDemoFullDidFromKeypair(keyAlice.keypair) + keyBob = makeSigningKeyTool() + identityBob = await createLocalDemoFullDidFromKeypair(keyBob.keypair) + + date = new Date(2019, 11, 10).toISOString() + claimContents = { + name: 'Bob', + } + + async function didResolveKey(keyUri: DidResourceUri): Promise { + const { did } = Did.parse(keyUri) + const document = [identityAlice, identityBob].find(({ uri }) => uri === did) + if (!document) throw new Error('Cannot resolve mocked DID') + return Did.keyToResolvedKey(document.authentication[0], did) + } + + // CType + testCType = CType.fromProperties('ClaimCtype', { + name: { type: 'string' }, + }) + testCTypeWithMultipleProperties = CType.fromProperties('Drivers license Claim', { + name: { type: 'string' }, + id: { type: 'string' }, + age: { type: 'string' }, + }) + + // Claim + claim = Claim.fromCTypeAndClaimContents(testCType, claimContents, identityAlice.uri) + // Legitimation + ;[legitimation] = await buildCredential(identityAlice.uri, identityBob.uri, {}, []) + // Quote Data + quoteData = { + attesterDid: identityAlice.uri, + cTypeHash: claim.cTypeHash, + cost: { + tax: { vat: 3.3 }, + net: 23.4, + gross: 23.5, + }, + currency: 'Euro', + termsAndConditions: 'https://coolcompany.io/terms.pdf', + timeframe: date, + } + // Quote signed by attester + quoteAttesterSigned = await Quote.createAttesterSignedQuote(quoteData, keyAlice.getSignCallback(identityAlice)) + // Quote agreement + bothSigned = await Quote.createQuoteAgreement( + quoteAttesterSigned, + legitimation.rootHash, + keyBob.getSignCallback(identityBob), + identityBob.uri, + { didResolveKey } + ) + + + // Submit Terms content + submitTermsContent = { + claim: { + cTypeHash: claim.cTypeHash, + }, + legitimations: [legitimation], + delegationId: undefined, + quote: quoteAttesterSigned, + cTypes: undefined, + } + + + // Request Attestation Content + requestAttestationContent = { + credential: legitimation, + quote: bothSigned, + } + + // Submit Attestation content + submitAttestationContent = { + attestation: { + delegationId: null, + claimHash: requestAttestationContent.credential.rootHash, + cTypeHash: claim.cTypeHash, + owner: identityBob.uri, + revoked: false, + }, + } + + // Request Credential content + requestCredentialContent = { + cTypes: [ + { + cTypeHash: claim.cTypeHash, + trustedAttesters: [identityAlice.uri], + requiredProperties: ['id', 'name'], + }, + ], + challenge: '1234', + } + // Submit Credential content + submitCredentialContent = [ + { + ...legitimation, + claimerSignature: { + signature: '0x1234', + keyUri: `${legitimation.claim.owner}#0x1234`, + }, + }, + ] + // Request Accept delegation content + requestAcceptDelegationContent = { + delegationData: { + account: identityAlice.uri, + id: Crypto.hashStr('0x12345678'), + parentId: Crypto.hashStr('0x12345678'), + permissions: [1], + isPCR: false, + }, + metaData: {}, + signatures: { + inviter: Did.signatureToJson( + await keyAlice.getSignCallback(identityAlice)({ + data: Crypto.coToUInt8('signature'), + did: identityAlice.uri, + keyRelationship: 'authentication', + }) + ), + }, + } + // Submit Accept delegation content + submitAcceptDelegationContent = { + delegationData: { + account: identityAlice.uri, + id: Crypto.hashStr('0x12345678'), + parentId: Crypto.hashStr('0x12345678'), + permissions: [1], + isPCR: false, + }, + signatures: { + inviter: Did.signatureToJson( + await keyAlice.getSignCallback(identityAlice)({ + data: Crypto.coToUInt8('signature'), + did: identityAlice.uri, + keyRelationship: 'authentication', + }) + ), + invitee: Did.signatureToJson( + await keyBob.getSignCallback(identityBob)({ + data: Crypto.coToUInt8('signature'), + did: identityBob.uri, + keyRelationship: 'authentication', + }) + ), + }, + } + + + + + submitTermsBody = { + content: submitTermsContent, + type: 'submit-terms', + } + + requestAttestationBody = { + content: requestAttestationContent, + type: 'request-attestation', + } + + submitAttestationBody = { + content: submitAttestationContent, + type: 'submit-attestation', + } + + rejectAttestationForClaimBody = { + content: requestAttestationContent.credential.rootHash, + type: 'reject-attestation', + } + requestCredentialBody = { + content: requestCredentialContent, + type: 'request-credential', + } + + submitCredentialBody = { + content: submitCredentialContent, + type: 'submit-credential', + } + + requestAcceptDelegationBody = { + content: requestAcceptDelegationContent, + type: 'request-accept-delegation', + } + + submitAcceptDelegationBody = { + content: submitAcceptDelegationContent, + type: 'submit-accept-delegation', + } + + + }) + + it('Checking required properties for given CType', () => { + expect(() => Message.verifyRequiredCTypeProperties(['id', 'name'], testCType)).toThrowError( + SDKErrors.CTypeUnknownPropertiesError + ) + + expect(() => + Message.verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties) + ).not.toThrowError(SDKErrors.CTypeUnknownPropertiesError) + + expect(() => + Message.verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties) + ).not.toThrowError() + }) + + beforeAll(async () => { + + messageSubmitTerms = Message.fromBody(submitTermsBody, identityAlice.uri, identityBob.uri) + + messageRequestAttestationForClaim = Message.fromBody(requestAttestationBody, identityAlice.uri, identityBob.uri) + messageSubmitAttestationForClaim = Message.fromBody(submitAttestationBody, identityAlice.uri, identityBob.uri) + + messageRejectAttestationForClaim = Message.fromBody( + rejectAttestationForClaimBody, + identityAlice.uri, + identityBob.uri + ) + messageRequestCredential = Message.fromBody(requestCredentialBody, identityAlice.uri, identityBob.uri) + messageSubmitCredential = Message.fromBody(submitCredentialBody, identityAlice.uri, identityBob.uri) + + }) + it('message body verifier should not throw errors on correct bodies', () => { + + expect(() => Message.verifyMessageBody(submitTermsBody)).not.toThrowError() + + expect(() => Message.verifyMessageBody(requestAttestationBody)).not.toThrowError() + expect(() => Message.verifyMessageBody(submitAttestationBody)).not.toThrowError() + expect(() => Message.verifyMessageBody(rejectAttestationForClaimBody)).not.toThrowError() + expect(() => Message.verifyMessageBody(requestCredentialBody)).not.toThrowError() + expect(() => Message.verifyMessageBody(submitCredentialBody)).not.toThrowError() + + }) + + + it('message envelope verifier should not throw errors on correct envelopes', () => { + + expect(() => Message.verifyMessageEnvelope(messageSubmitTerms)).not.toThrowError() + expect(() => Message.verifyMessageEnvelope(messageRequestAttestationForClaim)).not.toThrowError() + expect(() => Message.verifyMessageEnvelope(messageSubmitAttestationForClaim)).not.toThrowError() + expect(() => Message.verifyMessageEnvelope(messageRejectAttestationForClaim)).not.toThrowError() + expect(() => Message.verifyMessageEnvelope(messageRequestCredential)).not.toThrowError() + expect(() => Message.verifyMessageEnvelope(messageSubmitCredential)).not.toThrowError() + + }) + it('message envelope verifier should throw errors on faulty envelopes', () => { + + // @ts-ignore + messageSubmitTerms.sender = 'this is not a sender did' + expect(() => Message.verifyMessageEnvelope(messageSubmitTerms)).toThrowError(SDKErrors.InvalidDidFormatError) + // @ts-ignore + messageRequestAttestationForClaim.messageId = 12 + expect(() => Message.verifyMessageEnvelope(messageRequestAttestationForClaim)).toThrowError(TypeError) + // @ts-ignore + messageSubmitAttestationForClaim.createdAt = '123456' + expect(() => Message.verifyMessageEnvelope(messageSubmitAttestationForClaim)).toThrowError(TypeError) + // @ts-ignore + messageRejectAttestationForClaim.receivedAt = '123456' + expect(() => Message.verifyMessageEnvelope(messageRejectAttestationForClaim)).toThrowError(TypeError) + // @ts-ignore + messageRequestCredential.inReplyTo = 123 + expect(() => Message.verifyMessageEnvelope(messageRequestCredential)).toThrowError(TypeError) + }) + it('message body verifier should throw errors on faulty bodies', () => { + + submitTermsBody.content.delegationId = 'this is not a delegation id' + expect(() => Message.verifyMessageBody(submitTermsBody)).toThrowError(SDKErrors.HashMalformedError) + + submitCredentialBody.content[0].claimerSignature = { + signature: 'this is not the claimers signature', + // @ts-ignore + keyUri: 'this is not a key id', + } + expect(() => Message.verifyMessageBody(submitCredentialBody)).toThrowError() + // @ts-ignore + submitAttestationBody.content.attestation.claimHash = 'this is not the claim hash' + expect(() => Message.verifyMessageBody(submitAttestationBody)).toThrowError(SDKErrors.HashMalformedError) + // @ts-ignore + rejectAttestationForClaimBody.content = 'this is not the root hash' + expect(() => Message.verifyMessageBody(rejectAttestationForClaimBody)).toThrowError(SDKErrors.HashMalformedError) + // @ts-ignore + requestCredentialBody.content.cTypes[0].cTypeHash = 'this is not a cTypeHash' + expect(() => Message.verifyMessageBody(requestCredentialBody)).toThrowError(SDKErrors.HashMalformedError) + + expect(() => Message.verifyMessageBody({} as MessageBody)).toThrowError(SDKErrors.UnknownMessageBodyTypeError) + }) + it('delegation data structure verifier should throw on faulty delegation data', () => { + // @ts-expect-error + delete requestAcceptDelegationBody.content.delegationData.isPCR + expect(() => Message.verifyDelegationStructure(requestAcceptDelegationBody.content.delegationData)).toThrowError( + TypeError('isPCR is expected to be a boolean') + ) + requestAcceptDelegationBody.content.delegationData.id = 'this is not a delegation id' + expect(() => Message.verifyDelegationStructure(requestAcceptDelegationBody.content.delegationData)).toThrowError( + SDKErrors.DelegationIdTypeError + ) + submitAcceptDelegationBody.content.delegationData.permissions = [] + expect(() => Message.verifyDelegationStructure(submitAcceptDelegationBody.content.delegationData)).toThrowError( + SDKErrors.UnauthorizedError + ) + // @ts-expect-error + delete submitAcceptDelegationBody.content.delegationData.id + expect(() => Message.verifyDelegationStructure(submitAcceptDelegationBody.content.delegationData)).toThrowError( + SDKErrors.DelegationIdMissingError + ) + }) +}) diff --git a/src/messaging/index.ts b/src/messaging/index.ts new file mode 100644 index 0000000..7dbb4d0 --- /dev/null +++ b/src/messaging/index.ts @@ -0,0 +1,366 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * KILT participants can communicate via a 1:1 messaging system. + * + * All messages are **encrypted** with the encryption keys of the involved identities. + * Messages are encrypted using authenticated encryption: the two parties authenticate to each other, but the message authentication provides repudiation possibilities. + * + * The [[Message]] class exposes methods to construct and verify messages. + * + * @module @kiltprotocol/messaging + */ + +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import type { + DecryptCallback, + DidResolveKey, + DidResourceUri, + EncryptCallback, + IEncryptedMessage, + IEncryptedMessageContents, + ICType, + IDelegationData, + IMessage, + MessageBody, +} from '../types' +import { Attestation, Claim, Credential, CType, Quote } from '@kiltprotocol/core' +import { DataUtils, SDKErrors, UUID } from '@kiltprotocol/utils' +import * as Did from '@kiltprotocol/did' +import { hexToU8a, stringToU8a, u8aToHex, u8aToString, isHex } from '@polkadot/util' + +/** + * Checks if delegation data is well formed. + * + * @param delegationData Delegation data to check. + */ +export function verifyDelegationStructure(delegationData: IDelegationData): void { + const { permissions, id, parentId, isPCR, account } = delegationData + + if (!id) { + throw new SDKErrors.DelegationIdMissingError() + } else if (typeof id !== 'string' || !isHex(id)) { + throw new SDKErrors.DelegationIdTypeError() + } + + if (!account) { + throw new SDKErrors.OwnerMissingError() + } + Did.validateUri(account, 'Did') + + if (typeof isPCR !== 'boolean') { + throw new TypeError('isPCR is expected to be a boolean') + } + + if (permissions.length === 0 || permissions.length > 3) { + throw new SDKErrors.UnauthorizedError('Must have at least one permission and no more then two') + } + + if (parentId && (typeof parentId !== 'string' || !isHex(parentId))) { + throw new SDKErrors.DelegationIdTypeError() + } +} + +/** + * Checks if the message body is well-formed. + * + * @param body The message body. + */ +export function verifyMessageBody(body: MessageBody): void { + switch (body.type) { + case 'submit-terms': { + Claim.verifyDataStructure(body.content.claim) + body.content.legitimations.forEach((credential) => Credential.verifyDataStructure(credential)) + if (body.content.delegationId) { + DataUtils.verifyIsHex(body.content.delegationId) + } + if (body.content.quote) { + Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) + } + if (body.content.cTypes) { + body.content.cTypes.forEach((val) => CType.verifyDataStructure(val)) + } + break + } + case 'request-attestation': { + Credential.verifyDataStructure(body.content.credential) + if (body.content.quote) { + Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) + } + break + } + case 'submit-attestation': { + Attestation.verifyDataStructure(body.content.attestation) + break + } + case 'reject-attestation': { + if (!isHex(body.content)) { + throw new SDKErrors.HashMalformedError() + } + break + } + case 'request-credential': { + body.content.cTypes.forEach(({ cTypeHash, trustedAttesters, requiredProperties }): void => { + DataUtils.verifyIsHex(cTypeHash) + trustedAttesters?.forEach((did) => Did.validateUri(did, 'Did')) + requiredProperties?.forEach((requiredProps) => { + if (typeof requiredProps !== 'string') throw new TypeError('Required properties is expected to be a string') + }) + }) + break + } + case 'submit-credential': { + body.content.forEach((presentation) => { + Credential.verifyDataStructure(presentation) + if (!Did.isDidSignature(presentation.claimerSignature)) { + throw new SDKErrors.SignatureMalformedError() + } + }) + break + } + + default: + throw new SDKErrors.UnknownMessageBodyTypeError() + } +} + +/** + * Checks if the message object is well-formed. + * + * @param message The message object. + */ +export function verifyMessageEnvelope(message: IMessage): void { + const { messageId, createdAt, receiver, sender, receivedAt, inReplyTo } = message + if (messageId !== undefined && typeof messageId !== 'string') { + throw new TypeError('Message id is expected to be a string') + } + if (createdAt !== undefined && typeof createdAt !== 'number') { + throw new TypeError('Created at is expected to be a number') + } + if (receivedAt !== undefined && typeof receivedAt !== 'number') { + throw new TypeError('Received at is expected to be a number') + } + Did.validateUri(sender, 'Did') + Did.validateUri(receiver, 'Did') + if (inReplyTo && typeof inReplyTo !== 'string') { + throw new TypeError('In reply to is expected to be a string') + } +} + +/** + * Verifies required properties for a given [[CType]] before sending or receiving a message. + * + * @param requiredProperties The list of required properties that need to be verified against a [[CType]]. + * @param cType A [[CType]] used to verify the properties. + */ +export function verifyRequiredCTypeProperties(requiredProperties: string[], cType: ICType): void { + CType.verifyDataStructure(cType as ICType) + + const unknownProperties = requiredProperties.find((property) => !(property in cType.properties)) + if (unknownProperties) { + throw new SDKErrors.CTypeUnknownPropertiesError() + } +} + +/** + * Verifies that the sender of a [[Message]] is also the owner of it, e.g the owner's and sender's DIDs refer to the same subject. + * + * @param message The [[Message]] object which needs to be decrypted. + * @param message.body The body of the [[Message]] which depends on the [[BodyType]]. + * @param message.sender The sender's DID taken from the [[IMessage]]. + */ +export function ensureOwnerIsSender({ body, sender }: IMessage): void { + switch (body.type) { + case 'request-attestation': + { + const requestAttestation = body + if (!Did.isSameSubject(requestAttestation.content.credential.claim.owner, sender)) { + throw new SDKErrors.IdentityMismatchError('Claim', 'Sender') + } + } + break + case 'submit-attestation': + { + const submitAttestation = body + if (!Did.isSameSubject(submitAttestation.content.attestation.owner, sender)) { + throw new SDKErrors.IdentityMismatchError('Attestation', 'Sender') + } + } + break + case 'submit-credential': + { + const submitClaimsForCtype = body + submitClaimsForCtype.content.forEach((presentation) => { + if (!Did.isSameSubject(presentation.claim.owner, sender)) { + throw new SDKErrors.IdentityMismatchError('Claims', 'Sender') + } + }) + } + break + default: + } +} + +/** + * Symmetrically decrypts the result of [[encrypt]]. + * + * @param encrypted The encrypted message. + * @param decryptCallback The callback to decrypt with the secret key. + * @param decryptionOptions Options to perform the decryption operation. + * @param decryptionOptions.resolveKey The DID key resolver to use. + * @returns The original [[Message]]. + */ +export async function decrypt( + encrypted: IEncryptedMessage, + decryptCallback: DecryptCallback, + { + resolveKey = Did.resolveKey, + }: { + resolveKey?: DidResolveKey + } = {} +): Promise { + const { senderKeyUri, receiverKeyUri, ciphertext, nonce, receivedAt } = encrypted + + const senderKeyDetails = await resolveKey(senderKeyUri, 'keyAgreement') + + const { fragment } = Did.parse(receiverKeyUri) + if (!fragment) { + throw new SDKErrors.DidError(`No fragment for the receiver key ID "${receiverKeyUri}"`) + } + + let data: Uint8Array + try { + data = ( + await decryptCallback({ + peerPublicKey: senderKeyDetails.publicKey, + data: hexToU8a(ciphertext), + nonce: hexToU8a(nonce), + keyUri: receiverKeyUri, + }) + ).data + } catch (cause) { + throw new SDKErrors.DecodingMessageError(undefined, { + cause: cause as Error, + }) + } + + const decoded = u8aToString(data) + + const { body, createdAt, messageId, inReplyTo, references, sender, receiver } = JSON.parse( + decoded + ) as IEncryptedMessageContents + const decrypted: IMessage = { + receiver, + sender, + createdAt, + body, + messageId, + receivedAt, + inReplyTo, + references, + } + + if (sender !== senderKeyDetails.controller) { + throw new SDKErrors.IdentityMismatchError('Encryption key', 'Sender') + } + + return decrypted +} + +/** + * Checks the message structure and body contents (e.g. Hashes match, ensures the owner is the sender). + * Throws, if a check fails. + * + * @param decryptedMessage The decrypted message to check. + */ +export function verify(decryptedMessage: IMessage): void { + verifyMessageBody(decryptedMessage.body) + verifyMessageEnvelope(decryptedMessage) + ensureOwnerIsSender(decryptedMessage) +} + +/** + * Constructs a message from a message body. + * This should be encrypted with [[encrypt]] before sending to the receiver. + * + * @param body The body of the message. + * @param sender The DID of the sender. + * @param receiver The DID of the receiver. + * @returns The message created. + */ +export function fromBody(body: MessageBody, sender: IMessage['sender'], receiver: IMessage['receiver']): IMessage { + return { + body, + createdAt: Date.now(), + receiver, + sender, + messageId: UUID.generate(), + } +} + +/** + * Encrypts the [[Message]] as a string. This can be reversed with [[decrypt]]. + * + * @param message The message to encrypt. + * @param encryptCallback The callback to encrypt with the secret key. + * @param receiverKeyUri The key URI of the receiver. + * @param encryptionOptions Options to perform the encryption operation. + * @param encryptionOptions.resolveKey The DID key resolver to use. + * + * @returns The encrypted version of the original [[Message]], see [[IEncryptedMessage]]. + */ +export async function encrypt( + message: IMessage, + encryptCallback: EncryptCallback, + receiverKeyUri: DidResourceUri, + { + resolveKey = Did.resolveKey, + }: { + resolveKey?: DidResolveKey + } = {} +): Promise { + const receiverKey = await resolveKey(receiverKeyUri, 'keyAgreement') + if (message.receiver !== receiverKey.controller) { + throw new SDKErrors.IdentityMismatchError('receiver public key', 'receiver') + } + + const toEncrypt: IEncryptedMessageContents = { + body: message.body, + createdAt: message.createdAt, + sender: message.sender, + receiver: message.receiver, + messageId: message.messageId, + inReplyTo: message.inReplyTo, + references: message.references, + } + + const serialized = stringToU8a(JSON.stringify(toEncrypt)) + + const encrypted = await encryptCallback({ + did: message.sender, + data: serialized, + peerPublicKey: receiverKey.publicKey, + }) + + const ciphertext = u8aToHex(encrypted.data) + const nonce = u8aToHex(encrypted.nonce) + + return { + receivedAt: message.receivedAt, + ciphertext, + nonce, + senderKeyUri: encrypted.keyUri, + receiverKeyUri: receiverKey.id, + } +} diff --git a/src/types/CryptoCallbacks.ts b/src/types/CryptoCallbacks.ts new file mode 100644 index 0000000..442b9c0 --- /dev/null +++ b/src/types/CryptoCallbacks.ts @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import type { DidResourceUri, DidUri } from './DidDocument.js' + +/** + * Base interface for encryption requests. + */ +export interface EncryptRequestData { + /** + * Data to be encrypted. + */ + data: Uint8Array + /** + * The other party's public key to be used for x25519 Diffie-Hellman key agreement. + */ + peerPublicKey: Uint8Array + /** + * The DID to be used for encryption. + */ + did: DidUri +} + +/** + * Base interface for responses to encryption requests. + */ +export interface EncryptResponseData { + /** + * Result of the encryption. + */ + data: Uint8Array + /** + * A random nonce generated in the encryption process. + */ + nonce: Uint8Array + /** + * The did key uri used for the encryption. + */ + keyUri: DidResourceUri +} + +/** + * Uses stored key material to encrypt a message encoded as u8a. + * + * @param requestData The data to be encrypted, the peers public key and the sender's DID. + * @returns [[EncryptResponseData]] which additionally to the data contains a `nonce` randomly generated in the encryption process (required for decryption). + */ +export interface EncryptCallback { + (requestData: EncryptRequestData): Promise +} + +export interface DecryptRequestData { + /** + * Data to be encrypted. + */ + data: Uint8Array + /** + * The other party's public key to be used for x25519 Diffie-Hellman key agreement. + */ + peerPublicKey: Uint8Array + /** + * The random nonce generated during encryption as u8a. + */ + nonce: Uint8Array + /** + * The did key uri, which should be used for decryption. + */ + keyUri: DidResourceUri +} + +export interface DecryptResponseData { + /** + * Result of the decryption. + */ + data: Uint8Array +} + +/** + * Uses stored key material to decrypt a message encoded as u8a. + * + * @param requestData [[DecryptRequestData]] containing both our and their public keys, the nonce used for encryption, the data to be decrypted. + * @param requestData.nonce The random nonce generated during encryption as u8a. + * @returns A Promise resolving to [[DecryptResponseData]] containing the decrypted message or rejecting if a key is unknown or does not match. + */ +export interface DecryptCallback { + (requestData: DecryptRequestData): Promise +} diff --git a/src/types/DidDocument.ts b/src/types/DidDocument.ts index bada33a..f416b11 100644 --- a/src/types/DidDocument.ts +++ b/src/types/DidDocument.ts @@ -1,14 +1,20 @@ import type { KiltAddress } from './Address' - +import type { BN } from './Imported' /** * A string containing a KILT DID Uri. */ - type DidUriVersion = '' | `v${string}:` type AuthenticationKeyType = '00' | '01' type LightDidEncodedData = '' | `:${string}` +/** + * DID keys are purpose-bound. Their role or purpose is indicated by the verification or key relationship type. + */ +const keyRelationshipsC = ['authentication', 'capabilityDelegation', 'assertionMethod', 'keyAgreement'] as const +export const keyRelationships = keyRelationshipsC as unknown as string[] +export type KeyRelationship = (typeof keyRelationshipsC)[number] + export type DidUri = | `did:kilt:${DidUriVersion}${KiltAddress}` | `did:kilt:light:${DidUriVersion}${AuthenticationKeyType}${KiltAddress}${LightDidEncodedData}` @@ -22,8 +28,104 @@ export type UriFragment = `#${string}` */ export type DidResourceUri = `${DidUri}${UriFragment}` - export type DidSignature = { - keyUri: DidResourceUri - signature: string - } + keyUri: DidResourceUri + signature: string +} + +/** + * The SDK-specific base details of a DID key. + */ +export type BaseDidKey = { + /** + * Relative key URI: `#` sign followed by fragment part of URI. + */ + id: UriFragment + /** + * The public key material. + */ + publicKey: Uint8Array + /** + * The inclusion block of the key, if stored on chain. + */ + includedAt?: BN + /** + * The type of the key. + */ + type: string +} + +/** + * Possible types for a DID encryption key. + */ +const encryptionKeyTypesC = ['x25519'] as const +export const encryptionKeyTypes = encryptionKeyTypesC as unknown as string[] +export type EncryptionKeyType = (typeof encryptionKeyTypesC)[number] + +/** + * Possible types for a DID verification key. + */ +const verificationKeyTypesC = ['sr25519', 'ed25519', 'ecdsa'] as const +export const verificationKeyTypes = verificationKeyTypesC as unknown as string[] +export type VerificationKeyType = (typeof verificationKeyTypesC)[number] + +/** + * The SDK-specific details of a DID verification key. + */ +export type DidVerificationKey = BaseDidKey & { type: VerificationKeyType } +/** + * The SDK-specific details of a DID encryption key. + */ +export type DidEncryptionKey = BaseDidKey & { type: EncryptionKeyType } +/** + * The SDK-specific details of a DID key. + */ +export type DidKey = DidVerificationKey | DidEncryptionKey + +/** + * The SDK-specific details of a new DID service endpoint. + */ +export type DidServiceEndpoint = { + /** + * Relative endpoint URI: `#` sign followed by fragment part of URI. + */ + id: UriFragment + /** + * A list of service types the endpoint exposes. + */ + type: string[] + /** + * A list of URIs the endpoint exposes its services at. + */ + serviceEndpoint: string[] +} + +export interface DidDocument { + uri: DidUri + + authentication: [DidVerificationKey] + assertionMethod?: [DidVerificationKey] + capabilityDelegation?: [DidVerificationKey] + keyAgreement?: DidEncryptionKey[] + + service?: DidServiceEndpoint[] +} + +export type BaseNewDidKey = { + publicKey: Uint8Array + type: string +} + + +export type NewDidVerificationKey = BaseNewDidKey & { + type: VerificationKeyType +} + +export type LightDidSupportedVerificationKeyType = Extract< + VerificationKeyType, + 'ed25519' | 'sr25519' +> + +export type NewLightDidVerificationKey = NewDidVerificationKey & { + type: LightDidSupportedVerificationKeyType +} diff --git a/src/types/DidDocumentExporter.ts b/src/types/DidDocumentExporter.ts new file mode 100644 index 0000000..f3d1a78 --- /dev/null +++ b/src/types/DidDocumentExporter.ts @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import { DidResourceUri, DidServiceEndpoint, DidUri, EncryptionKeyType, VerificationKeyType } from './DidDocument.js' +import { DidResolutionDocumentMetadata } from './DidResolver.js' + +export type ConformingDidDocumentKeyType = + | 'Ed25519VerificationKey2018' + | 'Sr25519VerificationKey2020' + | 'EcdsaSecp256k1VerificationKey2019' + | 'X25519KeyAgreementKey2019' + +export const verificationKeyTypesMap: Record = { + // proposed and used by dock.io, e.g. https://github.com/w3c-ccg/security-vocab/issues/32, https://github.com/docknetwork/sdk/blob/9c818b03bfb4fdf144c20678169c7aad3935ad96/src/utils/vc/contexts/security_context.js + sr25519: 'Sr25519VerificationKey2020', + // these are part of current w3 security vocab, see e.g. https://www.w3.org/ns/did/v1 + ed25519: 'Ed25519VerificationKey2018', + ecdsa: 'EcdsaSecp256k1VerificationKey2019', +} + +export const encryptionKeyTypesMap: Record = { + x25519: 'X25519KeyAgreementKey2019', +} + +/** + * A spec-compliant description of a DID key. + */ +export type ConformingDidKey = { + /** + * The full key URI, in the form of #. + */ + id: DidResourceUri + /** + * The key controller, in the form of . + */ + controller: DidUri + /** + * The base58-encoded public component of the key. + */ + publicKeyBase58: string + /** + * The key type signalling the intended signing/encryption algorithm for the use of this key. + */ + type: ConformingDidDocumentKeyType +} + +/** + * A spec-compliant description of a DID endpoint. + */ +export type ConformingDidServiceEndpoint = Omit & { + /** + * The full service URI, in the form of #. + */ + id: DidResourceUri +} + +/** + * A DID Document according to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). + */ +export type ConformingDidDocument = { + id: DidUri + verificationMethod: ConformingDidKey[] + authentication: [ConformingDidKey['id']] + assertionMethod?: [ConformingDidKey['id']] + keyAgreement?: [ConformingDidKey['id']] + capabilityDelegation?: [ConformingDidKey['id']] + service?: ConformingDidServiceEndpoint[] + alsoKnownAs?: [`w3n:${string}`] +} + +/** + * A JSON+LD DID Document that extends a traditional DID Document with additional semantic information. + */ +export type JsonLDDidDocument = ConformingDidDocument & { '@context': string[] } + +/** + * DID Resolution Metadata returned by the DID `resolve` function as described by DID specifications (https://www.w3.org/TR/did-core/#did-resolution-metadata). + */ +export interface DidResolutionMetadata { + error?: 'notFound' | 'invalidDid' + errorMessage?: string +} + +/** + * Object containing the return values of the DID `resolve` function as described by DID specifications (https://www.w3.org/TR/did-core/#did-resolution). + */ +export interface ConformingDidResolutionResult { + didDocumentMetadata: Partial + didResolutionMetadata: DidResolutionMetadata + didDocument?: Partial & Pick +} diff --git a/src/types/DidResolver.ts b/src/types/DidResolver.ts new file mode 100644 index 0000000..a5655ff --- /dev/null +++ b/src/types/DidResolver.ts @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import { ConformingDidKey, ConformingDidServiceEndpoint } from './DidDocumentExporter.js' +import type { DidDocument, DidKey, DidResourceUri, DidUri, KeyRelationship } from './DidDocument.js' + +/** + * DID resolution metadata that includes a subset of the properties defined in the [W3C proposed standard](https://www.w3.org/TR/did-core/#did-resolution). + */ +export type DidResolutionDocumentMetadata = { + /** + * If present, it indicates that the resolved by DID should be treated as if it were the DID as specified in this property. + */ + canonicalId?: DidUri + /** + * A boolean flag indicating whether the resolved DID has been deactivated. + */ + deactivated: boolean +} + +/** + * The result of a DID resolution. + * + * It includes the DID Document, and optional document resolution metadata. + */ +export type DidResolutionResult = { + /** + * The resolved DID document. It is undefined if the DID has been upgraded or deleted. + */ + document?: DidDocument + /** + * The DID resolution metadata. + */ + metadata: DidResolutionDocumentMetadata + /** + * The DID's web3Name, if any. + */ + web3Name?: string +} + +export type ResolvedDidKey = Pick & + Pick + +export type ResolvedDidServiceEndpoint = ConformingDidServiceEndpoint + +/** + * Resolves a DID URI, returning the full contents of the DID document. + * + * @param did A DID URI identifying a DID document. All additional parameters and fragments are ignored. + * @returns A promise of a [[DidResolutionResult]] object representing the DID document or null if the DID + * cannot be resolved. + */ +export type DidResolve = (did: DidUri) => Promise + +/** + * Resolves a DID URI identifying a public key associated with a DID. + * + * @param didUri A DID URI identifying a public key associated with a DID through the DID document. + * @returns A promise of a [[ResolvedDidKey]] object representing the DID public key or null if + * the DID or key URI cannot be resolved. + */ +export type DidResolveKey = ( + didUri: DidResourceUri, + expectedVerificationMethod?: KeyRelationship +) => Promise diff --git a/src/types/Message.ts b/src/types/Message.ts index 42620cb..7141ac2 100644 --- a/src/types/Message.ts +++ b/src/types/Message.ts @@ -3,7 +3,17 @@ import type { ICredential, ICredentialPresentation } from './Credential' import type { IQuoteAgreement } from './Quote' import type { IAttestation } from './Attestation' import type { CTypeHash } from './CType' -import type { DidUri } from './DidDocument' +import type { DidResourceUri, DidUri } from './DidDocument' +import type { IDelegationNode } from './Delegation' +import { PartialClaim } from './Claim' + +export interface IDelegationData { + account: IDelegationNode['account'] + id: IDelegationNode['id'] + parentId: IDelegationNode['id'] + permissions: IDelegationNode['permissions'] + isPCR: boolean +} export type MessageBodyType = | 'error' @@ -16,6 +26,7 @@ export type MessageBodyType = | 'reject-attestation' | 'request-credential' | 'submit-credential' + | 'reject-terms' interface IMessageBodyBase { // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -91,6 +102,14 @@ export interface IRequestCredentialContent { challenge?: string } +export interface IRejectTermsContent { + claim: PartialClaim + legitimations: ICredential[] + delegationId?: IDelegationNode['id'] +} + + + export interface ISubmitCredential extends IMessageBodyBase { content: ICredentialPresentation[] type: 'submit-credential' @@ -127,6 +146,16 @@ export type MessageBody = | IRequestCredential | ISubmitCredential +/** + * - `body` - The body of the message, see [[MessageBody]]. + * - `createdAt` - The timestamp of the message construction. + * - `sender` - The DID of the sender. + * - `receiver` - The DID of the receiver. + * - `messageId` - The message id. + * - `receivedAt` - The timestamp of the message reception. + * - `inReplyTo` - The id of the parent-message. + * - `references` - The references or the in-reply-to of the parent-message followed by the message-id of the parent-message. + */ export interface IMessage { body: MessageBody createdAt: number @@ -137,3 +166,23 @@ export interface IMessage { inReplyTo?: IMessage['messageId'] references?: Array } + +/** + * Everything which is part of the encrypted and protected part of the [[IMessage]]. + */ +export type IEncryptedMessageContents = Omit + +/** + * Removes the plaintext [[IEncryptedMessageContents]] from an [[IMessage]] and instead includes them in encrypted form. + * This adds the following fields: + * - `ciphertext` - The encrypted message content. + * - `nonce` - The encryption nonce. + * - `receiverKeyUri` - The URI of the receiver's encryption key. + * - `senderKeyUri` - The URI of the sender's encryption key. + */ +export type IEncryptedMessage = Pick & { + receiverKeyUri: DidResourceUri + senderKeyUri: DidResourceUri + ciphertext: string + nonce: string +} diff --git a/src/types/index.ts b/src/types/index.ts index 033c323..4229248 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,9 +1,20 @@ import type { IEncryptedMessage, DidUri, KiltAddress, DidResourceUri } from '@kiltprotocol/types' import type { HexString } from '@polkadot/util/types' import type { CredentialDigestProof, SelfSignedProof, VerifiableCredential, constants } from '@kiltprotocol/vc-export' -import type * as IMessage from "./Message"; -export type Message = typeof IMessage; +export * from './Attestation.js' +export * from './CType.js' +export * from './Claim.js' +export * from './Delegation.js' +export * from './Address.js' +export * from './Message.js' +export * from './Quote.js' +export * from './Credential.js' +export * from './Terms.js' +export * from './DidDocument.js' +export * from './Imported.js' +export * from './CryptoCallbacks.js' +export * from './DidResolver.js' export type This = typeof globalThis export interface IEncryptedMessageV1 { From 0ab879c459d9de21013edc8fbc550baa5073971e Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Fri, 4 Aug 2023 14:52:42 +0200 Subject: [PATCH 04/39] with quote --- src/quote/Quote.test.ts | 267 +++++++++++++++++++++++++++++++++++++++ src/quote/Quote.ts | 198 +++++++++++++++++++++++++++++ src/quote/QuoteSchema.ts | 56 ++++++++ src/quote/index.ts | 9 ++ 4 files changed, 530 insertions(+) create mode 100644 src/quote/Quote.test.ts create mode 100644 src/quote/Quote.ts create mode 100644 src/quote/QuoteSchema.ts create mode 100644 src/quote/index.ts diff --git a/src/quote/Quote.test.ts b/src/quote/Quote.test.ts new file mode 100644 index 0000000..09b407b --- /dev/null +++ b/src/quote/Quote.test.ts @@ -0,0 +1,267 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import * as Did from '@kiltprotocol/did' +import type { + DidDocument, + DidResourceUri, + ICType, + IClaim, + ICostBreakdown, + ICredential, + IQuote, + IQuoteAgreement, + IQuoteAttesterSigned, + ResolvedDidKey, +} from '@kiltprotocol/types' +import { Crypto, SDKErrors } from '@kiltprotocol/utils' + +import { + createLocalDemoFullDidFromKeypair, + makeSigningKeyTool, +} from '../tests' +import { Credential, CType } from '@kiltprotocol/sdk-js' +import * as Quote from './Quote' +import { QuoteSchema } from './QuoteSchema' + +describe('Quote', () => { + let claimerIdentity: DidDocument + const claimer = makeSigningKeyTool('ed25519') + + let attesterIdentity: DidDocument + const attester = makeSigningKeyTool('ed25519') + + let invalidCost: ICostBreakdown + let date: string + let testCType: ICType + let claim: IClaim + let credential: ICredential + let invalidCostQuoteData: IQuote + let invalidPropertiesQuoteData: IQuote + let validQuoteData: IQuote + let validAttesterSignedQuote: IQuoteAttesterSigned + let quoteBothAgreed: IQuoteAgreement + let invalidPropertiesQuote: IQuote + let invalidCostQuote: IQuote + + async function mockResolveKey( + keyUri: DidResourceUri + ): Promise { + const { did } = Did.parse(keyUri) + const document = [claimerIdentity, attesterIdentity].find( + ({ uri }) => uri === did + ) + if (!document) throw new Error('Cannot resolve mocked DID') + return Did.keyToResolvedKey(document.authentication[0], did) + } + + beforeAll(async () => { + claimerIdentity = await createLocalDemoFullDidFromKeypair(claimer.keypair) + + attesterIdentity = await createLocalDemoFullDidFromKeypair(attester.keypair) + + invalidCost = { + gross: 233, + tax: { vat: 3.3 }, + } as unknown as ICostBreakdown + date = new Date(2019, 11, 10).toISOString() + + testCType = CType.fromProperties('Quote Information', { + name: { type: 'string' }, + }) + + claim = { + cTypeHash: CType.idToHash(testCType.$id), + contents: {}, + owner: claimerIdentity.uri, + } + + // build credential with legitimations + credential = Credential.fromClaim(claim) + + // @ts-ignore + invalidCostQuoteData = { + cTypeHash: '0x12345678', + cost: invalidCost, + currency: 'Euro', + timeframe: date, + termsAndConditions: 'Lots of these', + } as IQuote + + invalidPropertiesQuoteData = { + cTypeHash: '0x12345678', + cost: { + gross: 233, + net: 23.3, + tax: { vat: 3.3 }, + }, + timeframe: date, + currency: 'Euro', + termsAndConditions: 'Lots of these', + } as unknown as IQuote + + validQuoteData = { + attesterDid: attesterIdentity.uri, + cTypeHash: '0x12345678', + cost: { + gross: 233, + net: 23.3, + tax: { vat: 3.3 }, + }, + currency: 'Euro', + timeframe: new Date('12-04-2020').toISOString(), + termsAndConditions: 'Lots of these', + } + validAttesterSignedQuote = await Quote.createAttesterSignedQuote( + validQuoteData, + attester.getSignCallback(attesterIdentity) + ) + quoteBothAgreed = await Quote.createQuoteAgreement( + validAttesterSignedQuote, + credential.rootHash, + claimer.getSignCallback(claimerIdentity), + claimerIdentity.uri, + { + didResolveKey: mockResolveKey, + } + ) + invalidPropertiesQuote = invalidPropertiesQuoteData + invalidCostQuote = invalidCostQuoteData + }) + + it('tests created quote data against given data', async () => { + expect(validQuoteData.attesterDid).toEqual(attesterIdentity.uri) + const sign = claimer.getSignCallback(claimerIdentity) + const signature = Did.signatureToJson( + await sign({ + data: Crypto.hash( + Crypto.encodeObjectAsStr({ + ...validAttesterSignedQuote, + claimerDid: claimerIdentity.uri, + rootHash: credential.rootHash, + }) + ), + did: claimerIdentity.uri, + keyRelationship: 'authentication', + }) + ) + expect(signature).toEqual(quoteBothAgreed.claimerSignature) + + const { fragment: attesterKeyId } = Did.parse( + validAttesterSignedQuote.attesterSignature.keyUri + ) + + expect(() => + Crypto.verify( + Crypto.hashStr( + Crypto.encodeObjectAsStr({ + attesterDid: validQuoteData.attesterDid, + cTypeHash: validQuoteData.cTypeHash, + cost: validQuoteData.cost, + currency: validQuoteData.currency, + timeframe: validQuoteData.timeframe, + termsAndConditions: validQuoteData.termsAndConditions, + }) + ), + validAttesterSignedQuote.attesterSignature.signature, + Did.getKey(attesterIdentity, attesterKeyId!)?.publicKey || + new Uint8Array() + ) + ).not.toThrow() + await expect( + Quote.verifyAttesterSignedQuote(validAttesterSignedQuote, { + didResolveKey: mockResolveKey, + }) + ).resolves.not.toThrow() + await expect( + Quote.verifyQuoteAgreement(quoteBothAgreed, { + didResolveKey: mockResolveKey, + }) + ).resolves.not.toThrow() + expect( + await Quote.createAttesterSignedQuote( + validQuoteData, + attester.getSignCallback(attesterIdentity) + ) + ).toEqual(validAttesterSignedQuote) + }) + it('validates created quotes against QuoteSchema', () => { + expect(Quote.validateQuoteSchema(QuoteSchema, validQuoteData)).toBe(true) + expect(Quote.validateQuoteSchema(QuoteSchema, invalidCostQuote)).toBe(false) + expect(Quote.validateQuoteSchema(QuoteSchema, invalidPropertiesQuote)).toBe( + false + ) + }) + + it('detects tampering', async () => { + const messedWithCurrency: IQuoteAttesterSigned = { + ...validAttesterSignedQuote, + currency: 'Bananas', + } + await expect( + Quote.verifyAttesterSignedQuote(messedWithCurrency, { + didResolveKey: mockResolveKey, + }) + ).rejects.toThrow(SDKErrors.SignatureUnverifiableError) + const messedWithRootHash: IQuoteAgreement = { + ...quoteBothAgreed, + rootHash: '0x1234', + } + await expect( + Quote.verifyQuoteAgreement(messedWithRootHash, { + didResolveKey: mockResolveKey, + }) + ).rejects.toThrow(SDKErrors.SignatureUnverifiableError) + }) + + it('complains if attesterDid does not match attester signature', async () => { + const sign = claimer.getSignCallback(claimerIdentity) + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { attesterSignature, ...attesterSignedQuote } = + validAttesterSignedQuote + const wrongSignerAttester: IQuoteAttesterSigned = { + ...attesterSignedQuote, + attesterSignature: Did.signatureToJson( + await sign({ + data: Crypto.hash(Crypto.encodeObjectAsStr(attesterSignedQuote)), + did: claimerIdentity.uri, + keyRelationship: 'authentication', + }) + ), + } + + await expect( + Quote.verifyAttesterSignedQuote(wrongSignerAttester, { + didResolveKey: mockResolveKey, + }) + ).rejects.toThrow(SDKErrors.DidSubjectMismatchError) + }) + + it('complains if claimerDid does not match claimer signature', async () => { + const sign = attester.getSignCallback(attesterIdentity) + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { claimerSignature, ...restQuote } = quoteBothAgreed + const wrongSignerClaimer: IQuoteAgreement = { + ...restQuote, + claimerSignature: Did.signatureToJson( + await sign({ + data: Crypto.hash(Crypto.encodeObjectAsStr(restQuote)), + did: attesterIdentity.uri, + keyRelationship: 'authentication', + }) + ), + } + + await expect( + Quote.verifyQuoteAgreement(wrongSignerClaimer, { + didResolveKey: mockResolveKey, + }) + ).rejects.toThrow(SDKErrors.DidSubjectMismatchError) + }) +}) diff --git a/src/quote/Quote.ts b/src/quote/Quote.ts new file mode 100644 index 0000000..654e8f8 --- /dev/null +++ b/src/quote/Quote.ts @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +/** + * [[Quote]] constructs a framework for Attesters to make an offer for building a [[Claim]] on a [[CType]] in which it includes a price and other terms & conditions upon which a claimer can agree. + * + * A [[Quote]] object represents a legal **offer** for the closure of a contract attesting a [[Claim]] from the [[CType]] specified within the offer. + * + * A [[Quote]] comes with a versionable spec, allowing different [[Quote]] specs to exist over time and tracks under which [[Quote]] a contract was closed. + * + * @packageDocumentation + */ + +import type { + IQuote, + IQuoteAgreement, + IQuoteAttesterSigned, + ICredential, + SignCallback, + DidResolveKey, + DidUri, +} from '@kiltprotocol/types' +import { Crypto, JsonSchema, SDKErrors } from '@kiltprotocol/utils' +import { + resolveKey, + verifyDidSignature, + signatureToJson, + signatureFromJson, +} from '@kiltprotocol/did' +import { QuoteSchema } from './QuoteSchema' + +/** + * Validates the quote against the meta schema and quote data against the provided schema. + * + * @param schema A [[Quote]] schema object. + * @param validate [[Quote]] data to be validated against the provided schema. + * @param messages The errors messages are listed in an array. + * + * @returns Whether the quote schema is valid. + */ +export function validateQuoteSchema( + schema: JsonSchema.Schema, + validate: unknown, + messages?: string[] +): boolean { + const validator = new JsonSchema.Validator(schema) + if (schema.$id !== QuoteSchema.$id) { + validator.addSchema(QuoteSchema) + } + const result = validator.validate(validate) + if (!result.valid && messages) { + result.errors.forEach((error) => { + messages.push(error.error) + }) + } + return result.valid +} + +// TODO: should have a "create quote" function. + +/** + * Signs a [[Quote]] object as an Attester. + * + * @param quoteInput A [[Quote]] object. + * @param sign The callback to sign with the private key. + * @returns A signed [[Quote]] object. + */ +export async function createAttesterSignedQuote( + quoteInput: IQuote, + sign: SignCallback +): Promise { + if (!validateQuoteSchema(QuoteSchema, quoteInput)) { + throw new SDKErrors.QuoteUnverifiableError() + } + + const signature = await sign({ + data: Crypto.hash(Crypto.encodeObjectAsStr(quoteInput)), + did: quoteInput.attesterDid, + keyRelationship: 'authentication', + }) + return { + ...quoteInput, + attesterSignature: signatureToJson(signature), + } +} + +/** + * Verifies a [[IQuoteAttesterSigned]] object. + * + * @param quote The object which to be verified. + * @param options Optional settings. + * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. + */ +export async function verifyAttesterSignedQuote( + quote: IQuoteAttesterSigned, + { + didResolveKey = resolveKey, + }: { + didResolveKey?: DidResolveKey + } = {} +): Promise { + const { attesterSignature, ...basicQuote } = quote + await verifyDidSignature({ + ...signatureFromJson(attesterSignature), + message: Crypto.hashStr(Crypto.encodeObjectAsStr(basicQuote)), + expectedSigner: basicQuote.attesterDid, + expectedVerificationMethod: 'authentication', + didResolveKey, + }) + + const messages: string[] = [] + if (!validateQuoteSchema(QuoteSchema, basicQuote, messages)) { + throw new SDKErrors.QuoteUnverifiableError() + } +} + +/** + * Creates a [[Quote]] signed by the Attester and the Claimer. + * + * @param attesterSignedQuote A [[Quote]] object signed by an Attester. + * @param credentialRootHash A root hash of the entire object. + * @param sign The callback to sign with the private key. + * @param claimerDid The DID of the Claimer, who has to sign. + * @param options Optional settings. + * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. + * @returns A [[Quote]] agreement signed by both the Attester and Claimer. + */ +export async function createQuoteAgreement( + attesterSignedQuote: IQuoteAttesterSigned, + credentialRootHash: ICredential['rootHash'], + sign: SignCallback, + claimerDid: DidUri, + { + didResolveKey = resolveKey, + }: { + didResolveKey?: DidResolveKey + } = {} +): Promise { + const { attesterSignature, ...basicQuote } = attesterSignedQuote + + await verifyDidSignature({ + ...signatureFromJson(attesterSignature), + message: Crypto.hashStr(Crypto.encodeObjectAsStr(basicQuote)), + expectedVerificationMethod: 'authentication', + didResolveKey, + }) + + const quoteAgreement = { + ...attesterSignedQuote, + rootHash: credentialRootHash, + claimerDid, + } + const signature = await sign({ + data: Crypto.hash(Crypto.encodeObjectAsStr(quoteAgreement)), + did: claimerDid, + keyRelationship: 'authentication', + }) + + return { + ...quoteAgreement, + claimerSignature: signatureToJson(signature), + } +} + +/** + * Verifies a [[IQuoteAgreement]] object. + * + * @param quote The object to be verified. + * @param options Optional settings. + * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. + */ +export async function verifyQuoteAgreement( + quote: IQuoteAgreement, + { + didResolveKey = resolveKey, + }: { + didResolveKey?: DidResolveKey + } = {} +): Promise { + const { claimerSignature, claimerDid, rootHash, ...attesterSignedQuote } = + quote + // verify attester signature + await verifyAttesterSignedQuote(attesterSignedQuote, { didResolveKey }) + // verify claimer signature + await verifyDidSignature({ + ...signatureFromJson(claimerSignature), + message: Crypto.hashStr( + Crypto.encodeObjectAsStr({ ...attesterSignedQuote, claimerDid, rootHash }) + ), + expectedSigner: claimerDid, + expectedVerificationMethod: 'authentication', + didResolveKey, + }) +} diff --git a/src/quote/QuoteSchema.ts b/src/quote/QuoteSchema.ts new file mode 100644 index 0000000..d7d0d93 --- /dev/null +++ b/src/quote/QuoteSchema.ts @@ -0,0 +1,56 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import { JsonSchema } from '@kiltprotocol/utils' + +export const QuoteSchema: JsonSchema.Schema = { + $schema: 'http://json-schema.org/draft-07/schema#', + $id: 'kilt:quote:v1', + type: 'object', + title: 'Quote', + properties: { + attesterDid: { + type: 'string', + }, + cTypeHash: { + type: 'string', + }, + cost: { + type: 'object', + required: ['net', 'gross', 'tax'], + properties: { + net: { + type: 'number', + }, + gross: { + type: 'number', + }, + tax: { + type: 'object', + }, + }, + }, + currency: { + type: 'string', + }, + termsAndConditions: { + type: 'string', + }, + timeframe: { + type: 'string', + format: 'date-time', + }, + }, + required: [ + 'attesterDid', + 'cTypeHash', + 'cost', + 'currency', + 'termsAndConditions', + 'timeframe', + ], +} diff --git a/src/quote/index.ts b/src/quote/index.ts new file mode 100644 index 0000000..5f5d3cb --- /dev/null +++ b/src/quote/index.ts @@ -0,0 +1,9 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +export * from './Quote.js' +export { QuoteSchema } from './QuoteSchema.js' From 7008be2f85b18809113970f4a0432f74d9eec343 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Mon, 7 Aug 2023 15:21:06 +0200 Subject: [PATCH 05/39] fix: make exportable --- src/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.ts b/src/index.ts index c66149a..2286ada 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1 +1,3 @@ export { getExtensions, watchExtensions, initializeKiltExtensionAPI } from './getExtension' +export * from './messaging' +export * from './quote' From 5bb1159c9acefd80841d1ca3d334789935a8948c Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Mon, 7 Aug 2023 16:31:07 +0200 Subject: [PATCH 06/39] fix: test against latest not develop --- .github/workflows/publish.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 9c1413b..feb8c23 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -18,7 +18,7 @@ jobs: node-version: 16 cache: 'yarn' - - name: yarn install + - name: yarn install run: yarn install --immutable - name: Configure AWS credentials @@ -34,7 +34,7 @@ jobs: - name: set image name run: | - echo "IMG_NAME=${{ steps.login-ecr.outputs.registry }}/kilt/prototype-chain:latest-develop" >> "$GITHUB_ENV" + echo "IMG_NAME=${{ steps.login-ecr.outputs.registry }}/kilt/prototype-chain:latest" >> "$GITHUB_ENV" - name: pull image run: docker pull $IMG_NAME @@ -45,7 +45,7 @@ jobs: TESTCONTAINERS_NODE_IMG: ${{ env.IMG_NAME }} run: | yarn test - + - name: yarn build run: yarn build From 819d31538e933656a2972917be29b0b1d81d80c9 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Mon, 7 Aug 2023 16:34:43 +0200 Subject: [PATCH 07/39] fix: test against latest not develop --- .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 01bb2c8..5a23f2c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -28,7 +28,7 @@ jobs: - name: set image name run: | - echo "IMG_NAME=${{ steps.login-ecr.outputs.registry }}/kilt/prototype-chain:latest-develop" >> "$GITHUB_ENV" + echo "IMG_NAME=${{ steps.login-ecr.outputs.registry }}/kilt/prototype-chain:latest" >> "$GITHUB_ENV" - name: pull image run: docker pull $IMG_NAME From dcc28a79ee1773f354473ac05694a35547464e2a Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Tue, 8 Aug 2023 09:44:03 +0200 Subject: [PATCH 08/39] refactor: reduce types --- src/messaging/Message.test.ts | 32 ++++---- src/messaging/index.ts | 7 +- src/tests/messageUtils.ts | 3 +- src/types/Address.ts | 35 --------- src/types/Attestation.ts | 19 ----- src/types/CType.ts | 62 --------------- src/types/Claim.ts | 22 ------ src/types/Credential.ts | 31 -------- src/types/CryptoCallbacks.ts | 91 --------------------- src/types/Delegation.ts | 32 -------- src/types/DidDocument.ts | 131 ------------------------------- src/types/DidDocumentExporter.ts | 95 ---------------------- src/types/DidResolver.ts | 69 ---------------- src/types/Message.ts | 8 +- src/types/index.ts | 10 +-- 15 files changed, 24 insertions(+), 623 deletions(-) delete mode 100644 src/types/Address.ts delete mode 100644 src/types/Attestation.ts delete mode 100644 src/types/CType.ts delete mode 100644 src/types/Claim.ts delete mode 100644 src/types/Credential.ts delete mode 100644 src/types/CryptoCallbacks.ts delete mode 100644 src/types/Delegation.ts delete mode 100644 src/types/DidDocument.ts delete mode 100644 src/types/DidDocumentExporter.ts delete mode 100644 src/types/DidResolver.ts diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index 62a8253..8238043 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -10,16 +10,30 @@ import { u8aToHex } from '@polkadot/util' import { Attestation, CType, Claim, Credential, Quote } from '@kiltprotocol/core' import * as Did from '@kiltprotocol/did' -import type { - DidDocument, +import { Crypto, SDKErrors } from '@kiltprotocol/utils' + +import { + KeyTool, + KeyToolSignCallback, + createLocalDemoFullDidFromKeypair, + createLocalDemoFullDidFromLightDid, + makeEncryptionKeyTool, + makeSigningKeyTool, +} from '../tests' +import * as Message from './index' + +import type { DidDocument, DidKey, DidResourceUri, DidUri, IAttestation, ICType, + ResolvedDidKey, IClaim, ICredential, - ICredentialPresentation, + ICredentialPresentation +} from '@kiltprotocol/sdk-js' +import type { IEncryptedMessage, IMessage, IQuote, @@ -36,9 +50,7 @@ import type { ISubmitTerms, ITerms, MessageBody, - ResolvedDidKey, } from '../types' - import type { ISubmitDelegationApproval, IRequestDelegationApproval, @@ -46,17 +58,7 @@ import type { IRequestAcceptDelegation, } from '@kiltprotocol/types' -import { Crypto, SDKErrors } from '@kiltprotocol/utils' -import { - KeyTool, - KeyToolSignCallback, - createLocalDemoFullDidFromKeypair, - createLocalDemoFullDidFromLightDid, - makeEncryptionKeyTool, - makeSigningKeyTool, -} from '../tests' -import * as Message from './index' describe('Messaging', () => { let aliceLightDid: DidDocument diff --git a/src/messaging/index.ts b/src/messaging/index.ts index 7dbb4d0..d8bbece 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -24,17 +24,14 @@ */ import type { - DecryptCallback, - DidResolveKey, - DidResourceUri, - EncryptCallback, IEncryptedMessage, IEncryptedMessageContents, - ICType, IDelegationData, IMessage, MessageBody, } from '../types' + +import type { ICType, EncryptCallback, DidResourceUri, DidResolveKey, DecryptCallback } from '@kiltprotocol/types' import { Attestation, Claim, Credential, CType, Quote } from '@kiltprotocol/core' import { DataUtils, SDKErrors, UUID } from '@kiltprotocol/utils' import * as Did from '@kiltprotocol/did' diff --git a/src/tests/messageUtils.ts b/src/tests/messageUtils.ts index 029cf13..10f4209 100644 --- a/src/tests/messageUtils.ts +++ b/src/tests/messageUtils.ts @@ -9,7 +9,8 @@ import { DidKey, DidVerificationKey, DecryptCallback, - EncryptCallback } from '../types' + EncryptCallback } from '@kiltprotocol/types' + import { Did, SignCallback, diff --git a/src/types/Address.ts b/src/types/Address.ts deleted file mode 100644 index 9ee9edf..0000000 --- a/src/types/Address.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import '@polkadot/keyring' // TS needs this for the augmentation below - -import type { HexString, KeyringPair, Prefix } from './Imported' - -export interface KiltEncryptionKeypair { - secretKey: Uint8Array - publicKey: Uint8Array - type: 'x25519' -} - -export interface KiltKeyringPair extends KeyringPair { - address: `4${string}` - type: Exclude -} - -/// A KILT-chain specific address, encoded with the KILT 38 network prefix. -export type KiltAddress = KiltKeyringPair['address'] - -declare module '@polkadot/keyring' { - function encodeAddress( - key: HexString | Uint8Array | string, - ss58Format?: Prefix - ): string - function encodeAddress( - key: HexString | Uint8Array | string, - ss58Format?: 38 - ): KiltAddress -} diff --git a/src/types/Attestation.ts b/src/types/Attestation.ts deleted file mode 100644 index 0f42f89..0000000 --- a/src/types/Attestation.ts +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import type { DidUri } from './DidDocument' -import type { IDelegationNode } from './Delegation' -import type { ICredential } from './Credential' -import type { CTypeHash } from './CType' - -export interface IAttestation { - claimHash: ICredential['rootHash'] - cTypeHash: CTypeHash - owner: DidUri - delegationId: IDelegationNode['id'] | null - revoked: boolean -} diff --git a/src/types/CType.ts b/src/types/CType.ts deleted file mode 100644 index 7ab4452..0000000 --- a/src/types/CType.ts +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import type { HexString } from './Imported' - -export type InstanceType = 'boolean' | 'integer' | 'number' | 'string' | 'array' - -export type CTypeHash = HexString - -interface TypePattern { - type: InstanceType -} - -interface StringPattern extends TypePattern { - type: 'string' - format?: 'date' | 'time' | 'uri' - enum?: string[] - minLength?: number - maxLength?: number -} - -interface NumberPattern extends TypePattern { - type: 'integer' | 'number' - enum?: number[] - minimum?: number - maximum?: number -} - -interface BooleanPattern extends TypePattern { - type: 'boolean' -} - -interface RefPattern { - $ref: string -} - -interface ArrayPattern extends TypePattern { - type: 'array' - items: BooleanPattern | NumberPattern | StringPattern | RefPattern - minItems?: number - maxItems?: number -} - -export interface ICType { - $id: `kilt:ctype:${CTypeHash}` - $schema: string - title: string - properties: { - [key: string]: - | BooleanPattern - | NumberPattern - | StringPattern - | ArrayPattern - | RefPattern - } - type: 'object' - additionalProperties?: false -} diff --git a/src/types/Claim.ts b/src/types/Claim.ts deleted file mode 100644 index 3a22efb..0000000 --- a/src/types/Claim.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { CTypeHash } from './CType' -import type { DidUri } from './DidDocument' - -type ClaimPrimitives = string | number | boolean - -export interface IClaimContents { - [key: string]: - | ClaimPrimitives - | IClaimContents - | Array -} - -export interface IClaim { - cTypeHash: CTypeHash - contents: IClaimContents - owner: DidUri -} - -/** - * The minimal partial claim from which a JSON-LD representation can be built. - */ -export type PartialClaim = Partial & Pick diff --git a/src/types/Credential.ts b/src/types/Credential.ts deleted file mode 100644 index 7ea232f..0000000 --- a/src/types/Credential.ts +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import type { IClaim } from './Claim' -import type { IDelegationNode } from './Delegation' -import type { HexString } from './Imported' -import type { DidSignature } from './DidDocument' - -export type Hash = HexString - -export type NonceHash = { - hash: Hash - nonce?: string -} - -export interface ICredential { - claim: IClaim - claimNonceMap: Record - claimHashes: Hash[] - delegationId: IDelegationNode['id'] | null - legitimations: ICredential[] - rootHash: Hash -} - -export interface ICredentialPresentation extends ICredential { - claimerSignature: DidSignature & { challenge?: string } -} diff --git a/src/types/CryptoCallbacks.ts b/src/types/CryptoCallbacks.ts deleted file mode 100644 index 442b9c0..0000000 --- a/src/types/CryptoCallbacks.ts +++ /dev/null @@ -1,91 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import type { DidResourceUri, DidUri } from './DidDocument.js' - -/** - * Base interface for encryption requests. - */ -export interface EncryptRequestData { - /** - * Data to be encrypted. - */ - data: Uint8Array - /** - * The other party's public key to be used for x25519 Diffie-Hellman key agreement. - */ - peerPublicKey: Uint8Array - /** - * The DID to be used for encryption. - */ - did: DidUri -} - -/** - * Base interface for responses to encryption requests. - */ -export interface EncryptResponseData { - /** - * Result of the encryption. - */ - data: Uint8Array - /** - * A random nonce generated in the encryption process. - */ - nonce: Uint8Array - /** - * The did key uri used for the encryption. - */ - keyUri: DidResourceUri -} - -/** - * Uses stored key material to encrypt a message encoded as u8a. - * - * @param requestData The data to be encrypted, the peers public key and the sender's DID. - * @returns [[EncryptResponseData]] which additionally to the data contains a `nonce` randomly generated in the encryption process (required for decryption). - */ -export interface EncryptCallback { - (requestData: EncryptRequestData): Promise -} - -export interface DecryptRequestData { - /** - * Data to be encrypted. - */ - data: Uint8Array - /** - * The other party's public key to be used for x25519 Diffie-Hellman key agreement. - */ - peerPublicKey: Uint8Array - /** - * The random nonce generated during encryption as u8a. - */ - nonce: Uint8Array - /** - * The did key uri, which should be used for decryption. - */ - keyUri: DidResourceUri -} - -export interface DecryptResponseData { - /** - * Result of the decryption. - */ - data: Uint8Array -} - -/** - * Uses stored key material to decrypt a message encoded as u8a. - * - * @param requestData [[DecryptRequestData]] containing both our and their public keys, the nonce used for encryption, the data to be decrypted. - * @param requestData.nonce The random nonce generated during encryption as u8a. - * @returns A Promise resolving to [[DecryptResponseData]] containing the decrypted message or rejecting if a key is unknown or does not match. - */ -export interface DecryptCallback { - (requestData: DecryptRequestData): Promise -} diff --git a/src/types/Delegation.ts b/src/types/Delegation.ts deleted file mode 100644 index 046b256..0000000 --- a/src/types/Delegation.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import type { CTypeHash } from './CType' -import type { DidUri } from './DidDocument' - -/* eslint-disable no-bitwise */ -export const Permission = { - ATTEST: 1 << 0, // 0001 - DELEGATE: 1 << 1, // 0010 -} as const - -export type PermissionType = (typeof Permission)[keyof typeof Permission] - -export interface IDelegationNode { - id: string - hierarchyId: IDelegationNode['id'] - parentId?: IDelegationNode['id'] - childrenIds: Array - account: DidUri - permissions: PermissionType[] - revoked: boolean -} - -export interface IDelegationHierarchyDetails { - id: IDelegationNode['id'] - cTypeHash: CTypeHash -} diff --git a/src/types/DidDocument.ts b/src/types/DidDocument.ts deleted file mode 100644 index f416b11..0000000 --- a/src/types/DidDocument.ts +++ /dev/null @@ -1,131 +0,0 @@ -import type { KiltAddress } from './Address' -import type { BN } from './Imported' -/** - * A string containing a KILT DID Uri. - */ - -type DidUriVersion = '' | `v${string}:` -type AuthenticationKeyType = '00' | '01' -type LightDidEncodedData = '' | `:${string}` - -/** - * DID keys are purpose-bound. Their role or purpose is indicated by the verification or key relationship type. - */ -const keyRelationshipsC = ['authentication', 'capabilityDelegation', 'assertionMethod', 'keyAgreement'] as const -export const keyRelationships = keyRelationshipsC as unknown as string[] -export type KeyRelationship = (typeof keyRelationshipsC)[number] - -export type DidUri = - | `did:kilt:${DidUriVersion}${KiltAddress}` - | `did:kilt:light:${DidUriVersion}${AuthenticationKeyType}${KiltAddress}${LightDidEncodedData}` - -/** - * The fragment part of the DID URI including the `#` character. - */ -export type UriFragment = `#${string}` -/** - * URI for DID resources like keys or service endpoints. - */ -export type DidResourceUri = `${DidUri}${UriFragment}` - -export type DidSignature = { - keyUri: DidResourceUri - signature: string -} - -/** - * The SDK-specific base details of a DID key. - */ -export type BaseDidKey = { - /** - * Relative key URI: `#` sign followed by fragment part of URI. - */ - id: UriFragment - /** - * The public key material. - */ - publicKey: Uint8Array - /** - * The inclusion block of the key, if stored on chain. - */ - includedAt?: BN - /** - * The type of the key. - */ - type: string -} - -/** - * Possible types for a DID encryption key. - */ -const encryptionKeyTypesC = ['x25519'] as const -export const encryptionKeyTypes = encryptionKeyTypesC as unknown as string[] -export type EncryptionKeyType = (typeof encryptionKeyTypesC)[number] - -/** - * Possible types for a DID verification key. - */ -const verificationKeyTypesC = ['sr25519', 'ed25519', 'ecdsa'] as const -export const verificationKeyTypes = verificationKeyTypesC as unknown as string[] -export type VerificationKeyType = (typeof verificationKeyTypesC)[number] - -/** - * The SDK-specific details of a DID verification key. - */ -export type DidVerificationKey = BaseDidKey & { type: VerificationKeyType } -/** - * The SDK-specific details of a DID encryption key. - */ -export type DidEncryptionKey = BaseDidKey & { type: EncryptionKeyType } -/** - * The SDK-specific details of a DID key. - */ -export type DidKey = DidVerificationKey | DidEncryptionKey - -/** - * The SDK-specific details of a new DID service endpoint. - */ -export type DidServiceEndpoint = { - /** - * Relative endpoint URI: `#` sign followed by fragment part of URI. - */ - id: UriFragment - /** - * A list of service types the endpoint exposes. - */ - type: string[] - /** - * A list of URIs the endpoint exposes its services at. - */ - serviceEndpoint: string[] -} - -export interface DidDocument { - uri: DidUri - - authentication: [DidVerificationKey] - assertionMethod?: [DidVerificationKey] - capabilityDelegation?: [DidVerificationKey] - keyAgreement?: DidEncryptionKey[] - - service?: DidServiceEndpoint[] -} - -export type BaseNewDidKey = { - publicKey: Uint8Array - type: string -} - - -export type NewDidVerificationKey = BaseNewDidKey & { - type: VerificationKeyType -} - -export type LightDidSupportedVerificationKeyType = Extract< - VerificationKeyType, - 'ed25519' | 'sr25519' -> - -export type NewLightDidVerificationKey = NewDidVerificationKey & { - type: LightDidSupportedVerificationKeyType -} diff --git a/src/types/DidDocumentExporter.ts b/src/types/DidDocumentExporter.ts deleted file mode 100644 index f3d1a78..0000000 --- a/src/types/DidDocumentExporter.ts +++ /dev/null @@ -1,95 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import { DidResourceUri, DidServiceEndpoint, DidUri, EncryptionKeyType, VerificationKeyType } from './DidDocument.js' -import { DidResolutionDocumentMetadata } from './DidResolver.js' - -export type ConformingDidDocumentKeyType = - | 'Ed25519VerificationKey2018' - | 'Sr25519VerificationKey2020' - | 'EcdsaSecp256k1VerificationKey2019' - | 'X25519KeyAgreementKey2019' - -export const verificationKeyTypesMap: Record = { - // proposed and used by dock.io, e.g. https://github.com/w3c-ccg/security-vocab/issues/32, https://github.com/docknetwork/sdk/blob/9c818b03bfb4fdf144c20678169c7aad3935ad96/src/utils/vc/contexts/security_context.js - sr25519: 'Sr25519VerificationKey2020', - // these are part of current w3 security vocab, see e.g. https://www.w3.org/ns/did/v1 - ed25519: 'Ed25519VerificationKey2018', - ecdsa: 'EcdsaSecp256k1VerificationKey2019', -} - -export const encryptionKeyTypesMap: Record = { - x25519: 'X25519KeyAgreementKey2019', -} - -/** - * A spec-compliant description of a DID key. - */ -export type ConformingDidKey = { - /** - * The full key URI, in the form of #. - */ - id: DidResourceUri - /** - * The key controller, in the form of . - */ - controller: DidUri - /** - * The base58-encoded public component of the key. - */ - publicKeyBase58: string - /** - * The key type signalling the intended signing/encryption algorithm for the use of this key. - */ - type: ConformingDidDocumentKeyType -} - -/** - * A spec-compliant description of a DID endpoint. - */ -export type ConformingDidServiceEndpoint = Omit & { - /** - * The full service URI, in the form of #. - */ - id: DidResourceUri -} - -/** - * A DID Document according to the [W3C DID Core specification](https://www.w3.org/TR/did-core/). - */ -export type ConformingDidDocument = { - id: DidUri - verificationMethod: ConformingDidKey[] - authentication: [ConformingDidKey['id']] - assertionMethod?: [ConformingDidKey['id']] - keyAgreement?: [ConformingDidKey['id']] - capabilityDelegation?: [ConformingDidKey['id']] - service?: ConformingDidServiceEndpoint[] - alsoKnownAs?: [`w3n:${string}`] -} - -/** - * A JSON+LD DID Document that extends a traditional DID Document with additional semantic information. - */ -export type JsonLDDidDocument = ConformingDidDocument & { '@context': string[] } - -/** - * DID Resolution Metadata returned by the DID `resolve` function as described by DID specifications (https://www.w3.org/TR/did-core/#did-resolution-metadata). - */ -export interface DidResolutionMetadata { - error?: 'notFound' | 'invalidDid' - errorMessage?: string -} - -/** - * Object containing the return values of the DID `resolve` function as described by DID specifications (https://www.w3.org/TR/did-core/#did-resolution). - */ -export interface ConformingDidResolutionResult { - didDocumentMetadata: Partial - didResolutionMetadata: DidResolutionMetadata - didDocument?: Partial & Pick -} diff --git a/src/types/DidResolver.ts b/src/types/DidResolver.ts deleted file mode 100644 index a5655ff..0000000 --- a/src/types/DidResolver.ts +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import { ConformingDidKey, ConformingDidServiceEndpoint } from './DidDocumentExporter.js' -import type { DidDocument, DidKey, DidResourceUri, DidUri, KeyRelationship } from './DidDocument.js' - -/** - * DID resolution metadata that includes a subset of the properties defined in the [W3C proposed standard](https://www.w3.org/TR/did-core/#did-resolution). - */ -export type DidResolutionDocumentMetadata = { - /** - * If present, it indicates that the resolved by DID should be treated as if it were the DID as specified in this property. - */ - canonicalId?: DidUri - /** - * A boolean flag indicating whether the resolved DID has been deactivated. - */ - deactivated: boolean -} - -/** - * The result of a DID resolution. - * - * It includes the DID Document, and optional document resolution metadata. - */ -export type DidResolutionResult = { - /** - * The resolved DID document. It is undefined if the DID has been upgraded or deleted. - */ - document?: DidDocument - /** - * The DID resolution metadata. - */ - metadata: DidResolutionDocumentMetadata - /** - * The DID's web3Name, if any. - */ - web3Name?: string -} - -export type ResolvedDidKey = Pick & - Pick - -export type ResolvedDidServiceEndpoint = ConformingDidServiceEndpoint - -/** - * Resolves a DID URI, returning the full contents of the DID document. - * - * @param did A DID URI identifying a DID document. All additional parameters and fragments are ignored. - * @returns A promise of a [[DidResolutionResult]] object representing the DID document or null if the DID - * cannot be resolved. - */ -export type DidResolve = (did: DidUri) => Promise - -/** - * Resolves a DID URI identifying a public key associated with a DID. - * - * @param didUri A DID URI identifying a public key associated with a DID through the DID document. - * @returns A promise of a [[ResolvedDidKey]] object representing the DID public key or null if - * the DID or key URI cannot be resolved. - */ -export type DidResolveKey = ( - didUri: DidResourceUri, - expectedVerificationMethod?: KeyRelationship -) => Promise diff --git a/src/types/Message.ts b/src/types/Message.ts index 7141ac2..02a524d 100644 --- a/src/types/Message.ts +++ b/src/types/Message.ts @@ -1,11 +1,7 @@ import type { ITerms } from './Terms' -import type { ICredential, ICredentialPresentation } from './Credential' +import type { ICredential, ICredentialPresentation, IAttestation, CTypeHash, DidResourceUri, DidUri, IDelegationNode,PartialClaim } from '@kiltprotocol/types' import type { IQuoteAgreement } from './Quote' -import type { IAttestation } from './Attestation' -import type { CTypeHash } from './CType' -import type { DidResourceUri, DidUri } from './DidDocument' -import type { IDelegationNode } from './Delegation' -import { PartialClaim } from './Claim' + export interface IDelegationData { account: IDelegationNode['account'] diff --git a/src/types/index.ts b/src/types/index.ts index 4229248..85c5271 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -2,19 +2,11 @@ import type { IEncryptedMessage, DidUri, KiltAddress, DidResourceUri } from '@ki import type { HexString } from '@polkadot/util/types' import type { CredentialDigestProof, SelfSignedProof, VerifiableCredential, constants } from '@kiltprotocol/vc-export' -export * from './Attestation.js' -export * from './CType.js' -export * from './Claim.js' -export * from './Delegation.js' -export * from './Address.js' export * from './Message.js' export * from './Quote.js' -export * from './Credential.js' export * from './Terms.js' -export * from './DidDocument.js' export * from './Imported.js' -export * from './CryptoCallbacks.js' -export * from './DidResolver.js' + export type This = typeof globalThis export interface IEncryptedMessageV1 { From 0ce054af36ecab3b12b03baebca07b6dd75988f6 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Tue, 8 Aug 2023 09:51:10 +0200 Subject: [PATCH 09/39] refactor: remove jest setup --- jest.config.js | 1 - src/messaging/Message.test.ts | 6 ++++++ src/tests/jest.setup.ts | 5 ----- 3 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 src/tests/jest.setup.ts diff --git a/jest.config.js b/jest.config.js index 43d4510..4f4865e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,7 +1,6 @@ module.exports = { preset: 'ts-jest', testEnvironment: 'node', - setupFilesAfterEnv: ['/tests/jest.setup.ts'], clearMocks: true, // Parachain block time is 12s testTimeout: 12000, diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index 8238043..c49a586 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -10,6 +10,7 @@ import { u8aToHex } from '@polkadot/util' import { Attestation, CType, Claim, Credential, Quote } from '@kiltprotocol/core' import * as Did from '@kiltprotocol/did' +import { init } from '@kiltprotocol/sdk-js' import { Crypto, SDKErrors } from '@kiltprotocol/utils' import { @@ -89,6 +90,7 @@ describe('Messaging', () => { } beforeAll(async () => { + await init() const aliceAuthKey = makeSigningKeyTool('ed25519') aliceSign = aliceAuthKey.getSignCallback aliceLightDid = Did.createLightDidDocument({ @@ -115,6 +117,7 @@ describe('Messaging', () => { }) bobFullDid = await createLocalDemoFullDidFromLightDid(bobLightDid) }) + it('verify message encryption and signing', async () => { const message = Message.fromBody( { @@ -556,6 +559,9 @@ describe('Error checking / Verification', () => { let messageSubmitCredential: IMessage beforeAll(async () => { + + await init() + keyAlice = makeSigningKeyTool() identityAlice = await createLocalDemoFullDidFromKeypair(keyAlice.keypair) keyBob = makeSigningKeyTool() diff --git a/src/tests/jest.setup.ts b/src/tests/jest.setup.ts deleted file mode 100644 index 51e36b5..0000000 --- a/src/tests/jest.setup.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { cryptoWaitReady } from '@polkadot/util-crypto' - -beforeAll(async () => { - await cryptoWaitReady() -}) From 844cdbf966e3e02c4d0c0bc7c39bf379d03c8e44 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 09:49:21 +0200 Subject: [PATCH 10/39] refactor: restructure --- src/messaging/CredentialApiMessageTypes.ts | 133 ++++++++ src/messaging/Message.test.ts | 249 +++++---------- src/messaging/MessageEnvelope.ts | 159 ++++++++++ src/messaging/index.ts | 341 +-------------------- src/messaging/utils.ts | 39 +++ src/quote/Quote.test.ts | 2 +- 6 files changed, 416 insertions(+), 507 deletions(-) create mode 100644 src/messaging/CredentialApiMessageTypes.ts create mode 100644 src/messaging/MessageEnvelope.ts create mode 100644 src/messaging/utils.ts diff --git a/src/messaging/CredentialApiMessageTypes.ts b/src/messaging/CredentialApiMessageTypes.ts new file mode 100644 index 0000000..a9a435e --- /dev/null +++ b/src/messaging/CredentialApiMessageTypes.ts @@ -0,0 +1,133 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import { Attestation, Claim, Credential, CType, Quote } from '@kiltprotocol/core' +import { DataUtils, SDKErrors } from '@kiltprotocol/utils' +import * as Did from '@kiltprotocol/did' +import { isHex } from '@polkadot/util' + +import {verifyMessageEnvelope} from './MessageEnvelope' +import type { + IMessage, + MessageBody, +} from '../types' + +/** + * Checks if the message body is well-formed. + * + * @param body The message body. + */ +export function verifyMessageBody(body: MessageBody): void { + switch (body.type) { + case 'submit-terms': { + Claim.verifyDataStructure(body.content.claim) + body.content.legitimations.forEach((credential) => Credential.verifyDataStructure(credential)) + if (body.content.delegationId) { + DataUtils.verifyIsHex(body.content.delegationId) + } + if (body.content.quote) { + Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) + } + if (body.content.cTypes) { + body.content.cTypes.forEach((val) => CType.verifyDataStructure(val)) + } + break + } + case 'request-attestation': { + Credential.verifyDataStructure(body.content.credential) + if (body.content.quote) { + Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) + } + break + } + case 'submit-attestation': { + Attestation.verifyDataStructure(body.content.attestation) + break + } + case 'reject-attestation': { + if (!isHex(body.content)) { + throw new SDKErrors.HashMalformedError() + } + break + } + case 'request-credential': { + body.content.cTypes.forEach(({ cTypeHash, trustedAttesters, requiredProperties }): void => { + DataUtils.verifyIsHex(cTypeHash) + trustedAttesters?.forEach((did) => Did.validateUri(did, 'Did')) + requiredProperties?.forEach((requiredProps) => { + if (typeof requiredProps !== 'string') throw new TypeError('Required properties is expected to be a string') + }) + }) + break + } + case 'submit-credential': { + body.content.forEach((presentation) => { + Credential.verifyDataStructure(presentation) + if (!Did.isDidSignature(presentation.claimerSignature)) { + throw new SDKErrors.SignatureMalformedError() + } + }) + break + } + + default: + throw new SDKErrors.UnknownMessageBodyTypeError() + } +} + +/** + * Verifies that the sender of a [[Message]] is also the owner of it, e.g the owner's and sender's DIDs refer to the same subject. + * + * @param message The [[Message]] object which needs to be decrypted. + * @param message.body The body of the [[Message]] which depends on the [[BodyType]]. + * @param message.sender The sender's DID taken from the [[IMessage]]. + */ +export function ensureOwnerIsSender({ body, sender }: IMessage): void { + switch (body.type) { + case 'request-attestation': + { + const requestAttestation = body + if (!Did.isSameSubject(requestAttestation.content.credential.claim.owner, sender)) { + throw new SDKErrors.IdentityMismatchError('Claim', 'Sender') + } + } + break + case 'submit-attestation': + { + const submitAttestation = body + if (!Did.isSameSubject(submitAttestation.content.attestation.owner, sender)) { + throw new SDKErrors.IdentityMismatchError('Attestation', 'Sender') + } + } + break + case 'submit-credential': + { + const submitClaimsForCtype = body + submitClaimsForCtype.content.forEach((presentation) => { + if (!Did.isSameSubject(presentation.claim.owner, sender)) { + throw new SDKErrors.IdentityMismatchError('Claims', 'Sender') + } + }) + } + break + default: + } +} + +/** + * Checks the message structure and body contents (e.g. Hashes match, ensures the owner is the sender). + * Throws, if a check fails. + * + * @param decryptedMessage The decrypted message to check. + */ +export function verify(decryptedMessage: IMessage): void { + verifyMessageBody(decryptedMessage.body) + verifyMessageEnvelope(decryptedMessage) + ensureOwnerIsSender(decryptedMessage) +} + + diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index c49a586..ef7e2d8 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -12,17 +12,6 @@ import { Attestation, CType, Claim, Credential, Quote } from '@kiltprotocol/core import * as Did from '@kiltprotocol/did' import { init } from '@kiltprotocol/sdk-js' import { Crypto, SDKErrors } from '@kiltprotocol/utils' - -import { - KeyTool, - KeyToolSignCallback, - createLocalDemoFullDidFromKeypair, - createLocalDemoFullDidFromLightDid, - makeEncryptionKeyTool, - makeSigningKeyTool, -} from '../tests' -import * as Message from './index' - import type { DidDocument, DidKey, DidResourceUri, @@ -34,6 +23,18 @@ import type { DidDocument, ICredential, ICredentialPresentation } from '@kiltprotocol/sdk-js' + +import { + KeyTool, + KeyToolSignCallback, + createLocalDemoFullDidFromKeypair, + createLocalDemoFullDidFromLightDid, + makeEncryptionKeyTool, + makeSigningKeyTool, +} from '../tests' +import { fromBody, verifyRequiredCTypeProperties } from './utils' +import { decrypt, encrypt, verifyMessageEnvelope } from './MessageEnvelope' +import { ensureOwnerIsSender, verify, verifyMessageBody } from './CredentialApiMessageTypes' import type { IEncryptedMessage, IMessage, @@ -52,12 +53,6 @@ import type { ITerms, MessageBody, } from '../types' -import type { - ISubmitDelegationApproval, - IRequestDelegationApproval, - ISubmitAcceptDelegation, - IRequestAcceptDelegation, -} from '@kiltprotocol/types' @@ -119,7 +114,7 @@ describe('Messaging', () => { }) it('verify message encryption and signing', async () => { - const message = Message.fromBody( + const message = fromBody( { type: 'request-credential', content: { @@ -129,17 +124,17 @@ describe('Messaging', () => { aliceLightDid.uri, bobLightDid.uri ) - const encryptedMessage = await Message.encrypt( + const encryptedMessage = await encrypt( message, aliceEncKey.encrypt(aliceLightDid), `${bobLightDid.uri}#encryption`, { resolveKey } ) - const decryptedMessage = await Message.decrypt(encryptedMessage, bobEncKey.decrypt, { resolveKey }) + const decryptedMessage = await decrypt(encryptedMessage, bobEncKey.decrypt, { resolveKey }) expect(JSON.stringify(message.body)).toEqual(JSON.stringify(decryptedMessage.body)) - expect(() => Message.verify(decryptedMessage)).not.toThrow() + expect(() => verify(decryptedMessage)).not.toThrow() const encryptedMessageWrongContent = JSON.parse(JSON.stringify(encryptedMessage)) as IEncryptedMessage const messedUpContent = Crypto.coToUInt8(encryptedMessageWrongContent.ciphertext) @@ -147,7 +142,7 @@ describe('Messaging', () => { encryptedMessageWrongContent.ciphertext = u8aToHex(messedUpContent) await expect(() => - Message.decrypt(encryptedMessageWrongContent, bobEncKey.decrypt, { + decrypt(encryptedMessageWrongContent, bobEncKey.decrypt, { resolveKey, }) ).rejects.toThrowError(SDKErrors.DecodingMessageError) @@ -167,7 +162,7 @@ describe('Messaging', () => { receiverKeyUri: `${bobLightDid.uri}${bobLightDid.keyAgreement![0].id}`, } await expect(() => - Message.decrypt(encryptedMessageWrongBody, bobEncKey.decrypt, { + decrypt(encryptedMessageWrongBody, bobEncKey.decrypt, { resolveKey, }) ).rejects.toThrowError(SyntaxError) @@ -217,18 +212,18 @@ describe('Messaging', () => { // Should not throw if the owner and sender DID is the same. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, aliceFullDid.uri, bobFullDid.uri)) + ensureOwnerIsSender(fromBody(requestAttestationBody, aliceFullDid.uri, bobFullDid.uri)) ).not.toThrow() // Should not throw if the sender is the light DID version of the owner. // This is technically not to be allowed but message verification is not concerned with that. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, aliceLightDid.uri, bobFullDid.uri)) + ensureOwnerIsSender(fromBody(requestAttestationBody, aliceLightDid.uri, bobFullDid.uri)) ).not.toThrow() // Should throw if the sender and the owner are two different entities. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, bobFullDid.uri, aliceFullDid.uri)) + ensureOwnerIsSender(fromBody(requestAttestationBody, bobFullDid.uri, aliceFullDid.uri)) ).toThrowError(SDKErrors.IdentityMismatchError) const attestation = { @@ -248,18 +243,18 @@ describe('Messaging', () => { // Should not throw if the owner and sender DID is the same. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, bobFullDid.uri, aliceFullDid.uri)) + ensureOwnerIsSender(fromBody(submitAttestationBody, bobFullDid.uri, aliceFullDid.uri)) ).not.toThrow() // Should not throw if the sender is the light DID version of the owner. // This is technically not to be allowed but message verification is not concerned with that. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, bobLightDid.uri, aliceFullDid.uri)) + ensureOwnerIsSender(fromBody(submitAttestationBody, bobLightDid.uri, aliceFullDid.uri)) ).not.toThrow() // Should throw if the sender and the owner are two different entities. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, aliceFullDid.uri, bobFullDid.uri)) + ensureOwnerIsSender(fromBody(submitAttestationBody, aliceFullDid.uri, bobFullDid.uri)) ).toThrowError(SDKErrors.IdentityMismatchError) const submitClaimsForCTypeBody: ISubmitCredential = { @@ -269,18 +264,18 @@ describe('Messaging', () => { // Should not throw if the owner and sender DID is the same. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, aliceFullDid.uri, bobFullDid.uri)) + ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, aliceFullDid.uri, bobFullDid.uri)) ).not.toThrow() // Should not throw if the sender is the light DID version of the owner. // This is technically not to be allowed but message verification is not concerned with that. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, aliceLightDid.uri, bobFullDid.uri)) + ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, aliceLightDid.uri, bobFullDid.uri)) ).not.toThrow() // Should throw if the sender and the owner are two different entities. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, bobFullDid.uri, aliceFullDid.uri)) + ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, bobFullDid.uri, aliceFullDid.uri)) ).toThrowError(SDKErrors.IdentityMismatchError) }) @@ -369,31 +364,31 @@ describe('Messaging', () => { // Should not throw if the owner and sender DID is the same. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, aliceLightDid.uri, bobLightDid.uri)) + ensureOwnerIsSender(fromBody(requestAttestationBody, aliceLightDid.uri, bobLightDid.uri)) ).not.toThrow() // Should not throw if the owner has no additional details and the sender does. expect(() => - Message.ensureOwnerIsSender( - Message.fromBody(requestAttestationBodyWithEncodedDetails, aliceLightDidWithDetails.uri, bobLightDid.uri) + ensureOwnerIsSender( + fromBody(requestAttestationBodyWithEncodedDetails, aliceLightDidWithDetails.uri, bobLightDid.uri) ) ).not.toThrow() // Should not throw if the owner has additional details and the sender does not. expect(() => - Message.ensureOwnerIsSender( - Message.fromBody(requestAttestationBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri) + ensureOwnerIsSender( + fromBody(requestAttestationBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri) ) ).not.toThrow() // Should not throw if the sender is the full DID version of the owner. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, aliceFullDid.uri, bobLightDid.uri)) + ensureOwnerIsSender(fromBody(requestAttestationBody, aliceFullDid.uri, bobLightDid.uri)) ).not.toThrow() // Should throw if the sender and the owner are two different entities. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(requestAttestationBody, bobLightDid.uri, aliceLightDid.uri)) + ensureOwnerIsSender(fromBody(requestAttestationBody, bobLightDid.uri, aliceLightDid.uri)) ).toThrowError(SDKErrors.IdentityMismatchError) const attestation = { @@ -428,31 +423,31 @@ describe('Messaging', () => { // Should not throw if the owner and sender DID is the same. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, bobLightDid.uri, aliceLightDid.uri)) + ensureOwnerIsSender(fromBody(submitAttestationBody, bobLightDid.uri, aliceLightDid.uri)) ).not.toThrow() // Should not throw if the owner has no additional details and the sender does. expect(() => - Message.ensureOwnerIsSender( - Message.fromBody(submitAttestationBody, bobLightDidWithDetails.uri, aliceLightDid.uri) + ensureOwnerIsSender( + fromBody(submitAttestationBody, bobLightDidWithDetails.uri, aliceLightDid.uri) ) ).not.toThrow() // Should not throw if the owner has additional details and the sender does not. expect(() => - Message.ensureOwnerIsSender( - Message.fromBody(submitAttestationBodyWithEncodedDetails, bobLightDid.uri, aliceLightDid.uri) + ensureOwnerIsSender( + fromBody(submitAttestationBodyWithEncodedDetails, bobLightDid.uri, aliceLightDid.uri) ) ).not.toThrow() // Should not throw if the sender is the full DID version of the owner. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, bobFullDid.uri, aliceLightDid.uri)) + ensureOwnerIsSender(fromBody(submitAttestationBody, bobFullDid.uri, aliceLightDid.uri)) ).not.toThrow() // Should throw if the sender and the owner are two different entities. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitAttestationBody, aliceLightDid.uri, bobLightDid.uri)) + ensureOwnerIsSender(fromBody(submitAttestationBody, aliceLightDid.uri, bobLightDid.uri)) ).toThrowError(SDKErrors.IdentityMismatchError) const submitClaimsForCTypeBody: ISubmitCredential = { @@ -467,31 +462,31 @@ describe('Messaging', () => { // Should not throw if the owner and sender DID is the same. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, aliceLightDid.uri, bobLightDid.uri)) + ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, aliceLightDid.uri, bobLightDid.uri)) ).not.toThrow() // Should not throw if the owner has no additional details and the sender does. expect(() => - Message.ensureOwnerIsSender( - Message.fromBody(submitClaimsForCTypeBody, aliceLightDidWithDetails.uri, bobLightDid.uri) + ensureOwnerIsSender( + fromBody(submitClaimsForCTypeBody, aliceLightDidWithDetails.uri, bobLightDid.uri) ) ).not.toThrow() // Should not throw if the owner has additional details and the sender does not. expect(() => - Message.ensureOwnerIsSender( - Message.fromBody(submitClaimsForCTypeBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri) + ensureOwnerIsSender( + fromBody(submitClaimsForCTypeBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri) ) ).not.toThrow() // Should not throw if the sender is the full DID version of the owner. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, aliceFullDid.uri, bobLightDid.uri)) + ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, aliceFullDid.uri, bobLightDid.uri)) ).not.toThrow() // Should throw if the sender and the owner are two different entities. expect(() => - Message.ensureOwnerIsSender(Message.fromBody(submitClaimsForCTypeBody, bobLightDid.uri, aliceLightDid.uri)) + ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, bobLightDid.uri, aliceLightDid.uri)) ).toThrowError(SDKErrors.IdentityMismatchError) }) }) @@ -546,10 +541,6 @@ describe('Error checking / Verification', () => { let requestCredentialContent: IRequestCredentialContent let submitCredentialBody: ISubmitCredential let submitCredentialContent: ICredentialPresentation[] - let requestAcceptDelegationBody: IRequestAcceptDelegation - let requestAcceptDelegationContent: IRequestDelegationApproval - let submitAcceptDelegationBody: ISubmitAcceptDelegation - let submitAcceptDelegationContent: ISubmitDelegationApproval let messageSubmitTerms: IMessage let messageRequestAttestationForClaim: IMessage @@ -668,55 +659,6 @@ describe('Error checking / Verification', () => { }, }, ] - // Request Accept delegation content - requestAcceptDelegationContent = { - delegationData: { - account: identityAlice.uri, - id: Crypto.hashStr('0x12345678'), - parentId: Crypto.hashStr('0x12345678'), - permissions: [1], - isPCR: false, - }, - metaData: {}, - signatures: { - inviter: Did.signatureToJson( - await keyAlice.getSignCallback(identityAlice)({ - data: Crypto.coToUInt8('signature'), - did: identityAlice.uri, - keyRelationship: 'authentication', - }) - ), - }, - } - // Submit Accept delegation content - submitAcceptDelegationContent = { - delegationData: { - account: identityAlice.uri, - id: Crypto.hashStr('0x12345678'), - parentId: Crypto.hashStr('0x12345678'), - permissions: [1], - isPCR: false, - }, - signatures: { - inviter: Did.signatureToJson( - await keyAlice.getSignCallback(identityAlice)({ - data: Crypto.coToUInt8('signature'), - did: identityAlice.uri, - keyRelationship: 'authentication', - }) - ), - invitee: Did.signatureToJson( - await keyBob.getSignCallback(identityBob)({ - data: Crypto.coToUInt8('signature'), - did: identityBob.uri, - keyRelationship: 'authentication', - }) - ), - }, - } - - - submitTermsBody = { content: submitTermsContent, @@ -747,131 +689,102 @@ describe('Error checking / Verification', () => { type: 'submit-credential', } - requestAcceptDelegationBody = { - content: requestAcceptDelegationContent, - type: 'request-accept-delegation', - } - - submitAcceptDelegationBody = { - content: submitAcceptDelegationContent, - type: 'submit-accept-delegation', - } - }) it('Checking required properties for given CType', () => { - expect(() => Message.verifyRequiredCTypeProperties(['id', 'name'], testCType)).toThrowError( + expect(() => verifyRequiredCTypeProperties(['id', 'name'], testCType)).toThrowError( SDKErrors.CTypeUnknownPropertiesError ) expect(() => - Message.verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties) + verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties) ).not.toThrowError(SDKErrors.CTypeUnknownPropertiesError) expect(() => - Message.verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties) + verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties) ).not.toThrowError() }) beforeAll(async () => { - messageSubmitTerms = Message.fromBody(submitTermsBody, identityAlice.uri, identityBob.uri) + messageSubmitTerms = fromBody(submitTermsBody, identityAlice.uri, identityBob.uri) - messageRequestAttestationForClaim = Message.fromBody(requestAttestationBody, identityAlice.uri, identityBob.uri) - messageSubmitAttestationForClaim = Message.fromBody(submitAttestationBody, identityAlice.uri, identityBob.uri) + messageRequestAttestationForClaim = fromBody(requestAttestationBody, identityAlice.uri, identityBob.uri) + messageSubmitAttestationForClaim = fromBody(submitAttestationBody, identityAlice.uri, identityBob.uri) - messageRejectAttestationForClaim = Message.fromBody( + messageRejectAttestationForClaim = fromBody( rejectAttestationForClaimBody, identityAlice.uri, identityBob.uri ) - messageRequestCredential = Message.fromBody(requestCredentialBody, identityAlice.uri, identityBob.uri) - messageSubmitCredential = Message.fromBody(submitCredentialBody, identityAlice.uri, identityBob.uri) + messageRequestCredential = fromBody(requestCredentialBody, identityAlice.uri, identityBob.uri) + messageSubmitCredential = fromBody(submitCredentialBody, identityAlice.uri, identityBob.uri) }) it('message body verifier should not throw errors on correct bodies', () => { - expect(() => Message.verifyMessageBody(submitTermsBody)).not.toThrowError() + expect(() => verifyMessageBody(submitTermsBody)).not.toThrowError() - expect(() => Message.verifyMessageBody(requestAttestationBody)).not.toThrowError() - expect(() => Message.verifyMessageBody(submitAttestationBody)).not.toThrowError() - expect(() => Message.verifyMessageBody(rejectAttestationForClaimBody)).not.toThrowError() - expect(() => Message.verifyMessageBody(requestCredentialBody)).not.toThrowError() - expect(() => Message.verifyMessageBody(submitCredentialBody)).not.toThrowError() + expect(() => verifyMessageBody(requestAttestationBody)).not.toThrowError() + expect(() => verifyMessageBody(submitAttestationBody)).not.toThrowError() + expect(() => verifyMessageBody(rejectAttestationForClaimBody)).not.toThrowError() + expect(() => verifyMessageBody(requestCredentialBody)).not.toThrowError() + expect(() => verifyMessageBody(submitCredentialBody)).not.toThrowError() }) it('message envelope verifier should not throw errors on correct envelopes', () => { - expect(() => Message.verifyMessageEnvelope(messageSubmitTerms)).not.toThrowError() - expect(() => Message.verifyMessageEnvelope(messageRequestAttestationForClaim)).not.toThrowError() - expect(() => Message.verifyMessageEnvelope(messageSubmitAttestationForClaim)).not.toThrowError() - expect(() => Message.verifyMessageEnvelope(messageRejectAttestationForClaim)).not.toThrowError() - expect(() => Message.verifyMessageEnvelope(messageRequestCredential)).not.toThrowError() - expect(() => Message.verifyMessageEnvelope(messageSubmitCredential)).not.toThrowError() + expect(() => verifyMessageEnvelope(messageSubmitTerms)).not.toThrowError() + expect(() => verifyMessageEnvelope(messageRequestAttestationForClaim)).not.toThrowError() + expect(() => verifyMessageEnvelope(messageSubmitAttestationForClaim)).not.toThrowError() + expect(() => verifyMessageEnvelope(messageRejectAttestationForClaim)).not.toThrowError() + expect(() => verifyMessageEnvelope(messageRequestCredential)).not.toThrowError() + expect(() => verifyMessageEnvelope(messageSubmitCredential)).not.toThrowError() }) it('message envelope verifier should throw errors on faulty envelopes', () => { // @ts-ignore messageSubmitTerms.sender = 'this is not a sender did' - expect(() => Message.verifyMessageEnvelope(messageSubmitTerms)).toThrowError(SDKErrors.InvalidDidFormatError) + expect(() => verifyMessageEnvelope(messageSubmitTerms)).toThrowError(SDKErrors.InvalidDidFormatError) // @ts-ignore messageRequestAttestationForClaim.messageId = 12 - expect(() => Message.verifyMessageEnvelope(messageRequestAttestationForClaim)).toThrowError(TypeError) + expect(() => verifyMessageEnvelope(messageRequestAttestationForClaim)).toThrowError(TypeError) // @ts-ignore messageSubmitAttestationForClaim.createdAt = '123456' - expect(() => Message.verifyMessageEnvelope(messageSubmitAttestationForClaim)).toThrowError(TypeError) + expect(() => verifyMessageEnvelope(messageSubmitAttestationForClaim)).toThrowError(TypeError) // @ts-ignore messageRejectAttestationForClaim.receivedAt = '123456' - expect(() => Message.verifyMessageEnvelope(messageRejectAttestationForClaim)).toThrowError(TypeError) + expect(() => verifyMessageEnvelope(messageRejectAttestationForClaim)).toThrowError(TypeError) // @ts-ignore messageRequestCredential.inReplyTo = 123 - expect(() => Message.verifyMessageEnvelope(messageRequestCredential)).toThrowError(TypeError) + expect(() => verifyMessageEnvelope(messageRequestCredential)).toThrowError(TypeError) }) it('message body verifier should throw errors on faulty bodies', () => { submitTermsBody.content.delegationId = 'this is not a delegation id' - expect(() => Message.verifyMessageBody(submitTermsBody)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(submitTermsBody)).toThrowError(SDKErrors.HashMalformedError) submitCredentialBody.content[0].claimerSignature = { signature: 'this is not the claimers signature', // @ts-ignore keyUri: 'this is not a key id', } - expect(() => Message.verifyMessageBody(submitCredentialBody)).toThrowError() + expect(() => verifyMessageBody(submitCredentialBody)).toThrowError() // @ts-ignore submitAttestationBody.content.attestation.claimHash = 'this is not the claim hash' - expect(() => Message.verifyMessageBody(submitAttestationBody)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(submitAttestationBody)).toThrowError(SDKErrors.HashMalformedError) // @ts-ignore rejectAttestationForClaimBody.content = 'this is not the root hash' - expect(() => Message.verifyMessageBody(rejectAttestationForClaimBody)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(rejectAttestationForClaimBody)).toThrowError(SDKErrors.HashMalformedError) // @ts-ignore requestCredentialBody.content.cTypes[0].cTypeHash = 'this is not a cTypeHash' - expect(() => Message.verifyMessageBody(requestCredentialBody)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(requestCredentialBody)).toThrowError(SDKErrors.HashMalformedError) - expect(() => Message.verifyMessageBody({} as MessageBody)).toThrowError(SDKErrors.UnknownMessageBodyTypeError) - }) - it('delegation data structure verifier should throw on faulty delegation data', () => { - // @ts-expect-error - delete requestAcceptDelegationBody.content.delegationData.isPCR - expect(() => Message.verifyDelegationStructure(requestAcceptDelegationBody.content.delegationData)).toThrowError( - TypeError('isPCR is expected to be a boolean') - ) - requestAcceptDelegationBody.content.delegationData.id = 'this is not a delegation id' - expect(() => Message.verifyDelegationStructure(requestAcceptDelegationBody.content.delegationData)).toThrowError( - SDKErrors.DelegationIdTypeError - ) - submitAcceptDelegationBody.content.delegationData.permissions = [] - expect(() => Message.verifyDelegationStructure(submitAcceptDelegationBody.content.delegationData)).toThrowError( - SDKErrors.UnauthorizedError - ) - // @ts-expect-error - delete submitAcceptDelegationBody.content.delegationData.id - expect(() => Message.verifyDelegationStructure(submitAcceptDelegationBody.content.delegationData)).toThrowError( - SDKErrors.DelegationIdMissingError - ) + expect(() => verifyMessageBody({} as MessageBody)).toThrowError(SDKErrors.UnknownMessageBodyTypeError) }) + }) diff --git a/src/messaging/MessageEnvelope.ts b/src/messaging/MessageEnvelope.ts new file mode 100644 index 0000000..67ed361 --- /dev/null +++ b/src/messaging/MessageEnvelope.ts @@ -0,0 +1,159 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +import { DecryptCallback, DidResolveKey, DidResourceUri, EncryptCallback } from '@kiltprotocol/types' +import * as Did from '@kiltprotocol/did' +import { SDKErrors } from '@kiltprotocol/sdk-js' +import { hexToU8a, stringToU8a, u8aToHex, u8aToString } from '@polkadot/util' + +import type { IEncryptedMessage, IEncryptedMessageContents, IMessage } from '../types' + +/** + * Checks if the message object is well-formed. + * + * @param message The message object. + */ +export function verifyMessageEnvelope(message: IMessage): void { + const { messageId, createdAt, receiver, sender, receivedAt, inReplyTo } = message + if (messageId !== undefined && typeof messageId !== 'string') { + throw new TypeError('Message id is expected to be a string') + } + if (createdAt !== undefined && typeof createdAt !== 'number') { + throw new TypeError('Created at is expected to be a number') + } + if (receivedAt !== undefined && typeof receivedAt !== 'number') { + throw new TypeError('Received at is expected to be a number') + } + Did.validateUri(sender, 'Did') + Did.validateUri(receiver, 'Did') + if (inReplyTo && typeof inReplyTo !== 'string') { + throw new TypeError('In reply to is expected to be a string') + } +} + + +/** + * Symmetrically decrypts the result of [[encrypt]]. + * + * @param encrypted The encrypted message. + * @param decryptCallback The callback to decrypt with the secret key. + * @param decryptionOptions Options to perform the decryption operation. + * @param decryptionOptions.resolveKey The DID key resolver to use. + * @returns The original [[Message]]. + */ +export async function decrypt( + encrypted: IEncryptedMessage, + decryptCallback: DecryptCallback, + { + resolveKey = Did.resolveKey, + }: { + resolveKey?: DidResolveKey + } = {} +): Promise { + const { senderKeyUri, receiverKeyUri, ciphertext, nonce, receivedAt } = encrypted + + const senderKeyDetails = await resolveKey(senderKeyUri, 'keyAgreement') + + const { fragment } = Did.parse(receiverKeyUri) + if (!fragment) { + throw new SDKErrors.DidError(`No fragment for the receiver key ID "${receiverKeyUri}"`) + } + + let data: Uint8Array + try { + data = ( + await decryptCallback({ + peerPublicKey: senderKeyDetails.publicKey, + data: hexToU8a(ciphertext), + nonce: hexToU8a(nonce), + keyUri: receiverKeyUri, + }) + ).data + } catch (cause) { + throw new SDKErrors.DecodingMessageError(undefined, { + cause: cause as Error, + }) + } + + const decoded = u8aToString(data) + + const { body, createdAt, messageId, inReplyTo, references, sender, receiver } = JSON.parse( + decoded + ) as IEncryptedMessageContents + const decrypted: IMessage = { + receiver, + sender, + createdAt, + body, + messageId, + receivedAt, + inReplyTo, + references, + } + + if (sender !== senderKeyDetails.controller) { + throw new SDKErrors.IdentityMismatchError('Encryption key', 'Sender') + } + + return decrypted +} + +/** + * Encrypts the [[Message]] as a string. This can be reversed with [[decrypt]]. + * + * @param message The message to encrypt. + * @param encryptCallback The callback to encrypt with the secret key. + * @param receiverKeyUri The key URI of the receiver. + * @param encryptionOptions Options to perform the encryption operation. + * @param encryptionOptions.resolveKey The DID key resolver to use. + * + * @returns The encrypted version of the original [[Message]], see [[IEncryptedMessage]]. + */ +export async function encrypt( + message: IMessage, + encryptCallback: EncryptCallback, + receiverKeyUri: DidResourceUri, + { + resolveKey = Did.resolveKey, + }: { + resolveKey?: DidResolveKey + } = {} +): Promise { + const receiverKey = await resolveKey(receiverKeyUri, 'keyAgreement') + if (message.receiver !== receiverKey.controller) { + throw new SDKErrors.IdentityMismatchError('receiver public key', 'receiver') + } + + const toEncrypt: IEncryptedMessageContents = { + body: message.body, + createdAt: message.createdAt, + sender: message.sender, + receiver: message.receiver, + messageId: message.messageId, + inReplyTo: message.inReplyTo, + references: message.references, + } + + const serialized = stringToU8a(JSON.stringify(toEncrypt)) + + const encrypted = await encryptCallback({ + did: message.sender, + data: serialized, + peerPublicKey: receiverKey.publicKey, + }) + + const ciphertext = u8aToHex(encrypted.data) + const nonce = u8aToHex(encrypted.nonce) + + return { + receivedAt: message.receivedAt, + ciphertext, + nonce, + senderKeyUri: encrypted.keyUri, + receiverKeyUri: receiverKey.id, + } +} diff --git a/src/messaging/index.ts b/src/messaging/index.ts index d8bbece..cc19efe 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -23,341 +23,6 @@ * found in the LICENSE file in the root directory of this source tree. */ -import type { - IEncryptedMessage, - IEncryptedMessageContents, - IDelegationData, - IMessage, - MessageBody, -} from '../types' - -import type { ICType, EncryptCallback, DidResourceUri, DidResolveKey, DecryptCallback } from '@kiltprotocol/types' -import { Attestation, Claim, Credential, CType, Quote } from '@kiltprotocol/core' -import { DataUtils, SDKErrors, UUID } from '@kiltprotocol/utils' -import * as Did from '@kiltprotocol/did' -import { hexToU8a, stringToU8a, u8aToHex, u8aToString, isHex } from '@polkadot/util' - -/** - * Checks if delegation data is well formed. - * - * @param delegationData Delegation data to check. - */ -export function verifyDelegationStructure(delegationData: IDelegationData): void { - const { permissions, id, parentId, isPCR, account } = delegationData - - if (!id) { - throw new SDKErrors.DelegationIdMissingError() - } else if (typeof id !== 'string' || !isHex(id)) { - throw new SDKErrors.DelegationIdTypeError() - } - - if (!account) { - throw new SDKErrors.OwnerMissingError() - } - Did.validateUri(account, 'Did') - - if (typeof isPCR !== 'boolean') { - throw new TypeError('isPCR is expected to be a boolean') - } - - if (permissions.length === 0 || permissions.length > 3) { - throw new SDKErrors.UnauthorizedError('Must have at least one permission and no more then two') - } - - if (parentId && (typeof parentId !== 'string' || !isHex(parentId))) { - throw new SDKErrors.DelegationIdTypeError() - } -} - -/** - * Checks if the message body is well-formed. - * - * @param body The message body. - */ -export function verifyMessageBody(body: MessageBody): void { - switch (body.type) { - case 'submit-terms': { - Claim.verifyDataStructure(body.content.claim) - body.content.legitimations.forEach((credential) => Credential.verifyDataStructure(credential)) - if (body.content.delegationId) { - DataUtils.verifyIsHex(body.content.delegationId) - } - if (body.content.quote) { - Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) - } - if (body.content.cTypes) { - body.content.cTypes.forEach((val) => CType.verifyDataStructure(val)) - } - break - } - case 'request-attestation': { - Credential.verifyDataStructure(body.content.credential) - if (body.content.quote) { - Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) - } - break - } - case 'submit-attestation': { - Attestation.verifyDataStructure(body.content.attestation) - break - } - case 'reject-attestation': { - if (!isHex(body.content)) { - throw new SDKErrors.HashMalformedError() - } - break - } - case 'request-credential': { - body.content.cTypes.forEach(({ cTypeHash, trustedAttesters, requiredProperties }): void => { - DataUtils.verifyIsHex(cTypeHash) - trustedAttesters?.forEach((did) => Did.validateUri(did, 'Did')) - requiredProperties?.forEach((requiredProps) => { - if (typeof requiredProps !== 'string') throw new TypeError('Required properties is expected to be a string') - }) - }) - break - } - case 'submit-credential': { - body.content.forEach((presentation) => { - Credential.verifyDataStructure(presentation) - if (!Did.isDidSignature(presentation.claimerSignature)) { - throw new SDKErrors.SignatureMalformedError() - } - }) - break - } - - default: - throw new SDKErrors.UnknownMessageBodyTypeError() - } -} - -/** - * Checks if the message object is well-formed. - * - * @param message The message object. - */ -export function verifyMessageEnvelope(message: IMessage): void { - const { messageId, createdAt, receiver, sender, receivedAt, inReplyTo } = message - if (messageId !== undefined && typeof messageId !== 'string') { - throw new TypeError('Message id is expected to be a string') - } - if (createdAt !== undefined && typeof createdAt !== 'number') { - throw new TypeError('Created at is expected to be a number') - } - if (receivedAt !== undefined && typeof receivedAt !== 'number') { - throw new TypeError('Received at is expected to be a number') - } - Did.validateUri(sender, 'Did') - Did.validateUri(receiver, 'Did') - if (inReplyTo && typeof inReplyTo !== 'string') { - throw new TypeError('In reply to is expected to be a string') - } -} - -/** - * Verifies required properties for a given [[CType]] before sending or receiving a message. - * - * @param requiredProperties The list of required properties that need to be verified against a [[CType]]. - * @param cType A [[CType]] used to verify the properties. - */ -export function verifyRequiredCTypeProperties(requiredProperties: string[], cType: ICType): void { - CType.verifyDataStructure(cType as ICType) - - const unknownProperties = requiredProperties.find((property) => !(property in cType.properties)) - if (unknownProperties) { - throw new SDKErrors.CTypeUnknownPropertiesError() - } -} - -/** - * Verifies that the sender of a [[Message]] is also the owner of it, e.g the owner's and sender's DIDs refer to the same subject. - * - * @param message The [[Message]] object which needs to be decrypted. - * @param message.body The body of the [[Message]] which depends on the [[BodyType]]. - * @param message.sender The sender's DID taken from the [[IMessage]]. - */ -export function ensureOwnerIsSender({ body, sender }: IMessage): void { - switch (body.type) { - case 'request-attestation': - { - const requestAttestation = body - if (!Did.isSameSubject(requestAttestation.content.credential.claim.owner, sender)) { - throw new SDKErrors.IdentityMismatchError('Claim', 'Sender') - } - } - break - case 'submit-attestation': - { - const submitAttestation = body - if (!Did.isSameSubject(submitAttestation.content.attestation.owner, sender)) { - throw new SDKErrors.IdentityMismatchError('Attestation', 'Sender') - } - } - break - case 'submit-credential': - { - const submitClaimsForCtype = body - submitClaimsForCtype.content.forEach((presentation) => { - if (!Did.isSameSubject(presentation.claim.owner, sender)) { - throw new SDKErrors.IdentityMismatchError('Claims', 'Sender') - } - }) - } - break - default: - } -} - -/** - * Symmetrically decrypts the result of [[encrypt]]. - * - * @param encrypted The encrypted message. - * @param decryptCallback The callback to decrypt with the secret key. - * @param decryptionOptions Options to perform the decryption operation. - * @param decryptionOptions.resolveKey The DID key resolver to use. - * @returns The original [[Message]]. - */ -export async function decrypt( - encrypted: IEncryptedMessage, - decryptCallback: DecryptCallback, - { - resolveKey = Did.resolveKey, - }: { - resolveKey?: DidResolveKey - } = {} -): Promise { - const { senderKeyUri, receiverKeyUri, ciphertext, nonce, receivedAt } = encrypted - - const senderKeyDetails = await resolveKey(senderKeyUri, 'keyAgreement') - - const { fragment } = Did.parse(receiverKeyUri) - if (!fragment) { - throw new SDKErrors.DidError(`No fragment for the receiver key ID "${receiverKeyUri}"`) - } - - let data: Uint8Array - try { - data = ( - await decryptCallback({ - peerPublicKey: senderKeyDetails.publicKey, - data: hexToU8a(ciphertext), - nonce: hexToU8a(nonce), - keyUri: receiverKeyUri, - }) - ).data - } catch (cause) { - throw new SDKErrors.DecodingMessageError(undefined, { - cause: cause as Error, - }) - } - - const decoded = u8aToString(data) - - const { body, createdAt, messageId, inReplyTo, references, sender, receiver } = JSON.parse( - decoded - ) as IEncryptedMessageContents - const decrypted: IMessage = { - receiver, - sender, - createdAt, - body, - messageId, - receivedAt, - inReplyTo, - references, - } - - if (sender !== senderKeyDetails.controller) { - throw new SDKErrors.IdentityMismatchError('Encryption key', 'Sender') - } - - return decrypted -} - -/** - * Checks the message structure and body contents (e.g. Hashes match, ensures the owner is the sender). - * Throws, if a check fails. - * - * @param decryptedMessage The decrypted message to check. - */ -export function verify(decryptedMessage: IMessage): void { - verifyMessageBody(decryptedMessage.body) - verifyMessageEnvelope(decryptedMessage) - ensureOwnerIsSender(decryptedMessage) -} - -/** - * Constructs a message from a message body. - * This should be encrypted with [[encrypt]] before sending to the receiver. - * - * @param body The body of the message. - * @param sender The DID of the sender. - * @param receiver The DID of the receiver. - * @returns The message created. - */ -export function fromBody(body: MessageBody, sender: IMessage['sender'], receiver: IMessage['receiver']): IMessage { - return { - body, - createdAt: Date.now(), - receiver, - sender, - messageId: UUID.generate(), - } -} - -/** - * Encrypts the [[Message]] as a string. This can be reversed with [[decrypt]]. - * - * @param message The message to encrypt. - * @param encryptCallback The callback to encrypt with the secret key. - * @param receiverKeyUri The key URI of the receiver. - * @param encryptionOptions Options to perform the encryption operation. - * @param encryptionOptions.resolveKey The DID key resolver to use. - * - * @returns The encrypted version of the original [[Message]], see [[IEncryptedMessage]]. - */ -export async function encrypt( - message: IMessage, - encryptCallback: EncryptCallback, - receiverKeyUri: DidResourceUri, - { - resolveKey = Did.resolveKey, - }: { - resolveKey?: DidResolveKey - } = {} -): Promise { - const receiverKey = await resolveKey(receiverKeyUri, 'keyAgreement') - if (message.receiver !== receiverKey.controller) { - throw new SDKErrors.IdentityMismatchError('receiver public key', 'receiver') - } - - const toEncrypt: IEncryptedMessageContents = { - body: message.body, - createdAt: message.createdAt, - sender: message.sender, - receiver: message.receiver, - messageId: message.messageId, - inReplyTo: message.inReplyTo, - references: message.references, - } - - const serialized = stringToU8a(JSON.stringify(toEncrypt)) - - const encrypted = await encryptCallback({ - did: message.sender, - data: serialized, - peerPublicKey: receiverKey.publicKey, - }) - - const ciphertext = u8aToHex(encrypted.data) - const nonce = u8aToHex(encrypted.nonce) - - return { - receivedAt: message.receivedAt, - ciphertext, - nonce, - senderKeyUri: encrypted.keyUri, - receiverKeyUri: receiverKey.id, - } -} +export * from './utils' +export * from './MessageEnvelope' +export * from './CredentialApiMessageTypes' diff --git a/src/messaging/utils.ts b/src/messaging/utils.ts new file mode 100644 index 0000000..5fc0edf --- /dev/null +++ b/src/messaging/utils.ts @@ -0,0 +1,39 @@ +import { ICType } from '@kiltprotocol/types' +import { IMessage, MessageBody } from '../types' +import { CType, SDKErrors } from '@kiltprotocol/sdk-js' +import { UUID } from '@kiltprotocol/utils' + +/** + * Constructs a message from a message body. + * This should be encrypted with [[encrypt]] before sending to the receiver. + * + * @param body The body of the message. + * @param sender The DID of the sender. + * @param receiver The DID of the receiver. + * @returns The message created. + */ +export function fromBody(body: MessageBody, sender: IMessage['sender'], receiver: IMessage['receiver']): IMessage { + return { + body, + createdAt: Date.now(), + receiver, + sender, + messageId: UUID.generate(), + } +} + + +/** + * Verifies required properties for a given [[CType]] before sending or receiving a message. + * + * @param requiredProperties The list of required properties that need to be verified against a [[CType]]. + * @param cType A [[CType]] used to verify the properties. + */ +export function verifyRequiredCTypeProperties(requiredProperties: string[], cType: ICType): void { + CType.verifyDataStructure(cType as ICType) + + const unknownProperties = requiredProperties.find((property) => !(property in cType.properties)) + if (unknownProperties) { + throw new SDKErrors.CTypeUnknownPropertiesError() + } +} diff --git a/src/quote/Quote.test.ts b/src/quote/Quote.test.ts index 09b407b..e63c420 100644 --- a/src/quote/Quote.test.ts +++ b/src/quote/Quote.test.ts @@ -21,12 +21,12 @@ import type { ResolvedDidKey, } from '@kiltprotocol/types' import { Crypto, SDKErrors } from '@kiltprotocol/utils' +import { Credential, CType } from '@kiltprotocol/sdk-js' import { createLocalDemoFullDidFromKeypair, makeSigningKeyTool, } from '../tests' -import { Credential, CType } from '@kiltprotocol/sdk-js' import * as Quote from './Quote' import { QuoteSchema } from './QuoteSchema' From b5042c7bc9ec8410b2c7087a22791c3884a5e34c Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 09:58:20 +0200 Subject: [PATCH 11/39] chore: copyright --- src/messaging/utils.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/messaging/utils.ts b/src/messaging/utils.ts index 5fc0edf..cef217e 100644 --- a/src/messaging/utils.ts +++ b/src/messaging/utils.ts @@ -1,3 +1,10 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + import { ICType } from '@kiltprotocol/types' import { IMessage, MessageBody } from '../types' import { CType, SDKErrors } from '@kiltprotocol/sdk-js' From f66bca6308eae5ad292f100e6bf9753ae20ff1e7 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 13:30:22 +0200 Subject: [PATCH 12/39] remove terms --- src/types/Terms.ts | 20 -------------------- src/types/index.ts | 1 - 2 files changed, 21 deletions(-) delete mode 100644 src/types/Terms.ts diff --git a/src/types/Terms.ts b/src/types/Terms.ts deleted file mode 100644 index e4578aa..0000000 --- a/src/types/Terms.ts +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. - */ - -import type { ICType } from './CType' -import type { IDelegationNode } from './Delegation' -import type { IQuoteAttesterSigned } from './Quote' -import type { PartialClaim } from './Claim' -import type { ICredential } from './Credential' - -export interface ITerms { - claim: PartialClaim - legitimations: ICredential[] - delegationId?: IDelegationNode['id'] - quote?: IQuoteAttesterSigned - cTypes?: ICType[] -} diff --git a/src/types/index.ts b/src/types/index.ts index 85c5271..2c74659 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -4,7 +4,6 @@ import type { CredentialDigestProof, SelfSignedProof, VerifiableCredential, cons export * from './Message.js' export * from './Quote.js' -export * from './Terms.js' export * from './Imported.js' export type This = typeof globalThis From e026d9c111dafdb551734c4dcdc27ead33119d24 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 13:30:30 +0200 Subject: [PATCH 13/39] remove newline --- src/tests/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tests/utils.ts b/src/tests/utils.ts index a2816f1..ec5c2b9 100644 --- a/src/tests/utils.ts +++ b/src/tests/utils.ts @@ -153,4 +153,3 @@ export async function startContainer(): Promise { const WS_ADDRESS = `ws://${host}:${port}` return WS_ADDRESS } - From d4fb2a0c0a63cf334421968733accfd5c70b978c Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 13:30:53 +0200 Subject: [PATCH 14/39] update imports --- src/types/Quote.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/types/Quote.ts b/src/types/Quote.ts index 256b30c..a29937d 100644 --- a/src/types/Quote.ts +++ b/src/types/Quote.ts @@ -5,9 +5,7 @@ * found in the LICENSE file in the root directory of this source tree. */ -import type { DidSignature, DidUri } from './DidDocument' -import type { ICredential } from './Credential' -import type { CTypeHash } from './CType' +import type { DidSignature, DidUri, ICredential, CTypeHash } from '@kiltprotocol/types' export interface ICostBreakdown { tax: Record From 3f3aa01f2af6dbbd023d75da81ff8442eebb1501 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 13:30:59 +0200 Subject: [PATCH 15/39] add comments --- src/types/Message.ts | 164 +++++++++++++++++++++++++++++-------------- 1 file changed, 110 insertions(+), 54 deletions(-) diff --git a/src/types/Message.ts b/src/types/Message.ts index 02a524d..575ac28 100644 --- a/src/types/Message.ts +++ b/src/types/Message.ts @@ -1,15 +1,21 @@ -import type { ITerms } from './Terms' -import type { ICredential, ICredentialPresentation, IAttestation, CTypeHash, DidResourceUri, DidUri, IDelegationNode,PartialClaim } from '@kiltprotocol/types' -import type { IQuoteAgreement } from './Quote' +import type { ICredential, ICredentialPresentation, IAttestation, CTypeHash, DidResourceUri, DidUri, IDelegationNode, PartialClaim, ICType } from '@kiltprotocol/types' +import type { IQuoteAgreement, IQuoteAttesterSigned } from './Quote' - -export interface IDelegationData { - account: IDelegationNode['account'] - id: IDelegationNode['id'] - parentId: IDelegationNode['id'] - permissions: IDelegationNode['permissions'] - isPCR: boolean -} +/** + * All possible message types which are defined in the KILT Credential API (Spec version 3.2) + * https://github.com/KILTprotocol/spec-ext-credential-api + */ +export type MessageBody = + | IError + | IReject + | ISubmitTerms + | IRequestAttestation + | IRequestPayment + | IConfirmPayment + | ISubmitAttestation + | IRejectAttestation + | IRequestCredential + | ISubmitCredential export type MessageBodyType = | 'error' @@ -30,6 +36,32 @@ interface IMessageBodyBase { type: MessageBodyType } + +/** + * - `body` - The body of the message, see [[MessageBody]]. + * - `createdAt` - The timestamp of the message construction. + * - `sender` - The DID of the sender. + * - `receiver` - The DID of the receiver. + * - `messageId` - The message id. + * - `receivedAt` - The timestamp of the message reception. + * - `inReplyTo` - The id of the parent-message. + * - `references` - The references or the in-reply-to of the parent-message followed by the message-id of the parent-message. + */ +export interface IMessage { + body: MessageBody + createdAt: number + sender: DidUri + receiver: DidUri + messageId?: string + receivedAt?: number + inReplyTo?: IMessage['messageId'] + references?: Array +} + +/** + * Error messages signal unintentional programming errors which happened during + * the processing of the incoming messages or when constructing a response message. + */ export interface IError extends IMessageBodyBase { content: { /** Optional machine-readable type of the error. */ @@ -40,6 +72,9 @@ export interface IError extends IMessageBodyBase { type: 'error' } +/** + * Rejection messages signal the intentional cancelling of an individual step in the flow. + */ export interface IReject extends IMessageBodyBase { content: { /** Optional machine-readable type of the rejection. */ @@ -50,72 +85,121 @@ export interface IReject extends IMessageBodyBase { type: 'reject' } + +/** + * An attester utilizes the message to propose a claim. The purpose of the extension is to enable + * the user to authorize and endorse the claims prepared by the attester. + */ export interface ISubmitTerms extends IMessageBodyBase { content: ITerms type: 'submit-terms' } + +/** + * The content of the [IRequestAttestation] message. + */ export interface IRequestAttestationContent { credential: ICredential quote?: IQuoteAgreement } +/** + * The extension only sends the request with active consent of the user. This is the first step + * where the user’s DID is revealed to the dApp. + */ export interface IRequestAttestation extends IMessageBodyBase { content: IRequestAttestationContent type: 'request-attestation' } + +/** + * The content of the [IRequestPayment] message. + */ export interface IRequestPaymentContent { // Same as the `rootHash` value of the `'request-attestation'` message */ claimHash: string } +/** + * An attester can send this message if it wants the user to transfer payment in KILT Coins by themselves without interrupting the flow. + */ export interface IRequestPayment extends IMessageBodyBase { content: IRequestPaymentContent type: 'request-payment' } + +/** + * The content of the [ISubmitAttestation] message. + */ export interface ISubmitAttestationContent { attestation: IAttestation } +/** + * The attester sends the valid credential to the extension. + */ export interface ISubmitAttestation extends IMessageBodyBase { content: ISubmitAttestationContent type: 'submit-attestation' } + +/** + * If the attester does not approve the attestation request, the extension receives the [IRejectAttestation] message. + */ export interface IRejectAttestation extends IMessageBodyBase { content: ICredential['rootHash'] type: 'reject-attestation' } -export interface IRequestCredentialContent { - cTypes: Array<{ - cTypeHash: CTypeHash - trustedAttesters?: DidUri[] - requiredProperties?: string[] - }> - challenge?: string -} -export interface IRejectTermsContent { + + +/** + * The content of the [ISubmitTerms] message. + */ +export interface ITerms { claim: PartialClaim + // optional array of credentials of the attester legitimations: ICredential[] + // optional ID of the DelegationNode of the attester delegationId?: IDelegationNode['id'] + // Optional attester-signed binding + quote?: IQuoteAttesterSigned + // CTypes for the proposed credential. In most cases this will be just one, but in the case of nested ctypes, this can be multiple. + cTypes?: ICType[] } - +/** Message to submit credentials from the extension or dapp.*/ export interface ISubmitCredential extends IMessageBodyBase { content: ICredentialPresentation[] type: 'submit-credential' } +/** + * The content of the [IRequestCredential] message. + */ +export interface IRequestCredentialContent { + cTypes: Array<{ + cTypeHash: CTypeHash + trustedAttesters?: DidUri[] + requiredProperties?: string[] + }> + challenge?: string +} export interface IRequestCredential extends IMessageBodyBase { content: IRequestCredentialContent type: 'request-credential' } + +/** + * The content of the [IConfirmPayment] message. + */ export interface IConfirmPaymentContent { // Same as the `rootHash` value of the `'request-attestation'` message claimHash: string @@ -125,42 +209,14 @@ export interface IConfirmPaymentContent { blockHash: string } -export interface IConfirmPayment extends IMessageBodyBase { - content: IConfirmPaymentContent - type: 'confirm-payment' -} - -export type MessageBody = - | IError - | IReject - | ISubmitTerms - | IRequestAttestation - | IRequestPayment - | IConfirmPayment - | ISubmitAttestation - | IRejectAttestation - | IRequestCredential - | ISubmitCredential /** - * - `body` - The body of the message, see [[MessageBody]]. - * - `createdAt` - The timestamp of the message construction. - * - `sender` - The DID of the sender. - * - `receiver` - The DID of the receiver. - * - `messageId` - The message id. - * - `receivedAt` - The timestamp of the message reception. - * - `inReplyTo` - The id of the parent-message. - * - `references` - The references or the in-reply-to of the parent-message followed by the message-id of the parent-message. + * After the user has authorized the payment and it has been transferred, + * the extension confirms the transfer to the attester by sending the [IConfirmPayment] message. */ -export interface IMessage { - body: MessageBody - createdAt: number - sender: DidUri - receiver: DidUri - messageId?: string - receivedAt?: number - inReplyTo?: IMessage['messageId'] - references?: Array +export interface IConfirmPayment extends IMessageBodyBase { + content: IConfirmPaymentContent + type: 'confirm-payment' } /** From 92f433e45760a73978e7b418894f7551a61b887f Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 14:54:52 +0200 Subject: [PATCH 16/39] docs docs docs --- src/tests/messageUtils.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/tests/messageUtils.ts b/src/tests/messageUtils.ts index 10f4209..ea91e64 100644 --- a/src/tests/messageUtils.ts +++ b/src/tests/messageUtils.ts @@ -134,6 +134,13 @@ export function makeDecryptCallback({ } } +/** + * + * basic encrypt callback. + * @param DidDocument + * @returns EncryptResponseData + * + * */ export type EncryptionKeyToolCallback = ( didDocument: DidDocument ) => EncryptCallback @@ -162,17 +169,26 @@ export function makeEncryptCallback({ secretKey ) return { + // used nonce for encryption nonce, + // encrypted data data: box, + // used did key uri for encryption. keyUri: `${didDocument.uri}${keyId}`, } } } } +/** + * Basic tool set for encrypt and decrypt messages. + */ export interface EncryptionKeyTool { + // used keys for encrypt and decrypt. keyAgreement: [KiltEncryptionKeypair] + // callback to encrypt message. encrypt: EncryptionKeyToolCallback + // callback to decrypt messages decrypt: DecryptCallback } @@ -200,6 +216,13 @@ export function computeKeyId(key: DidKey['publicKey']): DidKey['id'] { return `#${blake2AsHex(key, 256)}` } + +/** + * Creates a DidKey by providing the publicKey. + * + * @param KiltKeyringPair The public key and the used public-key-concept. + * @returns DidVerificationKey + */ function makeDidKeyFromKeypair({ publicKey, type, @@ -247,6 +270,8 @@ export async function createLocalDemoFullDidFromKeypair( if (keyRelationships.has('keyAgreement')) { const encryptionKeypair = makeEncryptionKeyTool(`${keypair.publicKey}//enc`) .keyAgreement[0] + + // encryption key with public key, private key, type, and id. const encKey = { ...encryptionKeypair, id: computeKeyId(encryptionKeypair.publicKey), From e7dc7cc8cdc1c3bbefca51f32b687e2a7defffe8 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 15:06:18 +0200 Subject: [PATCH 17/39] docs docs docs --- src/types/Quote.ts | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/types/Quote.ts b/src/types/Quote.ts index a29937d..b6e94e2 100644 --- a/src/types/Quote.ts +++ b/src/types/Quote.ts @@ -7,6 +7,9 @@ import type { DidSignature, DidUri, ICredential, CTypeHash } from '@kiltprotocol/types' +/** + * Interface to break down the costs for a quote. + */ export interface ICostBreakdown { tax: Record net: number @@ -20,13 +23,23 @@ export interface IQuote { timeframe: string termsAndConditions: string } + +/** + * Signed quote from attester + */ export interface IQuoteAttesterSigned extends IQuote { + // Signature of the attester attesterSignature: DidSignature } +/** + * If the claimer accepts the quote from the attester, the claimer counter-signs it + */ export interface IQuoteAgreement extends IQuoteAttesterSigned { + // Attached credential hash for linking the Quote to the credential that it refers to rootHash: ICredential['rootHash'] claimerDid: DidUri + // The signature of the claimer. claimerSignature: DidSignature } From d1c69c7eeafb808ec0de1ea4e3df9f3fcd8f8e37 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 9 Aug 2023 16:58:55 +0200 Subject: [PATCH 18/39] feat: type guards --- src/messaging/CredentialApiMessageTypes.ts | 87 ++++++++------ src/utils/TypeGuards.ts | 129 +++++++++++++++++++++ src/utils/index.ts | 1 + 3 files changed, 179 insertions(+), 38 deletions(-) create mode 100644 src/utils/TypeGuards.ts create mode 100644 src/utils/index.ts diff --git a/src/messaging/CredentialApiMessageTypes.ts b/src/messaging/CredentialApiMessageTypes.ts index a9a435e..71192ff 100644 --- a/src/messaging/CredentialApiMessageTypes.ts +++ b/src/messaging/CredentialApiMessageTypes.ts @@ -10,6 +10,7 @@ import { DataUtils, SDKErrors } from '@kiltprotocol/utils' import * as Did from '@kiltprotocol/did' import { isHex } from '@polkadot/util' +import { isSubmitTerms, isRequestAttestation, isSubmitAttestation, isRejectAttestation, isSubmitCredential, isIRequestCredential } from '../utils' import {verifyMessageEnvelope} from './MessageEnvelope' import type { IMessage, @@ -24,56 +25,67 @@ import type { export function verifyMessageBody(body: MessageBody): void { switch (body.type) { case 'submit-terms': { - Claim.verifyDataStructure(body.content.claim) - body.content.legitimations.forEach((credential) => Credential.verifyDataStructure(credential)) - if (body.content.delegationId) { - DataUtils.verifyIsHex(body.content.delegationId) - } - if (body.content.quote) { - Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) - } - if (body.content.cTypes) { - body.content.cTypes.forEach((val) => CType.verifyDataStructure(val)) + if (isSubmitTerms(body)) { + Claim.verifyDataStructure(body.content.claim) + body.content.legitimations.forEach((credential) => Credential.verifyDataStructure(credential)) + if (body.content.delegationId) { + DataUtils.verifyIsHex(body.content.delegationId) + } + if (body.content.quote) { + Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) + } + if (body.content.cTypes) { + body.content.cTypes.forEach((val) => CType.verifyDataStructure(val)) + } } break } case 'request-attestation': { - Credential.verifyDataStructure(body.content.credential) - if (body.content.quote) { - Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) + if (isRequestAttestation(body)) { + Credential.verifyDataStructure(body.content.credential) + if (body.content.quote) { + Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) + } } break } case 'submit-attestation': { - Attestation.verifyDataStructure(body.content.attestation) + if (isSubmitAttestation(body)) { + Attestation.verifyDataStructure(body.content.attestation) + } break } case 'reject-attestation': { - if (!isHex(body.content)) { - throw new SDKErrors.HashMalformedError() + if (isRejectAttestation(body)) { + if (!isHex(body.content)) { + throw new SDKErrors.HashMalformedError() + } } break } case 'request-credential': { - body.content.cTypes.forEach(({ cTypeHash, trustedAttesters, requiredProperties }): void => { - DataUtils.verifyIsHex(cTypeHash) - trustedAttesters?.forEach((did) => Did.validateUri(did, 'Did')) - requiredProperties?.forEach((requiredProps) => { - if (typeof requiredProps !== 'string') throw new TypeError('Required properties is expected to be a string') + if (isIRequestCredential(body)) { + body.content.cTypes.forEach(({ cTypeHash, trustedAttesters, requiredProperties }) => { + DataUtils.verifyIsHex(cTypeHash) + trustedAttesters?.forEach((did) => Did.validateUri(did, 'Did')) + requiredProperties?.forEach((requiredProps) => { + if (typeof requiredProps !== 'string') throw new TypeError('Required properties is expected to be a string') + }) }) - }) + } break } case 'submit-credential': { - body.content.forEach((presentation) => { - Credential.verifyDataStructure(presentation) - if (!Did.isDidSignature(presentation.claimerSignature)) { - throw new SDKErrors.SignatureMalformedError() - } - }) + if (isSubmitCredential(body)) { + body.content.forEach((presentation) => { + Credential.verifyDataStructure(presentation) + if (!Did.isDidSignature(presentation.claimerSignature)) { + throw new SDKErrors.SignatureMalformedError() + } + }) + } break } - default: throw new SDKErrors.UnknownMessageBodyTypeError() } @@ -86,28 +98,26 @@ export function verifyMessageBody(body: MessageBody): void { * @param message.body The body of the [[Message]] which depends on the [[BodyType]]. * @param message.sender The sender's DID taken from the [[IMessage]]. */ + export function ensureOwnerIsSender({ body, sender }: IMessage): void { switch (body.type) { case 'request-attestation': - { - const requestAttestation = body - if (!Did.isSameSubject(requestAttestation.content.credential.claim.owner, sender)) { + if (isRequestAttestation(body)) { + if (!Did.isSameSubject(body.content.credential.claim.owner, sender)) { throw new SDKErrors.IdentityMismatchError('Claim', 'Sender') } } break case 'submit-attestation': - { - const submitAttestation = body - if (!Did.isSameSubject(submitAttestation.content.attestation.owner, sender)) { + if (isSubmitAttestation(body)) { + if (!Did.isSameSubject(body.content.attestation.owner, sender)) { throw new SDKErrors.IdentityMismatchError('Attestation', 'Sender') } } break case 'submit-credential': - { - const submitClaimsForCtype = body - submitClaimsForCtype.content.forEach((presentation) => { + if (isSubmitCredential(body)) { + body.content.forEach((presentation) => { if (!Did.isSameSubject(presentation.claim.owner, sender)) { throw new SDKErrors.IdentityMismatchError('Claims', 'Sender') } @@ -115,6 +125,7 @@ export function ensureOwnerIsSender({ body, sender }: IMessage): void { } break default: + break } } diff --git a/src/utils/TypeGuards.ts b/src/utils/TypeGuards.ts new file mode 100644 index 0000000..db295c8 --- /dev/null +++ b/src/utils/TypeGuards.ts @@ -0,0 +1,129 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ICredentialPresentation } from '@kiltprotocol/types' + +import type { + IRejectAttestation, + IRequestAttestation, + IRequestCredential, + IRequestCredentialContent, + ISubmitAttestation, + ISubmitCredential, + ISubmitTerms, + MessageBody, +} from '../types' + +export function isSubmitTerms(body: MessageBody): body is ISubmitTerms { + return ( + body.type === 'submit-terms' && + typeof body === 'object' && + 'content' in body && + 'claim' in body.content && + 'legitimations' in body.content && + (typeof body.content.legitimations === 'undefined' || Array.isArray(body.content.legitimations)) && + (typeof body.content.delegationId === 'undefined' || typeof body.content.delegationId === 'string') && + (typeof body.content.quote === 'undefined' || typeof body.content.quote === 'object') && + (typeof body.content.cTypes === 'undefined' || Array.isArray(body.content.cTypes)) + ) +} + +export function isRequestAttestation(body: MessageBody): body is IRequestAttestation { + return ( + body.type === 'request-attestation' && + typeof body === 'object' && + 'credential' in body.content && + typeof body.content.credential === 'object' && + (typeof body.content.quote === 'undefined' || typeof body.content.quote === 'object') + ) +} + +export function isSubmitAttestation(body: MessageBody): body is ISubmitAttestation { + return ( + body.type === 'submit-attestation' && + typeof body === 'object' && + 'content' in body && + typeof body.content === 'object' && + 'attestation' in body.content && + typeof body.content.attestation === 'object' + ) +} + +export function isRejectAttestation(body: MessageBody): body is IRejectAttestation { + return ( + body.type === 'reject-attestation' && + typeof body === 'object' && + 'content' in body && + typeof body.content === 'string' + ) +} + + + +export function isIRequestCredential(body: MessageBody): body is IRequestCredential { + return ( + typeof body === 'object' && + body !== null && + 'type' in body && + body.type === 'request-credential' && + 'content' in body && + isIRequestCredentialContent(body.content) + ) +} + +export function isIRequestCredentialContent(body: any): body is IRequestCredentialContent { + if ( + typeof body !== 'object' || + body === null || + !Array.isArray(body.cTypes) || + !body.cTypes.every((cType : any) => + typeof cType === 'object' && + cType !== null && + 'cTypeHash' in cType && + typeof cType.cTypeHash === 'string' && + (typeof cType.trustedAttesters === 'undefined' || Array.isArray(cType.trustedAttesters)) && + (typeof cType.requiredProperties === 'undefined' || Array.isArray(cType.requiredProperties)) + ) + ) { + return false + } + + if ('challenge' in body && typeof body.challenge !== 'undefined' && typeof body.challenge !== 'string') { + return false + } + + return true +} + +export function isSubmitCredential(body: MessageBody): body is ISubmitCredential { + return ( + typeof body === 'object' && + body !== null && + 'type' in body && + body.type === 'submit-credential' && + 'content' in body && + Array.isArray(body.content) && + body.content.every(isICredentialPresentation) + ) +} + +function isICredentialPresentation(body: any): body is ICredentialPresentation { + return ( + typeof body === 'object' && + body !== null && + 'claimerSignature' in body && + typeof body.claimerSignature === 'object' && + 'claim' in body && + 'claimNonceMap' in body && + 'claimHashes' in body && + 'delegationId' in body && + (body.delegationId === null || typeof body.delegationId === 'string') && + 'legitimations' in body && + Array.isArray(body.legitimations) && + 'rootHash' in body && + typeof body.rootHash === 'string' && + ('challenge' in body.claimerSignature ? typeof body.claimerSignature.challenge === 'string' : true) + ) +} + + + + diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..e84e2f2 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1 @@ +export * from './TypeGuards' From a493e939c3c2ff19cce0e63f325d27c1da7cb681 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Thu, 10 Aug 2023 10:20:40 +0200 Subject: [PATCH 19/39] feat: generics for message --- src/types/Message.ts | 70 ++++++++++---------------------------------- 1 file changed, 15 insertions(+), 55 deletions(-) diff --git a/src/types/Message.ts b/src/types/Message.ts index 575ac28..b6ff356 100644 --- a/src/types/Message.ts +++ b/src/types/Message.ts @@ -30,10 +30,9 @@ export type MessageBodyType = | 'submit-credential' | 'reject-terms' -interface IMessageBodyBase { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - content: any - type: MessageBodyType +interface IMessageBodyBase { + content: Content + type: Type } @@ -62,43 +61,24 @@ export interface IMessage { * Error messages signal unintentional programming errors which happened during * the processing of the incoming messages or when constructing a response message. */ -export interface IError extends IMessageBodyBase { - content: { - /** Optional machine-readable type of the error. */ - name?: string - /** Optional human-readable description of the error. */ - message?: string - } - type: 'error' -} +export type IError = IMessageBodyBase<'error', {name? : string, message?: string}>; /** * Rejection messages signal the intentional cancelling of an individual step in the flow. */ -export interface IReject extends IMessageBodyBase { - content: { - /** Optional machine-readable type of the rejection. */ - name?: string - /** Optional human-readable description of the rejection. */ - message?: string - } - type: 'reject' -} - +export type IReject = IMessageBodyBase<'reject', {name? : string, message?: string}>; /** * An attester utilizes the message to propose a claim. The purpose of the extension is to enable * the user to authorize and endorse the claims prepared by the attester. */ -export interface ISubmitTerms extends IMessageBodyBase { - content: ITerms - type: 'submit-terms' -} +export type ISubmitTerms = IMessageBodyBase<'submit-terms', ITerms>; /** * The content of the [IRequestAttestation] message. */ + export interface IRequestAttestationContent { credential: ICredential quote?: IQuoteAgreement @@ -108,10 +88,7 @@ export interface IRequestAttestationContent { * The extension only sends the request with active consent of the user. This is the first step * where the user’s DID is revealed to the dApp. */ -export interface IRequestAttestation extends IMessageBodyBase { - content: IRequestAttestationContent - type: 'request-attestation' -} +export type IRequestAttestation = IMessageBodyBase<'request-attestation', IRequestAttestationContent> /** @@ -125,10 +102,7 @@ export interface IRequestPaymentContent { /** * An attester can send this message if it wants the user to transfer payment in KILT Coins by themselves without interrupting the flow. */ -export interface IRequestPayment extends IMessageBodyBase { - content: IRequestPaymentContent - type: 'request-payment' -} +export type IRequestPayment = IMessageBodyBase<'request-payment', IRequestPaymentContent> /** @@ -141,19 +115,13 @@ export interface ISubmitAttestationContent { /** * The attester sends the valid credential to the extension. */ -export interface ISubmitAttestation extends IMessageBodyBase { - content: ISubmitAttestationContent - type: 'submit-attestation' -} +export type ISubmitAttestation = IMessageBodyBase<'submit-attestation', ISubmitAttestationContent> /** * If the attester does not approve the attestation request, the extension receives the [IRejectAttestation] message. */ -export interface IRejectAttestation extends IMessageBodyBase { - content: ICredential['rootHash'] - type: 'reject-attestation' -} +export type IRejectAttestation = IMessageBodyBase<'reject-attestation', ICredential['rootHash']> @@ -175,10 +143,7 @@ export interface ITerms { /** Message to submit credentials from the extension or dapp.*/ -export interface ISubmitCredential extends IMessageBodyBase { - content: ICredentialPresentation[] - type: 'submit-credential' -} +export type ISubmitCredential = IMessageBodyBase<'submit-credential', ICredentialPresentation[]> /** * The content of the [IRequestCredential] message. @@ -191,10 +156,8 @@ export interface IRequestCredentialContent { }> challenge?: string } -export interface IRequestCredential extends IMessageBodyBase { - content: IRequestCredentialContent - type: 'request-credential' -} + +export type IRequestCredential = IMessageBodyBase<'request-credential', IRequestCredentialContent> /** @@ -214,10 +177,7 @@ export interface IConfirmPaymentContent { * After the user has authorized the payment and it has been transferred, * the extension confirms the transfer to the attester by sending the [IConfirmPayment] message. */ -export interface IConfirmPayment extends IMessageBodyBase { - content: IConfirmPaymentContent - type: 'confirm-payment' -} +export type IConfirmPayment = IMessageBodyBase<'confirm-payment', IConfirmPaymentContent> /** * Everything which is part of the encrypted and protected part of the [[IMessage]]. From 13b7dcf822c04b281f68da6f3f6a4d4839619ea0 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Thu, 10 Aug 2023 14:03:28 +0200 Subject: [PATCH 20/39] feat: type guards --- .eslintrc.json | 10 +- .prettierrc | 7 +- package.json | 1 + src/messaging/CredentialApiMessageTypes.ts | 182 ++- src/messaging/Message.test.ts | 139 +- src/messaging/MessageEnvelope.ts | 53 +- src/messaging/index.ts | 2 +- src/messaging/utils.ts | 27 +- src/quote/Quote.test.ts | 36 +- src/quote/Quote.ts | 109 +- src/quote/QuoteSchema.ts | 9 +- src/tests/messageUtils.ts | 198 ++- src/types/Message.ts | 14 +- src/utils/TypeGuards.ts | 181 ++- yarn.lock | 1329 ++++++++++---------- 15 files changed, 1104 insertions(+), 1193 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 6957d59..928ea18 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -5,7 +5,8 @@ }, "extends": [ "eslint:recommended", - "plugin:@typescript-eslint/recommended" + "plugin:@typescript-eslint/recommended", + "prettier" ], "parser": "@typescript-eslint/parser", "parserOptions": { @@ -16,10 +17,7 @@ "@typescript-eslint" ], "rules": { - "indent": [ - "error", - 2 - ], + "linebreak-style": [ "error", "unix" @@ -33,4 +31,4 @@ "never" ] } -} \ No newline at end of file +} diff --git a/.prettierrc b/.prettierrc index 5149b1b..eadb010 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,6 @@ { - "trailingComma": "es5", - "semi": false, - "singleQuote": true + "trailingComma": "es5", + "semi": false, + "singleQuote": true, + "tabWidth": 2 } diff --git a/package.json b/package.json index a3e8031..aa92873 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "@typescript-eslint/eslint-plugin": "^5.33.0", "@typescript-eslint/parser": "^5.33.0", "eslint": ">=8.14.0", + "eslint-config-prettier": "^9.0.0", "jest": "^28.0.0", "react": "^18.2.0", "testcontainers": "^9.5.0", diff --git a/src/messaging/CredentialApiMessageTypes.ts b/src/messaging/CredentialApiMessageTypes.ts index 71192ff..b04e18a 100644 --- a/src/messaging/CredentialApiMessageTypes.ts +++ b/src/messaging/CredentialApiMessageTypes.ts @@ -10,135 +10,101 @@ import { DataUtils, SDKErrors } from '@kiltprotocol/utils' import * as Did from '@kiltprotocol/did' import { isHex } from '@polkadot/util' -import { isSubmitTerms, isRequestAttestation, isSubmitAttestation, isRejectAttestation, isSubmitCredential, isIRequestCredential } from '../utils' -import {verifyMessageEnvelope} from './MessageEnvelope' -import type { - IMessage, - MessageBody, -} from '../types' +import { + isSubmitTerms, + isRequestAttestation, + isSubmitAttestation, + isRejectAttestation, + isSubmitCredential, + isIRequestCredential, +} from '../utils' +import { verifyMessageEnvelope } from './MessageEnvelope' +import type { IMessage } from '../types' /** - * Checks if the message body is well-formed. - * - * @param body The message body. - */ -export function verifyMessageBody(body: MessageBody): void { - switch (body.type) { - case 'submit-terms': { - if (isSubmitTerms(body)) { - Claim.verifyDataStructure(body.content.claim) - body.content.legitimations.forEach((credential) => Credential.verifyDataStructure(credential)) - if (body.content.delegationId) { - DataUtils.verifyIsHex(body.content.delegationId) - } - if (body.content.quote) { - Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) - } - if (body.content.cTypes) { - body.content.cTypes.forEach((val) => CType.verifyDataStructure(val)) - } + * Checks if the message body is well-formed. + * + * @param body The message body. + */ +export function verifyMessageBody(message: IMessage): void { + if (isSubmitTerms(message)) { + const { body } = message + Claim.verifyDataStructure(body.content.claim) + body.content.legitimations.forEach((credential) => Credential.verifyDataStructure(credential)) + if (body.content.delegationId) { + DataUtils.verifyIsHex(body.content.delegationId) } - break - } - case 'request-attestation': { - if (isRequestAttestation(body)) { - Credential.verifyDataStructure(body.content.credential) - if (body.content.quote) { - Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) - } + if (body.content.quote) { + Quote.validateQuoteSchema(Quote.QuoteSchema, body.content.quote) } - break - } - case 'submit-attestation': { - if (isSubmitAttestation(body)) { - Attestation.verifyDataStructure(body.content.attestation) + if (body.content.cTypes) { + body.content.cTypes.forEach((val) => CType.verifyDataStructure(val)) } - break - } - case 'reject-attestation': { - if (isRejectAttestation(body)) { - if (!isHex(body.content)) { - throw new SDKErrors.HashMalformedError() - } + } else if (isRequestAttestation(message)) { + Credential.verifyDataStructure(message.body.content.credential) + if (message.body.content.quote) { + Quote.validateQuoteSchema(Quote.QuoteSchema, message.body.content.quote) } - break - } - case 'request-credential': { - if (isIRequestCredential(body)) { - body.content.cTypes.forEach(({ cTypeHash, trustedAttesters, requiredProperties }) => { - DataUtils.verifyIsHex(cTypeHash) - trustedAttesters?.forEach((did) => Did.validateUri(did, 'Did')) - requiredProperties?.forEach((requiredProps) => { - if (typeof requiredProps !== 'string') throw new TypeError('Required properties is expected to be a string') - }) - }) + } else if (isSubmitAttestation(message)) { + Attestation.verifyDataStructure(message.body.content.attestation) + } else if (isRejectAttestation(message)) { + if (!isHex(message.body.content)) { + throw new SDKErrors.HashMalformedError() } - break - } - case 'submit-credential': { - if (isSubmitCredential(body)) { - body.content.forEach((presentation) => { - Credential.verifyDataStructure(presentation) - if (!Did.isDidSignature(presentation.claimerSignature)) { - throw new SDKErrors.SignatureMalformedError() - } + } else if (isIRequestCredential(message)) { + message.body.content.cTypes.forEach(({ cTypeHash, trustedAttesters, requiredProperties }) => { + DataUtils.verifyIsHex(cTypeHash) + trustedAttesters?.forEach((did) => Did.validateUri(did, 'Did')) + requiredProperties?.forEach((requiredProps) => { + if (typeof requiredProps !== 'string') throw new TypeError('Required properties is expected to be a string') }) - } - break - } - default: + }) + } else if (isSubmitCredential(message)) { + message.body.content.forEach((presentation) => { + Credential.verifyDataStructure(presentation) + if (!Did.isDidSignature(presentation.claimerSignature)) { + throw new SDKErrors.SignatureMalformedError() + } + }) + } else { throw new SDKErrors.UnknownMessageBodyTypeError() } } /** - * Verifies that the sender of a [[Message]] is also the owner of it, e.g the owner's and sender's DIDs refer to the same subject. - * - * @param message The [[Message]] object which needs to be decrypted. - * @param message.body The body of the [[Message]] which depends on the [[BodyType]]. - * @param message.sender The sender's DID taken from the [[IMessage]]. - */ + * Verifies that the sender of a [[Message]] is also the owner of it, e.g the owner's and sender's DIDs refer to the same subject. + * + * @param message The [[Message]] object which needs to be decrypted. + * @param message.body The body of the [[Message]] which depends on the [[BodyType]]. + * @param message.sender The sender's DID taken from the [[IMessage]]. + */ -export function ensureOwnerIsSender({ body, sender }: IMessage): void { - switch (body.type) { - case 'request-attestation': - if (isRequestAttestation(body)) { - if (!Did.isSameSubject(body.content.credential.claim.owner, sender)) { - throw new SDKErrors.IdentityMismatchError('Claim', 'Sender') - } +export function ensureOwnerIsSender(message: IMessage): void { + if (isRequestAttestation(message)) { + if (!Did.isSameSubject(message.body.content.credential.claim.owner, message.sender)) { + throw new SDKErrors.IdentityMismatchError('Claim', 'Sender') } - break - case 'submit-attestation': - if (isSubmitAttestation(body)) { - if (!Did.isSameSubject(body.content.attestation.owner, sender)) { - throw new SDKErrors.IdentityMismatchError('Attestation', 'Sender') - } + } else if (isSubmitAttestation(message)) { + if (!Did.isSameSubject(message.body.content.attestation.owner, message.sender)) { + throw new SDKErrors.IdentityMismatchError('Attestation', 'Sender') } - break - case 'submit-credential': - if (isSubmitCredential(body)) { - body.content.forEach((presentation) => { - if (!Did.isSameSubject(presentation.claim.owner, sender)) { - throw new SDKErrors.IdentityMismatchError('Claims', 'Sender') - } - }) - } - break - default: - break + } else if (isSubmitCredential(message)) { + message.body.content.forEach((presentation) => { + if (!Did.isSameSubject(presentation.claim.owner, message.sender)) { + throw new SDKErrors.IdentityMismatchError('Claims', 'Sender') + } + }) } } /** - * Checks the message structure and body contents (e.g. Hashes match, ensures the owner is the sender). - * Throws, if a check fails. - * - * @param decryptedMessage The decrypted message to check. - */ + * Checks the message structure and body contents (e.g. Hashes match, ensures the owner is the sender). + * Throws, if a check fails. + * + * @param decryptedMessage The decrypted message to check. + */ export function verify(decryptedMessage: IMessage): void { - verifyMessageBody(decryptedMessage.body) + verifyMessageBody(decryptedMessage) verifyMessageEnvelope(decryptedMessage) ensureOwnerIsSender(decryptedMessage) } - - diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index ef7e2d8..e9366ff 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -12,7 +12,8 @@ import { Attestation, CType, Claim, Credential, Quote } from '@kiltprotocol/core import * as Did from '@kiltprotocol/did' import { init } from '@kiltprotocol/sdk-js' import { Crypto, SDKErrors } from '@kiltprotocol/utils' -import type { DidDocument, +import type { + DidDocument, DidKey, DidResourceUri, DidUri, @@ -21,7 +22,7 @@ import type { DidDocument, ResolvedDidKey, IClaim, ICredential, - ICredentialPresentation + ICredentialPresentation, } from '@kiltprotocol/sdk-js' import { @@ -51,11 +52,8 @@ import type { ISubmitCredential, ISubmitTerms, ITerms, - MessageBody, } from '../types' - - describe('Messaging', () => { let aliceLightDid: DidDocument let aliceLightDidWithDetails: DidDocument @@ -136,7 +134,9 @@ describe('Messaging', () => { expect(() => verify(decryptedMessage)).not.toThrow() - const encryptedMessageWrongContent = JSON.parse(JSON.stringify(encryptedMessage)) as IEncryptedMessage + const encryptedMessageWrongContent = JSON.parse( + JSON.stringify(encryptedMessage) + ) as IEncryptedMessage const messedUpContent = Crypto.coToUInt8(encryptedMessageWrongContent.ciphertext) messedUpContent.set(Crypto.hash('1234'), 10) encryptedMessageWrongContent.ciphertext = u8aToHex(messedUpContent) @@ -153,7 +153,7 @@ describe('Messaging', () => { peerPublicKey: bobLightDid.keyAgreement![0].publicKey, did: aliceLightDid.uri, }) - const encryptedMessageWrongBody: IEncryptedMessage = { + const encryptedMessageWrongBody: IEncryptedMessage = { ciphertext: u8aToHex(encryptedWrongBody.data), nonce: u8aToHex(encryptedWrongBody.nonce), // eslint-disable-next-line @typescript-eslint/no-non-null-assertion @@ -211,20 +211,16 @@ describe('Messaging', () => { } // Should not throw if the owner and sender DID is the same. - expect(() => - ensureOwnerIsSender(fromBody(requestAttestationBody, aliceFullDid.uri, bobFullDid.uri)) - ).not.toThrow() + expect(() => ensureOwnerIsSender(fromBody(requestAttestationBody, aliceFullDid.uri, bobFullDid.uri))).not.toThrow() // Should not throw if the sender is the light DID version of the owner. // This is technically not to be allowed but message verification is not concerned with that. - expect(() => - ensureOwnerIsSender(fromBody(requestAttestationBody, aliceLightDid.uri, bobFullDid.uri)) - ).not.toThrow() + expect(() => ensureOwnerIsSender(fromBody(requestAttestationBody, aliceLightDid.uri, bobFullDid.uri))).not.toThrow() // Should throw if the sender and the owner are two different entities. - expect(() => - ensureOwnerIsSender(fromBody(requestAttestationBody, bobFullDid.uri, aliceFullDid.uri)) - ).toThrowError(SDKErrors.IdentityMismatchError) + expect(() => ensureOwnerIsSender(fromBody(requestAttestationBody, bobFullDid.uri, aliceFullDid.uri))).toThrowError( + SDKErrors.IdentityMismatchError + ) const attestation = { delegationId: null, @@ -242,20 +238,16 @@ describe('Messaging', () => { } // Should not throw if the owner and sender DID is the same. - expect(() => - ensureOwnerIsSender(fromBody(submitAttestationBody, bobFullDid.uri, aliceFullDid.uri)) - ).not.toThrow() + expect(() => ensureOwnerIsSender(fromBody(submitAttestationBody, bobFullDid.uri, aliceFullDid.uri))).not.toThrow() // Should not throw if the sender is the light DID version of the owner. // This is technically not to be allowed but message verification is not concerned with that. - expect(() => - ensureOwnerIsSender(fromBody(submitAttestationBody, bobLightDid.uri, aliceFullDid.uri)) - ).not.toThrow() + expect(() => ensureOwnerIsSender(fromBody(submitAttestationBody, bobLightDid.uri, aliceFullDid.uri))).not.toThrow() // Should throw if the sender and the owner are two different entities. - expect(() => - ensureOwnerIsSender(fromBody(submitAttestationBody, aliceFullDid.uri, bobFullDid.uri)) - ).toThrowError(SDKErrors.IdentityMismatchError) + expect(() => ensureOwnerIsSender(fromBody(submitAttestationBody, aliceFullDid.uri, bobFullDid.uri))).toThrowError( + SDKErrors.IdentityMismatchError + ) const submitClaimsForCTypeBody: ISubmitCredential = { content: [presentation], @@ -376,15 +368,11 @@ describe('Messaging', () => { // Should not throw if the owner has additional details and the sender does not. expect(() => - ensureOwnerIsSender( - fromBody(requestAttestationBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri) - ) + ensureOwnerIsSender(fromBody(requestAttestationBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri)) ).not.toThrow() // Should not throw if the sender is the full DID version of the owner. - expect(() => - ensureOwnerIsSender(fromBody(requestAttestationBody, aliceFullDid.uri, bobLightDid.uri)) - ).not.toThrow() + expect(() => ensureOwnerIsSender(fromBody(requestAttestationBody, aliceFullDid.uri, bobLightDid.uri))).not.toThrow() // Should throw if the sender and the owner are two different entities. expect(() => @@ -422,33 +410,25 @@ describe('Messaging', () => { } // Should not throw if the owner and sender DID is the same. - expect(() => - ensureOwnerIsSender(fromBody(submitAttestationBody, bobLightDid.uri, aliceLightDid.uri)) - ).not.toThrow() + expect(() => ensureOwnerIsSender(fromBody(submitAttestationBody, bobLightDid.uri, aliceLightDid.uri))).not.toThrow() // Should not throw if the owner has no additional details and the sender does. expect(() => - ensureOwnerIsSender( - fromBody(submitAttestationBody, bobLightDidWithDetails.uri, aliceLightDid.uri) - ) + ensureOwnerIsSender(fromBody(submitAttestationBody, bobLightDidWithDetails.uri, aliceLightDid.uri)) ).not.toThrow() // Should not throw if the owner has additional details and the sender does not. expect(() => - ensureOwnerIsSender( - fromBody(submitAttestationBodyWithEncodedDetails, bobLightDid.uri, aliceLightDid.uri) - ) + ensureOwnerIsSender(fromBody(submitAttestationBodyWithEncodedDetails, bobLightDid.uri, aliceLightDid.uri)) ).not.toThrow() // Should not throw if the sender is the full DID version of the owner. - expect(() => - ensureOwnerIsSender(fromBody(submitAttestationBody, bobFullDid.uri, aliceLightDid.uri)) - ).not.toThrow() + expect(() => ensureOwnerIsSender(fromBody(submitAttestationBody, bobFullDid.uri, aliceLightDid.uri))).not.toThrow() // Should throw if the sender and the owner are two different entities. - expect(() => - ensureOwnerIsSender(fromBody(submitAttestationBody, aliceLightDid.uri, bobLightDid.uri)) - ).toThrowError(SDKErrors.IdentityMismatchError) + expect(() => ensureOwnerIsSender(fromBody(submitAttestationBody, aliceLightDid.uri, bobLightDid.uri))).toThrowError( + SDKErrors.IdentityMismatchError + ) const submitClaimsForCTypeBody: ISubmitCredential = { content: [presentation], @@ -467,16 +447,12 @@ describe('Messaging', () => { // Should not throw if the owner has no additional details and the sender does. expect(() => - ensureOwnerIsSender( - fromBody(submitClaimsForCTypeBody, aliceLightDidWithDetails.uri, bobLightDid.uri) - ) + ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, aliceLightDidWithDetails.uri, bobLightDid.uri)) ).not.toThrow() // Should not throw if the owner has additional details and the sender does not. expect(() => - ensureOwnerIsSender( - fromBody(submitClaimsForCTypeBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri) - ) + ensureOwnerIsSender(fromBody(submitClaimsForCTypeBodyWithEncodedDetails, aliceLightDid.uri, bobLightDid.uri)) ).not.toThrow() // Should not throw if the sender is the full DID version of the owner. @@ -550,7 +526,6 @@ describe('Error checking / Verification', () => { let messageSubmitCredential: IMessage beforeAll(async () => { - await init() keyAlice = makeSigningKeyTool() @@ -608,7 +583,6 @@ describe('Error checking / Verification', () => { { didResolveKey } ) - // Submit Terms content submitTermsContent = { claim: { @@ -620,7 +594,6 @@ describe('Error checking / Verification', () => { cTypes: undefined, } - // Request Attestation Content requestAttestationContent = { credential: legitimation, @@ -688,8 +661,6 @@ describe('Error checking / Verification', () => { content: submitCredentialContent, type: 'submit-credential', } - - }) it('Checking required properties for given CType', () => { @@ -697,56 +668,42 @@ describe('Error checking / Verification', () => { SDKErrors.CTypeUnknownPropertiesError ) - expect(() => - verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties) - ).not.toThrowError(SDKErrors.CTypeUnknownPropertiesError) + expect(() => verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties)).not.toThrowError( + SDKErrors.CTypeUnknownPropertiesError + ) - expect(() => - verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties) - ).not.toThrowError() + expect(() => verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties)).not.toThrowError() }) beforeAll(async () => { - messageSubmitTerms = fromBody(submitTermsBody, identityAlice.uri, identityBob.uri) messageRequestAttestationForClaim = fromBody(requestAttestationBody, identityAlice.uri, identityBob.uri) messageSubmitAttestationForClaim = fromBody(submitAttestationBody, identityAlice.uri, identityBob.uri) - messageRejectAttestationForClaim = fromBody( - rejectAttestationForClaimBody, - identityAlice.uri, - identityBob.uri - ) + messageRejectAttestationForClaim = fromBody(rejectAttestationForClaimBody, identityAlice.uri, identityBob.uri) messageRequestCredential = fromBody(requestCredentialBody, identityAlice.uri, identityBob.uri) messageSubmitCredential = fromBody(submitCredentialBody, identityAlice.uri, identityBob.uri) - }) it('message body verifier should not throw errors on correct bodies', () => { + expect(() => verifyMessageBody(messageSubmitTerms)).not.toThrowError() - expect(() => verifyMessageBody(submitTermsBody)).not.toThrowError() - - expect(() => verifyMessageBody(requestAttestationBody)).not.toThrowError() - expect(() => verifyMessageBody(submitAttestationBody)).not.toThrowError() - expect(() => verifyMessageBody(rejectAttestationForClaimBody)).not.toThrowError() - expect(() => verifyMessageBody(requestCredentialBody)).not.toThrowError() - expect(() => verifyMessageBody(submitCredentialBody)).not.toThrowError() - + expect(() => verifyMessageBody(messageRequestAttestationForClaim)).not.toThrowError() + expect(() => verifyMessageBody(messageSubmitAttestationForClaim)).not.toThrowError() + expect(() => verifyMessageBody(messageRejectAttestationForClaim)).not.toThrowError() + expect(() => verifyMessageBody(messageRequestCredential)).not.toThrowError() + expect(() => verifyMessageBody(messageSubmitCredential)).not.toThrowError() }) - it('message envelope verifier should not throw errors on correct envelopes', () => { - expect(() => verifyMessageEnvelope(messageSubmitTerms)).not.toThrowError() expect(() => verifyMessageEnvelope(messageRequestAttestationForClaim)).not.toThrowError() expect(() => verifyMessageEnvelope(messageSubmitAttestationForClaim)).not.toThrowError() expect(() => verifyMessageEnvelope(messageRejectAttestationForClaim)).not.toThrowError() expect(() => verifyMessageEnvelope(messageRequestCredential)).not.toThrowError() expect(() => verifyMessageEnvelope(messageSubmitCredential)).not.toThrowError() - }) it('message envelope verifier should throw errors on faulty envelopes', () => { - // @ts-ignore messageSubmitTerms.sender = 'this is not a sender did' expect(() => verifyMessageEnvelope(messageSubmitTerms)).toThrowError(SDKErrors.InvalidDidFormatError) @@ -764,27 +721,29 @@ describe('Error checking / Verification', () => { expect(() => verifyMessageEnvelope(messageRequestCredential)).toThrowError(TypeError) }) it('message body verifier should throw errors on faulty bodies', () => { - submitTermsBody.content.delegationId = 'this is not a delegation id' - expect(() => verifyMessageBody(submitTermsBody)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(messageSubmitTerms)).toThrowError(SDKErrors.HashMalformedError) submitCredentialBody.content[0].claimerSignature = { signature: 'this is not the claimers signature', // @ts-ignore keyUri: 'this is not a key id', } - expect(() => verifyMessageBody(submitCredentialBody)).toThrowError() + expect(() => verifyMessageBody(messageSubmitCredential)).toThrowError() // @ts-ignore submitAttestationBody.content.attestation.claimHash = 'this is not the claim hash' - expect(() => verifyMessageBody(submitAttestationBody)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(messageSubmitAttestationForClaim)).toThrowError( + SDKErrors.UnknownMessageBodyTypeError + ) // @ts-ignore rejectAttestationForClaimBody.content = 'this is not the root hash' - expect(() => verifyMessageBody(rejectAttestationForClaimBody)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(messageRejectAttestationForClaim)).toThrowError( + SDKErrors.UnknownMessageBodyTypeError + ) // @ts-ignore requestCredentialBody.content.cTypes[0].cTypeHash = 'this is not a cTypeHash' - expect(() => verifyMessageBody(requestCredentialBody)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(messageRequestCredential)).toThrowError(SDKErrors.UnknownMessageBodyTypeError) - expect(() => verifyMessageBody({} as MessageBody)).toThrowError(SDKErrors.UnknownMessageBodyTypeError) + expect(() => verifyMessageBody({} as IMessage)).toThrowError(SDKErrors.UnknownMessageBodyTypeError) }) - }) diff --git a/src/messaging/MessageEnvelope.ts b/src/messaging/MessageEnvelope.ts index 67ed361..49a4af2 100644 --- a/src/messaging/MessageEnvelope.ts +++ b/src/messaging/MessageEnvelope.ts @@ -13,10 +13,10 @@ import { hexToU8a, stringToU8a, u8aToHex, u8aToString } from '@polkadot/util' import type { IEncryptedMessage, IEncryptedMessageContents, IMessage } from '../types' /** - * Checks if the message object is well-formed. - * - * @param message The message object. - */ + * Checks if the message object is well-formed. + * + * @param message The message object. + */ export function verifyMessageEnvelope(message: IMessage): void { const { messageId, createdAt, receiver, sender, receivedAt, inReplyTo } = message if (messageId !== undefined && typeof messageId !== 'string') { @@ -35,24 +35,23 @@ export function verifyMessageEnvelope(message: IMessage): void { } } - /** - * Symmetrically decrypts the result of [[encrypt]]. - * - * @param encrypted The encrypted message. - * @param decryptCallback The callback to decrypt with the secret key. - * @param decryptionOptions Options to perform the decryption operation. - * @param decryptionOptions.resolveKey The DID key resolver to use. - * @returns The original [[Message]]. - */ + * Symmetrically decrypts the result of [[encrypt]]. + * + * @param encrypted The encrypted message. + * @param decryptCallback The callback to decrypt with the secret key. + * @param decryptionOptions Options to perform the decryption operation. + * @param decryptionOptions.resolveKey The DID key resolver to use. + * @returns The original [[Message]]. + */ export async function decrypt( encrypted: IEncryptedMessage, decryptCallback: DecryptCallback, { resolveKey = Did.resolveKey, }: { - resolveKey?: DidResolveKey - } = {} + resolveKey?: DidResolveKey + } = {} ): Promise { const { senderKeyUri, receiverKeyUri, ciphertext, nonce, receivedAt } = encrypted @@ -103,16 +102,16 @@ export async function decrypt( } /** - * Encrypts the [[Message]] as a string. This can be reversed with [[decrypt]]. - * - * @param message The message to encrypt. - * @param encryptCallback The callback to encrypt with the secret key. - * @param receiverKeyUri The key URI of the receiver. - * @param encryptionOptions Options to perform the encryption operation. - * @param encryptionOptions.resolveKey The DID key resolver to use. - * - * @returns The encrypted version of the original [[Message]], see [[IEncryptedMessage]]. - */ + * Encrypts the [[Message]] as a string. This can be reversed with [[decrypt]]. + * + * @param message The message to encrypt. + * @param encryptCallback The callback to encrypt with the secret key. + * @param receiverKeyUri The key URI of the receiver. + * @param encryptionOptions Options to perform the encryption operation. + * @param encryptionOptions.resolveKey The DID key resolver to use. + * + * @returns The encrypted version of the original [[Message]], see [[IEncryptedMessage]]. + */ export async function encrypt( message: IMessage, encryptCallback: EncryptCallback, @@ -120,8 +119,8 @@ export async function encrypt( { resolveKey = Did.resolveKey, }: { - resolveKey?: DidResolveKey - } = {} + resolveKey?: DidResolveKey + } = {} ): Promise { const receiverKey = await resolveKey(receiverKeyUri, 'keyAgreement') if (message.receiver !== receiverKey.controller) { diff --git a/src/messaging/index.ts b/src/messaging/index.ts index cc19efe..c46e121 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -25,4 +25,4 @@ export * from './utils' export * from './MessageEnvelope' -export * from './CredentialApiMessageTypes' +export * from './CredentialApiMessageTypes' diff --git a/src/messaging/utils.ts b/src/messaging/utils.ts index cef217e..db56fc7 100644 --- a/src/messaging/utils.ts +++ b/src/messaging/utils.ts @@ -11,14 +11,14 @@ import { CType, SDKErrors } from '@kiltprotocol/sdk-js' import { UUID } from '@kiltprotocol/utils' /** - * Constructs a message from a message body. - * This should be encrypted with [[encrypt]] before sending to the receiver. - * - * @param body The body of the message. - * @param sender The DID of the sender. - * @param receiver The DID of the receiver. - * @returns The message created. - */ + * Constructs a message from a message body. + * This should be encrypted with [[encrypt]] before sending to the receiver. + * + * @param body The body of the message. + * @param sender The DID of the sender. + * @param receiver The DID of the receiver. + * @returns The message created. + */ export function fromBody(body: MessageBody, sender: IMessage['sender'], receiver: IMessage['receiver']): IMessage { return { body, @@ -29,13 +29,12 @@ export function fromBody(body: MessageBody, sender: IMessage['sender'], receiver } } - /** - * Verifies required properties for a given [[CType]] before sending or receiving a message. - * - * @param requiredProperties The list of required properties that need to be verified against a [[CType]]. - * @param cType A [[CType]] used to verify the properties. - */ + * Verifies required properties for a given [[CType]] before sending or receiving a message. + * + * @param requiredProperties The list of required properties that need to be verified against a [[CType]]. + * @param cType A [[CType]] used to verify the properties. + */ export function verifyRequiredCTypeProperties(requiredProperties: string[], cType: ICType): void { CType.verifyDataStructure(cType as ICType) diff --git a/src/quote/Quote.test.ts b/src/quote/Quote.test.ts index e63c420..333273e 100644 --- a/src/quote/Quote.test.ts +++ b/src/quote/Quote.test.ts @@ -23,10 +23,7 @@ import type { import { Crypto, SDKErrors } from '@kiltprotocol/utils' import { Credential, CType } from '@kiltprotocol/sdk-js' -import { - createLocalDemoFullDidFromKeypair, - makeSigningKeyTool, -} from '../tests' +import { createLocalDemoFullDidFromKeypair, makeSigningKeyTool } from '../tests' import * as Quote from './Quote' import { QuoteSchema } from './QuoteSchema' @@ -50,13 +47,9 @@ describe('Quote', () => { let invalidPropertiesQuote: IQuote let invalidCostQuote: IQuote - async function mockResolveKey( - keyUri: DidResourceUri - ): Promise { + async function mockResolveKey(keyUri: DidResourceUri): Promise { const { did } = Did.parse(keyUri) - const document = [claimerIdentity, attesterIdentity].find( - ({ uri }) => uri === did - ) + const document = [claimerIdentity, attesterIdentity].find(({ uri }) => uri === did) if (!document) throw new Error('Cannot resolve mocked DID') return Did.keyToResolvedKey(document.authentication[0], did) } @@ -153,9 +146,7 @@ describe('Quote', () => { ) expect(signature).toEqual(quoteBothAgreed.claimerSignature) - const { fragment: attesterKeyId } = Did.parse( - validAttesterSignedQuote.attesterSignature.keyUri - ) + const { fragment: attesterKeyId } = Did.parse(validAttesterSignedQuote.attesterSignature.keyUri) expect(() => Crypto.verify( @@ -170,8 +161,7 @@ describe('Quote', () => { }) ), validAttesterSignedQuote.attesterSignature.signature, - Did.getKey(attesterIdentity, attesterKeyId!)?.publicKey || - new Uint8Array() + Did.getKey(attesterIdentity, attesterKeyId!)?.publicKey || new Uint8Array() ) ).not.toThrow() await expect( @@ -184,19 +174,14 @@ describe('Quote', () => { didResolveKey: mockResolveKey, }) ).resolves.not.toThrow() - expect( - await Quote.createAttesterSignedQuote( - validQuoteData, - attester.getSignCallback(attesterIdentity) - ) - ).toEqual(validAttesterSignedQuote) + expect(await Quote.createAttesterSignedQuote(validQuoteData, attester.getSignCallback(attesterIdentity))).toEqual( + validAttesterSignedQuote + ) }) it('validates created quotes against QuoteSchema', () => { expect(Quote.validateQuoteSchema(QuoteSchema, validQuoteData)).toBe(true) expect(Quote.validateQuoteSchema(QuoteSchema, invalidCostQuote)).toBe(false) - expect(Quote.validateQuoteSchema(QuoteSchema, invalidPropertiesQuote)).toBe( - false - ) + expect(Quote.validateQuoteSchema(QuoteSchema, invalidPropertiesQuote)).toBe(false) }) it('detects tampering', async () => { @@ -223,8 +208,7 @@ describe('Quote', () => { it('complains if attesterDid does not match attester signature', async () => { const sign = claimer.getSignCallback(claimerIdentity) // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { attesterSignature, ...attesterSignedQuote } = - validAttesterSignedQuote + const { attesterSignature, ...attesterSignedQuote } = validAttesterSignedQuote const wrongSignerAttester: IQuoteAttesterSigned = { ...attesterSignedQuote, attesterSignature: Did.signatureToJson( diff --git a/src/quote/Quote.ts b/src/quote/Quote.ts index 654e8f8..d92c7bf 100644 --- a/src/quote/Quote.ts +++ b/src/quote/Quote.ts @@ -25,28 +25,19 @@ import type { DidUri, } from '@kiltprotocol/types' import { Crypto, JsonSchema, SDKErrors } from '@kiltprotocol/utils' -import { - resolveKey, - verifyDidSignature, - signatureToJson, - signatureFromJson, -} from '@kiltprotocol/did' +import { resolveKey, verifyDidSignature, signatureToJson, signatureFromJson } from '@kiltprotocol/did' import { QuoteSchema } from './QuoteSchema' /** - * Validates the quote against the meta schema and quote data against the provided schema. - * - * @param schema A [[Quote]] schema object. - * @param validate [[Quote]] data to be validated against the provided schema. - * @param messages The errors messages are listed in an array. - * - * @returns Whether the quote schema is valid. - */ -export function validateQuoteSchema( - schema: JsonSchema.Schema, - validate: unknown, - messages?: string[] -): boolean { + * Validates the quote against the meta schema and quote data against the provided schema. + * + * @param schema A [[Quote]] schema object. + * @param validate [[Quote]] data to be validated against the provided schema. + * @param messages The errors messages are listed in an array. + * + * @returns Whether the quote schema is valid. + */ +export function validateQuoteSchema(schema: JsonSchema.Schema, validate: unknown, messages?: string[]): boolean { const validator = new JsonSchema.Validator(schema) if (schema.$id !== QuoteSchema.$id) { validator.addSchema(QuoteSchema) @@ -63,16 +54,13 @@ export function validateQuoteSchema( // TODO: should have a "create quote" function. /** - * Signs a [[Quote]] object as an Attester. - * - * @param quoteInput A [[Quote]] object. - * @param sign The callback to sign with the private key. - * @returns A signed [[Quote]] object. - */ -export async function createAttesterSignedQuote( - quoteInput: IQuote, - sign: SignCallback -): Promise { + * Signs a [[Quote]] object as an Attester. + * + * @param quoteInput A [[Quote]] object. + * @param sign The callback to sign with the private key. + * @returns A signed [[Quote]] object. + */ +export async function createAttesterSignedQuote(quoteInput: IQuote, sign: SignCallback): Promise { if (!validateQuoteSchema(QuoteSchema, quoteInput)) { throw new SDKErrors.QuoteUnverifiableError() } @@ -89,19 +77,19 @@ export async function createAttesterSignedQuote( } /** - * Verifies a [[IQuoteAttesterSigned]] object. - * - * @param quote The object which to be verified. - * @param options Optional settings. - * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. - */ + * Verifies a [[IQuoteAttesterSigned]] object. + * + * @param quote The object which to be verified. + * @param options Optional settings. + * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. + */ export async function verifyAttesterSignedQuote( quote: IQuoteAttesterSigned, { didResolveKey = resolveKey, }: { - didResolveKey?: DidResolveKey - } = {} + didResolveKey?: DidResolveKey + } = {} ): Promise { const { attesterSignature, ...basicQuote } = quote await verifyDidSignature({ @@ -119,16 +107,16 @@ export async function verifyAttesterSignedQuote( } /** - * Creates a [[Quote]] signed by the Attester and the Claimer. - * - * @param attesterSignedQuote A [[Quote]] object signed by an Attester. - * @param credentialRootHash A root hash of the entire object. - * @param sign The callback to sign with the private key. - * @param claimerDid The DID of the Claimer, who has to sign. - * @param options Optional settings. - * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. - * @returns A [[Quote]] agreement signed by both the Attester and Claimer. - */ + * Creates a [[Quote]] signed by the Attester and the Claimer. + * + * @param attesterSignedQuote A [[Quote]] object signed by an Attester. + * @param credentialRootHash A root hash of the entire object. + * @param sign The callback to sign with the private key. + * @param claimerDid The DID of the Claimer, who has to sign. + * @param options Optional settings. + * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. + * @returns A [[Quote]] agreement signed by both the Attester and Claimer. + */ export async function createQuoteAgreement( attesterSignedQuote: IQuoteAttesterSigned, credentialRootHash: ICredential['rootHash'], @@ -137,8 +125,8 @@ export async function createQuoteAgreement( { didResolveKey = resolveKey, }: { - didResolveKey?: DidResolveKey - } = {} + didResolveKey?: DidResolveKey + } = {} ): Promise { const { attesterSignature, ...basicQuote } = attesterSignedQuote @@ -167,30 +155,27 @@ export async function createQuoteAgreement( } /** - * Verifies a [[IQuoteAgreement]] object. - * - * @param quote The object to be verified. - * @param options Optional settings. - * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. - */ + * Verifies a [[IQuoteAgreement]] object. + * + * @param quote The object to be verified. + * @param options Optional settings. + * @param options.didResolveKey Resolve function used in the process of verifying the attester signature. + */ export async function verifyQuoteAgreement( quote: IQuoteAgreement, { didResolveKey = resolveKey, }: { - didResolveKey?: DidResolveKey - } = {} + didResolveKey?: DidResolveKey + } = {} ): Promise { - const { claimerSignature, claimerDid, rootHash, ...attesterSignedQuote } = - quote + const { claimerSignature, claimerDid, rootHash, ...attesterSignedQuote } = quote // verify attester signature await verifyAttesterSignedQuote(attesterSignedQuote, { didResolveKey }) // verify claimer signature await verifyDidSignature({ ...signatureFromJson(claimerSignature), - message: Crypto.hashStr( - Crypto.encodeObjectAsStr({ ...attesterSignedQuote, claimerDid, rootHash }) - ), + message: Crypto.hashStr(Crypto.encodeObjectAsStr({ ...attesterSignedQuote, claimerDid, rootHash })), expectedSigner: claimerDid, expectedVerificationMethod: 'authentication', didResolveKey, diff --git a/src/quote/QuoteSchema.ts b/src/quote/QuoteSchema.ts index d7d0d93..6d874e6 100644 --- a/src/quote/QuoteSchema.ts +++ b/src/quote/QuoteSchema.ts @@ -45,12 +45,5 @@ export const QuoteSchema: JsonSchema.Schema = { format: 'date-time', }, }, - required: [ - 'attesterDid', - 'cTypeHash', - 'cost', - 'currency', - 'termsAndConditions', - 'timeframe', - ], + required: ['attesterDid', 'cTypeHash', 'cost', 'currency', 'termsAndConditions', 'timeframe'], } diff --git a/src/tests/messageUtils.ts b/src/tests/messageUtils.ts index ea91e64..0b04cb1 100644 --- a/src/tests/messageUtils.ts +++ b/src/tests/messageUtils.ts @@ -9,20 +9,12 @@ import { DidKey, DidVerificationKey, DecryptCallback, - EncryptCallback } from '@kiltprotocol/types' + EncryptCallback, +} from '@kiltprotocol/types' -import { - Did, - SignCallback, -} from '@kiltprotocol/sdk-js' +import { Did, SignCallback } from '@kiltprotocol/sdk-js' import { Crypto } from '@kiltprotocol/utils' -import { - blake2AsU8a, - blake2AsHex, -} from '@polkadot/util-crypto' - - - +import { blake2AsU8a, blake2AsHex } from '@polkadot/util-crypto' /** * Generates a callback that can be used for signing. @@ -36,9 +28,7 @@ export function makeSignCallback(keypair: KeyringPair): KeyToolSignCallback { const keyId = didDocument[keyRelationship]?.[0].id const keyType = didDocument[keyRelationship]?.[0].type if (keyId === undefined || keyType === undefined) { - throw new Error( - `Key for purpose "${keyRelationship}" not found in did "${didDocument.uri}"` - ) + throw new Error(`Key for purpose "${keyRelationship}" not found in did "${didDocument.uri}"`) } const signature = keypair.sign(data, { withType: false }) @@ -51,14 +41,12 @@ export function makeSignCallback(keypair: KeyringPair): KeyToolSignCallback { } /** - * Generates a callback that can be used for signing. - * - * @param keypair The keypair to use for signing. - * @returns The callback. - */ -export function makeStoreDidCallback( - keypair: KiltKeyringPair -): StoreDidCallback { + * Generates a callback that can be used for signing. + * + * @param keypair The keypair to use for signing. + * @returns The callback. + */ +export function makeStoreDidCallback(keypair: KiltKeyringPair): StoreDidCallback { return async function sign({ data }) { const signature = keypair.sign(data, { withType: false }) return { @@ -68,16 +56,13 @@ export function makeStoreDidCallback( } } - /** - * Generates a keypair usable for signing and a few related values. - * - * @param type The type to use for the keypair. - * @returns The keypair, matching sign callback, a key usable as DID authentication key. - */ -export function makeSigningKeyTool( - type: KiltKeyringPair['type'] = 'sr25519' -): KeyTool { + * Generates a keypair usable for signing and a few related values. + * + * @param type The type to use for the keypair. + * @returns The keypair, matching sign callback, a key usable as DID authentication key. + */ +export function makeSigningKeyTool(type: KiltKeyringPair['type'] = 'sr25519'): KeyTool { const keypair = Crypto.makeKeypairFromSeed(undefined, type) const getSignCallback = makeSignCallback(keypair) const storeDidCallback = makeStoreDidCallback(keypair) @@ -90,17 +75,14 @@ export function makeSigningKeyTool( } } - /** - * Creates a full DID from a light DID where the verification keypair is enabled for all verification purposes (authentication, assertionMethod, capabilityDelegation). - * This is not recommended, use for demo purposes only! - * - * @param lightDid The light DID whose keys will be used on the full DID. - * @returns A full DID instance that is not yet written to the blockchain. - */ -export async function createLocalDemoFullDidFromLightDid( - lightDid: DidDocument -): Promise { + * Creates a full DID from a light DID where the verification keypair is enabled for all verification purposes (authentication, assertionMethod, capabilityDelegation). + * This is not recommended, use for demo purposes only! + * + * @param lightDid The light DID whose keys will be used on the full DID. + * @returns A full DID instance that is not yet written to the blockchain. + */ +export async function createLocalDemoFullDidFromLightDid(lightDid: DidDocument): Promise { const { uri, authentication } = lightDid return { @@ -112,23 +94,16 @@ export async function createLocalDemoFullDidFromLightDid( } } - /** - * Generates a callback that can be used for decryption. - * - * @param secretKey The options parameter. - * @param secretKey.secretKey The key to use for decryption. - * @returns The callback. - */ -export function makeDecryptCallback({ - secretKey, -}: KiltEncryptionKeypair): DecryptCallback { + * Generates a callback that can be used for decryption. + * + * @param secretKey The options parameter. + * @param secretKey.secretKey The key to use for decryption. + * @returns The callback. + */ +export function makeDecryptCallback({ secretKey }: KiltEncryptionKeypair): DecryptCallback { return async function decryptCallback({ data, nonce, peerPublicKey }) { - const decrypted = Crypto.decryptAsymmetric( - { box: data, nonce }, - peerPublicKey, - secretKey - ) + const decrypted = Crypto.decryptAsymmetric({ box: data, nonce }, peerPublicKey, secretKey) if (decrypted === false) throw new Error('Decryption failed') return { data: decrypted } } @@ -141,33 +116,23 @@ export function makeDecryptCallback({ * @returns EncryptResponseData * * */ -export type EncryptionKeyToolCallback = ( - didDocument: DidDocument - ) => EncryptCallback - - +export type EncryptionKeyToolCallback = (didDocument: DidDocument) => EncryptCallback /** - * Generates a callback that can be used for encryption. - * - * @param secretKey The options parameter. - * @param secretKey.secretKey The key to use for encryption. - * @returns The callback. - */ -export function makeEncryptCallback({ - secretKey, -}: KiltEncryptionKeypair): EncryptionKeyToolCallback { + * Generates a callback that can be used for encryption. + * + * @param secretKey The options parameter. + * @param secretKey.secretKey The key to use for encryption. + * @returns The callback. + */ +export function makeEncryptCallback({ secretKey }: KiltEncryptionKeypair): EncryptionKeyToolCallback { return (didDocument) => { return async function encryptCallback({ data, peerPublicKey }) { const keyId = didDocument.keyAgreement?.[0].id if (!keyId) { throw new Error(`Encryption key not found in did "${didDocument.uri}"`) } - const { box, nonce } = Crypto.encryptAsymmetric( - data, - peerPublicKey, - secretKey - ) + const { box, nonce } = Crypto.encryptAsymmetric(data, peerPublicKey, secretKey) return { // used nonce for encryption nonce, @@ -185,19 +150,19 @@ export function makeEncryptCallback({ */ export interface EncryptionKeyTool { // used keys for encrypt and decrypt. - keyAgreement: [KiltEncryptionKeypair] - // callback to encrypt message. - encrypt: EncryptionKeyToolCallback - // callback to decrypt messages - decrypt: DecryptCallback - } + keyAgreement: [KiltEncryptionKeypair] + // callback to encrypt message. + encrypt: EncryptionKeyToolCallback + // callback to decrypt messages + decrypt: DecryptCallback +} /** - * Generates a keypair suitable for encryption. - * - * @param seed {string} Input to generate the keypair from. - * @returns Object with secret and public key and the key type. - */ + * Generates a keypair suitable for encryption. + * + * @param seed {string} Input to generate the keypair from. + * @returns Object with secret and public key and the key type. + */ export function makeEncryptionKeyTool(seed: string): EncryptionKeyTool { const keypair = Crypto.makeEncryptionKeypairFromSeed(blake2AsU8a(seed, 256)) @@ -216,17 +181,13 @@ export function computeKeyId(key: DidKey['publicKey']): DidKey['id'] { return `#${blake2AsHex(key, 256)}` } - /** * Creates a DidKey by providing the publicKey. * * @param KiltKeyringPair The public key and the used public-key-concept. * @returns DidVerificationKey */ -function makeDidKeyFromKeypair({ - publicKey, - type, -}: KiltKeyringPair): DidVerificationKey { +function makeDidKeyFromKeypair({ publicKey, type }: KiltKeyringPair): DidVerificationKey { return { id: computeKeyId(publicKey), publicKey, @@ -235,28 +196,24 @@ function makeDidKeyFromKeypair({ } /** - * Creates [[DidDocument]] for local use, e.g., in testing. Will not work on-chain because key IDs are generated ad-hoc. - * - * @param keypair The KeyringPair for authentication key, other keys derived from it. - * @param generationOptions The additional options for generation. - * @param generationOptions.keyRelationships The set of key relationships to indicate which keys must be added to the DID. - * @param generationOptions.endpoints The set of service endpoints that must be added to the DID. - * - * @returns A promise resolving to a [[DidDocument]] object. The resulting object is NOT stored on chain. - */ + * Creates [[DidDocument]] for local use, e.g., in testing. Will not work on-chain because key IDs are generated ad-hoc. + * + * @param keypair The KeyringPair for authentication key, other keys derived from it. + * @param generationOptions The additional options for generation. + * @param generationOptions.keyRelationships The set of key relationships to indicate which keys must be added to the DID. + * @param generationOptions.endpoints The set of service endpoints that must be added to the DID. + * + * @returns A promise resolving to a [[DidDocument]] object. The resulting object is NOT stored on chain. + */ export async function createLocalDemoFullDidFromKeypair( keypair: KiltKeyringPair, { - keyRelationships = new Set([ - 'assertionMethod', - 'capabilityDelegation', - 'keyAgreement', - ]), + keyRelationships = new Set(['assertionMethod', 'capabilityDelegation', 'keyAgreement']), endpoints = [], }: { - keyRelationships?: Set> - endpoints?: DidServiceEndpoint[] - } = {} + keyRelationships?: Set> + endpoints?: DidServiceEndpoint[] + } = {} ): Promise { const authKey = makeDidKeyFromKeypair(keypair) const uri = Did.getFullDidUriFromKey(authKey) @@ -268,8 +225,7 @@ export async function createLocalDemoFullDidFromKeypair( } if (keyRelationships.has('keyAgreement')) { - const encryptionKeypair = makeEncryptionKeyTool(`${keypair.publicKey}//enc`) - .keyAgreement[0] + const encryptionKeypair = makeEncryptionKeyTool(`${keypair.publicKey}//enc`).keyAgreement[0] // encryption key with public key, private key, type, and id. const encKey = { @@ -279,15 +235,11 @@ export async function createLocalDemoFullDidFromKeypair( result.keyAgreement = [encKey] } if (keyRelationships.has('assertionMethod')) { - const attKey = makeDidKeyFromKeypair( - keypair.derive('//att') as KiltKeyringPair - ) + const attKey = makeDidKeyFromKeypair(keypair.derive('//att') as KiltKeyringPair) result.assertionMethod = [attKey] } if (keyRelationships.has('capabilityDelegation')) { - const delKey = makeDidKeyFromKeypair( - keypair.derive('//del') as KiltKeyringPair - ) + const delKey = makeDidKeyFromKeypair(keypair.derive('//del') as KiltKeyringPair) result.capabilityDelegation = [delKey] } @@ -295,11 +247,11 @@ export async function createLocalDemoFullDidFromKeypair( } export type KeyToolSignCallback = (didDocument: DidDocument) => SignCallback - type StoreDidCallback = Parameters['2'] +type StoreDidCallback = Parameters['2'] export interface KeyTool { - keypair: KiltKeyringPair - getSignCallback: KeyToolSignCallback - storeDidCallback: StoreDidCallback - authentication: [NewLightDidVerificationKey] - } + keypair: KiltKeyringPair + getSignCallback: KeyToolSignCallback + storeDidCallback: StoreDidCallback + authentication: [NewLightDidVerificationKey] +} diff --git a/src/types/Message.ts b/src/types/Message.ts index b6ff356..f9de4d7 100644 --- a/src/types/Message.ts +++ b/src/types/Message.ts @@ -30,7 +30,7 @@ export type MessageBodyType = | 'submit-credential' | 'reject-terms' -interface IMessageBodyBase { +export interface IMessageBodyBase { content: Content type: Type } @@ -46,15 +46,15 @@ interface IMessageBodyBase { * - `inReplyTo` - The id of the parent-message. * - `references` - The references or the in-reply-to of the parent-message followed by the message-id of the parent-message. */ -export interface IMessage { - body: MessageBody +export interface IMessage { + body: Body createdAt: number sender: DidUri receiver: DidUri messageId?: string receivedAt?: number - inReplyTo?: IMessage['messageId'] - references?: Array + inReplyTo?: IMessage['messageId'] + references?: Array['messageId']> } /** @@ -182,7 +182,7 @@ export type IConfirmPayment = IMessageBodyBase<'confirm-payment', IConfirmPaymen /** * Everything which is part of the encrypted and protected part of the [[IMessage]]. */ -export type IEncryptedMessageContents = Omit +export type IEncryptedMessageContents = Omit, 'receivedAt'> /** * Removes the plaintext [[IEncryptedMessageContents]] from an [[IMessage]] and instead includes them in encrypted form. @@ -192,7 +192,7 @@ export type IEncryptedMessageContents = Omit * - `receiverKeyUri` - The URI of the receiver's encryption key. * - `senderKeyUri` - The URI of the sender's encryption key. */ -export type IEncryptedMessage = Pick & { +export type IEncryptedMessage = Pick, 'receivedAt'> & { receiverKeyUri: DidResourceUri senderKeyUri: DidResourceUri ciphertext: string diff --git a/src/utils/TypeGuards.ts b/src/utils/TypeGuards.ts index db295c8..322a19e 100644 --- a/src/utils/TypeGuards.ts +++ b/src/utils/TypeGuards.ts @@ -1,7 +1,9 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { ICredentialPresentation } from '@kiltprotocol/types' +import { IAttestation, ICredentialPresentation } from '@kiltprotocol/types' import type { + IMessage, + IMessageBodyBase, IRejectAttestation, IRequestAttestation, IRequestCredential, @@ -9,121 +11,166 @@ import type { ISubmitAttestation, ISubmitCredential, ISubmitTerms, - MessageBody, } from '../types' -export function isSubmitTerms(body: MessageBody): body is ISubmitTerms { +export function isIMessage(message: any): message is IMessage { return ( - body.type === 'submit-terms' && - typeof body === 'object' && - 'content' in body && - 'claim' in body.content && - 'legitimations' in body.content && - (typeof body.content.legitimations === 'undefined' || Array.isArray(body.content.legitimations)) && - (typeof body.content.delegationId === 'undefined' || typeof body.content.delegationId === 'string') && - (typeof body.content.quote === 'undefined' || typeof body.content.quote === 'object') && - (typeof body.content.cTypes === 'undefined' || Array.isArray(body.content.cTypes)) + typeof message === 'object' && + 'body' in message && + 'type' in message.body && + 'createdAt' in message && + 'sender' in message && + 'receiver' in message && + typeof message.createdAt === 'number' && + typeof message.sender === 'string' && + typeof message.receiver === 'string' && + (typeof message.messageId === 'undefined' || typeof message.messageId === 'string') && + (typeof message.receivedAt === 'undefined' || typeof message.receivedAt === 'number') && + (typeof message.inReplyTo === 'undefined' || typeof message.inReplyTo === 'string') && + (Array.isArray(message.references) || typeof message.references === 'undefined') ) } -export function isRequestAttestation(body: MessageBody): body is IRequestAttestation { +export function isSubmitTerms( + message: IMessage<{ type: string; content: unknown }> +): message is IMessage { + if ( + !isIMessage(message) || + message.body.type !== 'submit-terms' || + typeof message.body.content !== 'object' || + message.body.content === null + ) { + return false + } + + const { claim, legitimations, delegationId, quote, cTypes } = message.body.content as ISubmitTerms['content'] + return ( - body.type === 'request-attestation' && - typeof body === 'object' && - 'credential' in body.content && - typeof body.content.credential === 'object' && - (typeof body.content.quote === 'undefined' || typeof body.content.quote === 'object') + claim !== undefined && + legitimations !== undefined && + (legitimations === undefined || Array.isArray(legitimations)) && + (delegationId === undefined || typeof delegationId === 'string') && + (quote === undefined || typeof quote === 'object') && + (cTypes === undefined || Array.isArray(cTypes)) ) } +export function isSubmitAttestation( + message: IMessage<{ type: string; content: unknown }> +): message is IMessage { + if (!isIMessage(message) || message.body.type !== 'submit-attestation') { + return false + } + + const content = message.body.content as ISubmitAttestation['content'] -export function isSubmitAttestation(body: MessageBody): body is ISubmitAttestation { return ( - body.type === 'submit-attestation' && - typeof body === 'object' && - 'content' in body && - typeof body.content === 'object' && - 'attestation' in body.content && - typeof body.content.attestation === 'object' + typeof content === 'object' && content !== null && 'attestation' in content && isIAttestation(content.attestation) + ) +} + +export function isIAttestation(body: any): body is IAttestation { + if (typeof body !== 'object') { + return false + } + + const { claimHash, cTypeHash, owner, delegationId, revoked } = body + + return ( + typeof claimHash === 'string' && + typeof cTypeHash === 'string' && + typeof owner === 'string' && + (delegationId === null || typeof delegationId === 'string') && + typeof revoked === 'boolean' ) } -export function isRejectAttestation(body: MessageBody): body is IRejectAttestation { +export function isRejectAttestation( + message: IMessage<{ type: string; content: unknown }> +): message is IMessage { return ( - body.type === 'reject-attestation' && - typeof body === 'object' && - 'content' in body && - typeof body.content === 'string' + isIMessage(message) && + message.body.type === 'reject-attestation' && + typeof message.body === 'object' && + 'content' in message.body && + typeof message.body.content === 'string' ) } +export function isRequestAttestation(message: IMessage): message is IMessage { + if (!isIMessage(message) || !('content' in message.body)) { + return false + } + const content = message.body.content as IRequestAttestation['content'] + return ( + message.body.type === 'request-attestation' && + 'credential' in content && + typeof content.credential === 'object' && + (typeof content.quote === 'undefined' || typeof content.quote === 'object') + ) +} -export function isIRequestCredential(body: MessageBody): body is IRequestCredential { +export function isIRequestCredential( + message: IMessage<{ type: string; content: unknown }> +): message is IMessage { return ( - typeof body === 'object' && - body !== null && - 'type' in body && - body.type === 'request-credential' && - 'content' in body && - isIRequestCredentialContent(body.content) + isIMessage(message) && + message.body.type === 'request-credential' && + isIRequestCredentialContent(message.body.content) ) } export function isIRequestCredentialContent(body: any): body is IRequestCredentialContent { if ( typeof body !== 'object' || - body === null || - !Array.isArray(body.cTypes) || - !body.cTypes.every((cType : any) => + body === null || + !Array.isArray(body.cTypes) || + !body.cTypes.every( + (cType: any) => typeof cType === 'object' && cType !== null && 'cTypeHash' in cType && typeof cType.cTypeHash === 'string' && (typeof cType.trustedAttesters === 'undefined' || Array.isArray(cType.trustedAttesters)) && (typeof cType.requiredProperties === 'undefined' || Array.isArray(cType.requiredProperties)) - ) + ) ) { return false } - if ('challenge' in body && typeof body.challenge !== 'undefined' && typeof body.challenge !== 'string') { + if ('challenge' in body && typeof body.challenge !== 'undefined' && typeof body.challenge !== 'string') { return false } return true } -export function isSubmitCredential(body: MessageBody): body is ISubmitCredential { +export function isSubmitCredential( + message: IMessage<{ type: string; content: unknown }> +): message is IMessage { return ( - typeof body === 'object' && - body !== null && - 'type' in body && - body.type === 'submit-credential' && - 'content' in body && - Array.isArray(body.content) && - body.content.every(isICredentialPresentation) + isIMessage(message) && + message.body.type === 'submit-credential' && + Array.isArray(message.body.content) && + message.body.content.every(isICredentialPresentation) ) } function isICredentialPresentation(body: any): body is ICredentialPresentation { return ( typeof body === 'object' && - body !== null && - 'claimerSignature' in body && - typeof body.claimerSignature === 'object' && - 'claim' in body && - 'claimNonceMap' in body && - 'claimHashes' in body && - 'delegationId' in body && - (body.delegationId === null || typeof body.delegationId === 'string') && - 'legitimations' in body && - Array.isArray(body.legitimations) && - 'rootHash' in body && - typeof body.rootHash === 'string' && - ('challenge' in body.claimerSignature ? typeof body.claimerSignature.challenge === 'string' : true) + body !== null && + 'claimerSignature' in body && + typeof body.claimerSignature === 'object' && + 'claim' in body && + 'claimNonceMap' in body && + 'claimHashes' in body && + 'delegationId' in body && + (body.delegationId === null || typeof body.delegationId === 'string') && + 'legitimations' in body && + Array.isArray(body.legitimations) && + 'rootHash' in body && + typeof body.rootHash === 'string' && + ('challenge' in body.claimerSignature ? typeof body.claimerSignature.challenge === 'string' : true) ) } - - - - diff --git a/yarn.lock b/yarn.lock index 652453e..f974311 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4,7 +4,7 @@ "@ampproject/remapping@^2.2.0": version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz" integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== dependencies: "@jridgewell/gen-mapping" "^0.3.0" @@ -12,19 +12,19 @@ "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4": version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz" integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== dependencies: "@babel/highlight" "^7.18.6" "@babel/compat-data@^7.21.4": version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.4.tgz#457ffe647c480dff59c2be092fc3acf71195c87f" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.21.4.tgz" integrity sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g== -"@babel/core@^7.11.6", "@babel/core@^7.12.3": +"@babel/core@^7.0.0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.8.0", "@babel/core@>=7.0.0-beta.0 <8": version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.4.tgz#c6dc73242507b8e2a27fd13a9c1814f9fa34a659" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.21.4.tgz" integrity sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA== dependencies: "@ampproject/remapping" "^2.2.0" @@ -45,7 +45,7 @@ "@babel/generator@^7.21.4", "@babel/generator@^7.7.2": version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.4.tgz#64a94b7448989f421f919d5239ef553b37bb26bc" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.21.4.tgz" integrity sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA== dependencies: "@babel/types" "^7.21.4" @@ -55,7 +55,7 @@ "@babel/helper-compilation-targets@^7.21.4": version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz#770cd1ce0889097ceacb99418ee6934ef0572656" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz" integrity sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg== dependencies: "@babel/compat-data" "^7.21.4" @@ -66,12 +66,12 @@ "@babel/helper-environment-visitor@^7.18.9": version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz" integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== "@babel/helper-function-name@^7.21.0": version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz" integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== dependencies: "@babel/template" "^7.20.7" @@ -79,21 +79,21 @@ "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz" integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== dependencies: "@babel/types" "^7.18.6" "@babel/helper-module-imports@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz" integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== dependencies: "@babel/types" "^7.18.6" "@babel/helper-module-transforms@^7.21.2": version "7.21.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz#160caafa4978ac8c00ac66636cb0fa37b024e2d2" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz" integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ== dependencies: "@babel/helper-environment-visitor" "^7.18.9" @@ -107,41 +107,41 @@ "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.8.0": version "7.19.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz#4796bb14961521f0f8715990bee2fb6e51ce21bf" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz" integrity sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw== "@babel/helper-simple-access@^7.20.2": version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz" integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== dependencies: "@babel/types" "^7.20.2" "@babel/helper-split-export-declaration@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + 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== dependencies: "@babel/types" "^7.18.6" "@babel/helper-string-parser@^7.19.4": version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz" integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== "@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== "@babel/helper-validator-option@^7.21.0": version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz" integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== "@babel/helpers@^7.21.0": version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.21.0.tgz" integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== dependencies: "@babel/template" "^7.20.7" @@ -150,7 +150,7 @@ "@babel/highlight@^7.18.6": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== dependencies: "@babel/helper-validator-identifier" "^7.18.6" @@ -159,103 +159,103 @@ "@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.4": version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.4.tgz#94003fdfc520bbe2875d4ae557b43ddb6d880f17" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.21.4.tgz" integrity sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-bigint@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz" integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-class-properties@^7.8.3": version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz" integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== dependencies: "@babel/helper-plugin-utils" "^7.12.13" "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz" integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz" integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz" integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-numeric-separator@^7.8.3": version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz" integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-optional-chaining@^7.8.3": version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz" integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: "@babel/helper-plugin-utils" "^7.8.0" "@babel/plugin-syntax-top-level-await@^7.8.3": version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz" integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-typescript@^7.7.2": version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz" integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== dependencies: "@babel/helper-plugin-utils" "^7.18.6" "@babel/template@^7.20.7", "@babel/template@^7.3.3": version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz" integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== dependencies: "@babel/code-frame" "^7.18.6" @@ -264,7 +264,7 @@ "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.21.4", "@babel/traverse@^7.7.2": version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.4.tgz#a836aca7b116634e97a6ed99976236b3282c9d36" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.21.4.tgz" integrity sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q== dependencies: "@babel/code-frame" "^7.21.4" @@ -280,7 +280,7 @@ "@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.21.4", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.4.tgz#2d5d6bb7908699b3b416409ffd3b5daa25b030d4" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.21.4.tgz" integrity sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA== dependencies: "@babel/helper-string-parser" "^7.19.4" @@ -289,24 +289,24 @@ "@balena/dockerignore@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" + resolved "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz" integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q== "@bcoe/v8-coverage@^0.2.3": version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + resolved "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== "@cspotcode/source-map-support@^0.8.0": version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + resolved "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz" integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== dependencies: "@jridgewell/trace-mapping" "0.3.9" "@eslint/eslintrc@^1.3.2": version "1.3.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.2.tgz#58b69582f3b7271d8fa67fe5251767a5b38ea356" + resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz" integrity sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ== dependencies: ajv "^6.12.4" @@ -321,7 +321,7 @@ "@humanwhocodes/config-array@^0.10.5": version "0.10.7" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.7.tgz#6d53769fd0c222767e6452e8ebda825c22e9f0dc" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz" integrity sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w== dependencies: "@humanwhocodes/object-schema" "^1.2.1" @@ -330,22 +330,22 @@ "@humanwhocodes/gitignore-to-minimatch@^1.0.2": version "1.0.2" - resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" + resolved "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz" integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== "@humanwhocodes/module-importer@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== "@istanbuljs/load-nyc-config@^1.0.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + resolved "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz" integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== dependencies: camelcase "^5.3.1" @@ -356,12 +356,12 @@ "@istanbuljs/schema@^0.1.2": version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + resolved "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== "@jest/console@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-28.1.3.tgz#2030606ec03a18c31803b8a36382762e447655df" + resolved "https://registry.npmjs.org/@jest/console/-/console-28.1.3.tgz" integrity sha512-QPAkP5EwKdK/bxIr6C1I4Vs0rm2nHiANzj/Z5X2JQkrZo6IqvC4ldZ9K95tF0HdidhA8Bo6egxSzUFPYKcEXLw== dependencies: "@jest/types" "^28.1.3" @@ -373,7 +373,7 @@ "@jest/core@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-28.1.3.tgz#0ebf2bd39840f1233cd5f2d1e6fc8b71bd5a1ac7" + resolved "https://registry.npmjs.org/@jest/core/-/core-28.1.3.tgz" integrity sha512-CIKBrlaKOzA7YG19BEqCw3SLIsEwjZkeJzf5bdooVnW4bH5cktqe3JX+G2YV1aK5vP8N9na1IGWFzYaTp6k6NA== dependencies: "@jest/console" "^28.1.3" @@ -408,7 +408,7 @@ "@jest/environment@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-28.1.3.tgz#abed43a6b040a4c24fdcb69eab1f97589b2d663e" + resolved "https://registry.npmjs.org/@jest/environment/-/environment-28.1.3.tgz" integrity sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA== dependencies: "@jest/fake-timers" "^28.1.3" @@ -418,14 +418,14 @@ "@jest/expect-utils@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + resolved "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.3.tgz" integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== dependencies: jest-get-type "^28.0.2" "@jest/expect@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-28.1.3.tgz#9ac57e1d4491baca550f6bdbd232487177ad6a72" + resolved "https://registry.npmjs.org/@jest/expect/-/expect-28.1.3.tgz" integrity sha512-lzc8CpUbSoE4dqT0U+g1qODQjBRHPpCPXissXD4mS9+sWQdmmpeJ9zSH1rS1HEkrsMN0fb7nKrJ9giAR1d3wBw== dependencies: expect "^28.1.3" @@ -433,7 +433,7 @@ "@jest/fake-timers@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-28.1.3.tgz#230255b3ad0a3d4978f1d06f70685baea91c640e" + resolved "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.3.tgz" integrity sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw== dependencies: "@jest/types" "^28.1.3" @@ -445,7 +445,7 @@ "@jest/globals@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-28.1.3.tgz#a601d78ddc5fdef542728309894895b4a42dc333" + resolved "https://registry.npmjs.org/@jest/globals/-/globals-28.1.3.tgz" integrity sha512-XFU4P4phyryCXu1pbcqMO0GSQcYe1IsalYCDzRNyhetyeyxMcIxa11qPNDpVNLeretItNqEmYYQn1UYz/5x1NA== dependencies: "@jest/environment" "^28.1.3" @@ -454,7 +454,7 @@ "@jest/reporters@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-28.1.3.tgz#9adf6d265edafc5fc4a434cfb31e2df5a67a369a" + resolved "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.3.tgz" integrity sha512-JuAy7wkxQZVNU/V6g9xKzCGC5LVXx9FDcABKsSXp5MiKPEE2144a/vXTEDoyzjUpZKfVwp08Wqg5A4WfTMAzjg== dependencies: "@bcoe/v8-coverage" "^0.2.3" @@ -485,14 +485,14 @@ "@jest/schemas@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-28.1.3.tgz" integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== dependencies: "@sinclair/typebox" "^0.24.1" "@jest/source-map@^28.1.2": version "28.1.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-28.1.2.tgz#7fe832b172b497d6663cdff6c13b0a920e139e24" + resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-28.1.2.tgz" integrity sha512-cV8Lx3BeStJb8ipPHnqVw/IM2VCMWO3crWZzYodSIkxXnRcXJipCdx1JCK0K5MsJJouZQTH73mzf4vgxRaH9ww== dependencies: "@jridgewell/trace-mapping" "^0.3.13" @@ -501,7 +501,7 @@ "@jest/test-result@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-28.1.3.tgz#5eae945fd9f4b8fcfce74d239e6f725b6bf076c5" + resolved "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.3.tgz" integrity sha512-kZAkxnSE+FqE8YjW8gNuoVkkC9I7S1qmenl8sGcDOLropASP+BkcGKwhXoyqQuGOGeYY0y/ixjrd/iERpEXHNg== dependencies: "@jest/console" "^28.1.3" @@ -511,7 +511,7 @@ "@jest/test-sequencer@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz#9d0c283d906ac599c74bde464bc0d7e6a82886c3" + resolved "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.3.tgz" integrity sha512-NIMPEqqa59MWnDi1kvXXpYbqsfQmSJsIbnd85mdVGkiDfQ9WQQTXOLsvISUfonmnBT+w85WEgneCigEEdHDFxw== dependencies: "@jest/test-result" "^28.1.3" @@ -521,7 +521,7 @@ "@jest/transform@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-28.1.3.tgz#59d8098e50ab07950e0f2fc0fc7ec462371281b0" + resolved "https://registry.npmjs.org/@jest/transform/-/transform-28.1.3.tgz" integrity sha512-u5dT5di+oFI6hfcLOHGTAfmUxFRrjK+vnaP0kkVow9Md/M7V/MxqQMOz/VV25UZO8pzeA9PjfTpOu6BDuwSPQA== dependencies: "@babel/core" "^7.11.6" @@ -540,9 +540,9 @@ slash "^3.0.0" write-file-atomic "^4.0.1" -"@jest/types@^28.1.3": +"@jest/types@^28.0.0", "@jest/types@^28.1.3": version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + resolved "https://registry.npmjs.org/@jest/types/-/types-28.1.3.tgz" integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== dependencies: "@jest/schemas" "^28.1.3" @@ -554,47 +554,47 @@ "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== dependencies: "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": +"@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@3.1.0": version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== "@jridgewell/set-array@^1.0.1": version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@1.4.14": version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.13", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": version "0.3.18" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz" integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== dependencies: "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@kiltprotocol/asset-did@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/asset-did/-/asset-did-0.33.1.tgz#039dd6f9ca8dc33eec9e639ddbe2c500bb3fa331" + resolved "https://registry.npmjs.org/@kiltprotocol/asset-did/-/asset-did-0.33.1.tgz" integrity sha512-CsXFAvjTQ/GnGXoJJIPZnt+5sODRqFRWMXstoZrGgu9Tw/3uYRV54sitDpCwvlFzEnF3R11zFKGdB1DMfzlSOA== dependencies: "@kiltprotocol/types" "0.33.1" @@ -602,14 +602,14 @@ "@kiltprotocol/augment-api@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/augment-api/-/augment-api-0.33.1.tgz#85d91d27ea26b5b0a7671ff69a8e60222bb3eda1" + resolved "https://registry.npmjs.org/@kiltprotocol/augment-api/-/augment-api-0.33.1.tgz" integrity sha512-j2+A29O3DenX4fn43s4JwvmpaL6l3YJJMY+n7AMAJNvbHpWZljzONMwIr/9OfX5UoeE9VCQL1ISQ1Ibf+/UFrQ== dependencies: "@kiltprotocol/type-definitions" "0.33.1" "@kiltprotocol/chain-helpers@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/chain-helpers/-/chain-helpers-0.33.1.tgz#d8621dd035fc9b1a0c26e748019038135123ac75" + resolved "https://registry.npmjs.org/@kiltprotocol/chain-helpers/-/chain-helpers-0.33.1.tgz" integrity sha512-kHvHgIJmkrG1sO2xB2C+I7rQGrKlZdjSR7ukJXxw3K/33zjKZN49TOar7gcTpE4iaDJ3NERTVwHd6d6GRGLJmw== dependencies: "@kiltprotocol/config" "0.33.1" @@ -620,7 +620,7 @@ "@kiltprotocol/config@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/config/-/config-0.33.1.tgz#2fd8d2cd3b5eb40c50bd76b7d130c4566ea580fe" + resolved "https://registry.npmjs.org/@kiltprotocol/config/-/config-0.33.1.tgz" integrity sha512-12pOdI9qbOPiF3TNNtMjeEVb+cMW84KKttXsULYFW+/wvKV2pquL0Fx5SOMEC/a2mBA8uHGYRWnN46HxN9VQhw== dependencies: "@kiltprotocol/types" "0.33.1" @@ -629,7 +629,7 @@ "@kiltprotocol/core@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/core/-/core-0.33.1.tgz#946535a125940e303359d60a084d4a067e029f0f" + resolved "https://registry.npmjs.org/@kiltprotocol/core/-/core-0.33.1.tgz" integrity sha512-ESgopzxQBYThx0MOXOYNDX0wU/4smbATmhD9GSoMLx5r8hJ4w3s00Mip8QUb36l7VpVsiiQO6zqawIc857ksNw== dependencies: "@kiltprotocol/asset-did" "0.33.1" @@ -648,7 +648,7 @@ "@kiltprotocol/did@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/did/-/did-0.33.1.tgz#8a0cdcff183af31b3a5e6c2655bb389da9f89e15" + resolved "https://registry.npmjs.org/@kiltprotocol/did/-/did-0.33.1.tgz" integrity sha512-zAIviziNkQ6lF+GRC9hewlS0Lo/Q81G+z2+L4tl3Ku02kvbVwHatopzE8G0T+lLlFyebN526Alg2Pty5Mk2rQA== dependencies: "@kiltprotocol/augment-api" "0.33.1" @@ -664,7 +664,7 @@ "@kiltprotocol/messaging@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/messaging/-/messaging-0.33.1.tgz#a1eb8664ce6c898ead281f92accab4f7a2669922" + resolved "https://registry.npmjs.org/@kiltprotocol/messaging/-/messaging-0.33.1.tgz" integrity sha512-qLH4uNAY7p46B5Afl0vmXRlm7V6AzTcMxNfoCV7pivvhY8wcbXVbiSh0JVVSHd2m4bzA1bWnloz07Vek3rHYmA== dependencies: "@kiltprotocol/core" "0.33.1" @@ -675,7 +675,7 @@ "@kiltprotocol/sdk-js@^0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/sdk-js/-/sdk-js-0.33.1.tgz#af54068ca5f82423242b0994fb42e9586da68490" + resolved "https://registry.npmjs.org/@kiltprotocol/sdk-js/-/sdk-js-0.33.1.tgz" integrity sha512-AoqFINPQ2PFAEtHBDhBTW0/qsaRBI50RhHHXb+ntFtpHxh2+CrEzKo3p2WAfe+XF9hFO3AjABcZ/4MFgyHAj2Q== dependencies: "@kiltprotocol/chain-helpers" "0.33.1" @@ -688,12 +688,12 @@ "@kiltprotocol/type-definitions@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/type-definitions/-/type-definitions-0.33.1.tgz#d9b908cc613e6dfabdc0eeb6a1cd3f9313158c01" + resolved "https://registry.npmjs.org/@kiltprotocol/type-definitions/-/type-definitions-0.33.1.tgz" integrity sha512-pQfpzrizMmIbVeDEeCjLzYtusP2laUSoXkfvAQNs3qJPqqn99mlRdGd6sAD/rSEOpGjAl7BlV4dpxqFKkrd7Fg== -"@kiltprotocol/types@0.33.1", "@kiltprotocol/types@^0.33.1": +"@kiltprotocol/types@^0.33.1", "@kiltprotocol/types@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/types/-/types-0.33.1.tgz#ee4cedfb928cc23756eeee4e0ebe3ba8d53d05c7" + resolved "https://registry.npmjs.org/@kiltprotocol/types/-/types-0.33.1.tgz" integrity sha512-7iuMz4XNFlRrsGLPxWO0oad+vBZjmntuvf8zoD2LlAnBeHkM8mJ6PUmUQgNmX21DKqvosMsSlLE3nEChf60Q9Q== dependencies: "@polkadot/api" "^10.4.0" @@ -704,7 +704,7 @@ "@kiltprotocol/utils@0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/utils/-/utils-0.33.1.tgz#d912f19323ee80e6aa654172509d8b2322edccbf" + resolved "https://registry.npmjs.org/@kiltprotocol/utils/-/utils-0.33.1.tgz" integrity sha512-hSEWxclIiEL0llEAds2+hTEFPzHLRY5WgfXFDJgPT4KPAh+ogWDwQHW0NWgcVb5MTTeb9g03GcqOM1++Dt3H3g== dependencies: "@kiltprotocol/types" "0.33.1" @@ -718,7 +718,7 @@ "@kiltprotocol/vc-export@^0.33.1": version "0.33.1" - resolved "https://registry.yarnpkg.com/@kiltprotocol/vc-export/-/vc-export-0.33.1.tgz#ed3c37fc7259c8c3ed01e1d1ef89217bef550fe3" + resolved "https://registry.npmjs.org/@kiltprotocol/vc-export/-/vc-export-0.33.1.tgz" integrity sha512-6PXEy8rIK63ZIwmvipSsLwCoTmzqRXfzfq+jvdYnCE5PmWhtDvTlF8fD/LbcDfpWdyTeYM7Lx9LSTF1Omrz71w== dependencies: "@kiltprotocol/config" "0.33.1" @@ -736,32 +736,32 @@ "@noble/curves@1.1.0": version "1.1.0" - resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + resolved "https://registry.npmjs.org/@noble/curves/-/curves-1.1.0.tgz" integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== dependencies: "@noble/hashes" "1.3.1" "@noble/hashes@1.3.1": version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.1.tgz" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== dependencies: "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== "@nodelib/fs.walk@^1.2.3": version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== dependencies: "@nodelib/fs.scandir" "2.1.5" @@ -769,7 +769,7 @@ "@polkadot/api-augment@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-augment/-/api-augment-10.9.1.tgz#9fc81b81903229bb23b0b16783e97ec52a5d4f1b" + resolved "https://registry.npmjs.org/@polkadot/api-augment/-/api-augment-10.9.1.tgz" integrity sha512-kRZZvCFVcN4hAH4dJ+Qzfdy27/4EEq3oLDf3ihj0LTVrAezSWcKPGE3EVFy+Mn6Lo4SUc7RVyoKvIUhSk2l4Dg== dependencies: "@polkadot/api-base" "10.9.1" @@ -782,7 +782,7 @@ "@polkadot/api-base@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-base/-/api-base-10.9.1.tgz#27f63c4950814c2f10535f794121fa1384dc2207" + resolved "https://registry.npmjs.org/@polkadot/api-base/-/api-base-10.9.1.tgz" integrity sha512-Q3m2KzlceMK2kX8bhnUZWk3RT6emmijeeFZZQgCePpEcrSeNjnqG4qjuTPgkveaOkUT8MAoDc5Avuzcc2jlW9g== dependencies: "@polkadot/rpc-core" "10.9.1" @@ -793,7 +793,7 @@ "@polkadot/api-derive@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/api-derive/-/api-derive-10.9.1.tgz#04a4ca3285fd215c4cd50cfb3f4791d38dd90050" + resolved "https://registry.npmjs.org/@polkadot/api-derive/-/api-derive-10.9.1.tgz" integrity sha512-mRud1UZCFIc4Z63qAoGSIHh/foyUYADfy1RQYCmPpeFKfIdCIrHpd7xFdJXTOMYOS0BwlM6u4qli/ZT4XigezQ== dependencies: "@polkadot/api" "10.9.1" @@ -807,9 +807,9 @@ rxjs "^7.8.1" tslib "^2.5.3" -"@polkadot/api@10.9.1", "@polkadot/api@^10.4.0": +"@polkadot/api@^10.4.0", "@polkadot/api@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/api/-/api-10.9.1.tgz#156b3436f45ef18218960804988c1f552d2c4e46" + resolved "https://registry.npmjs.org/@polkadot/api/-/api-10.9.1.tgz" integrity sha512-ND/2UqZBWvtt4PfV03OStTKg0mxmPk4UpMAgJKutdgsz/wP9CYJ1KbjwFgPNekL9JnzbKQsWyQNPVrcw7kQk8A== dependencies: "@polkadot/api-augment" "10.9.1" @@ -832,16 +832,16 @@ "@polkadot/keyring@^12.0.0", "@polkadot/keyring@^12.3.1", "@polkadot/keyring@^12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/keyring/-/keyring-12.3.2.tgz#112a0c28816a1f47edad6260dc94222c29465a54" + resolved "https://registry.npmjs.org/@polkadot/keyring/-/keyring-12.3.2.tgz" integrity sha512-NTdtDeI0DP9l/45hXynNABeP5VB8piw5YR+CbUxK2e36xpJWVXwbcOepzslg5ghE9rs8UKJb30Z/HqTU4sBY0Q== dependencies: "@polkadot/util" "12.3.2" "@polkadot/util-crypto" "12.3.2" tslib "^2.5.3" -"@polkadot/networks@12.3.2", "@polkadot/networks@^12.3.1": +"@polkadot/networks@^12.3.1", "@polkadot/networks@12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/networks/-/networks-12.3.2.tgz#131b0439c481add159814dd2cf0286c6c3fe5b3b" + resolved "https://registry.npmjs.org/@polkadot/networks/-/networks-12.3.2.tgz" integrity sha512-uCkyybKoeEm1daKr0uT/9oNDHDDzCy2/ZdVl346hQqfdR1Ct3BaxMjxqvdmb5N8aCw0cBWSfgsxAYtw8ESmllQ== dependencies: "@polkadot/util" "12.3.2" @@ -850,7 +850,7 @@ "@polkadot/rpc-augment@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-augment/-/rpc-augment-10.9.1.tgz#214ec3ee145d20caa61ea204041a3aadb89c6b0f" + resolved "https://registry.npmjs.org/@polkadot/rpc-augment/-/rpc-augment-10.9.1.tgz" integrity sha512-MaLHkNlyqN20ZRYr6uNd1BZr1OsrnX9qLAmsl0mcrri1vPGRH6VHjfFH1RBLkikpWD82v17g0l2hLwdV1ZHMcw== dependencies: "@polkadot/rpc-core" "10.9.1" @@ -861,7 +861,7 @@ "@polkadot/rpc-core@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-core/-/rpc-core-10.9.1.tgz#798c514dbed6f6c2e43098a494c9f51fb144dc31" + resolved "https://registry.npmjs.org/@polkadot/rpc-core/-/rpc-core-10.9.1.tgz" integrity sha512-ZtA8B8SfXSAwVkBlCcKRHw0eSM7ec/sbiNOM5GasXPeRujUgT7lOwSH2GbUZSqe9RfRDMp6DvO9c2JoGc3LLWw== dependencies: "@polkadot/rpc-augment" "10.9.1" @@ -873,7 +873,7 @@ "@polkadot/rpc-provider@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/rpc-provider/-/rpc-provider-10.9.1.tgz#de3a474bbcd26d28d9cd3134acdb3b5ce92b680b" + resolved "https://registry.npmjs.org/@polkadot/rpc-provider/-/rpc-provider-10.9.1.tgz" integrity sha512-4QzT2QzD+320+eT6b79sGAA85Tt3Bb8fQvse4r5Mom2iiBd2SO81vOhxSAOaIe4GUsw25VzFJmsbe7+OObItdg== dependencies: "@polkadot/keyring" "^12.3.1" @@ -893,7 +893,7 @@ "@polkadot/types-augment@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-augment/-/types-augment-10.9.1.tgz#5f1c1225c04ffbfe243629a46087c9c9de25a6b3" + resolved "https://registry.npmjs.org/@polkadot/types-augment/-/types-augment-10.9.1.tgz" integrity sha512-OY9/jTMFRFqYdkUnfcGwqMLC64A0Q25bjvCuVQCVjsPFKE3wl0Kt5rNT01eV2UmLXrR6fY0xWbR2w80bLA7CIQ== dependencies: "@polkadot/types" "10.9.1" @@ -901,9 +901,9 @@ "@polkadot/util" "^12.3.1" tslib "^2.5.3" -"@polkadot/types-codec@10.9.1", "@polkadot/types-codec@^10.4.0": +"@polkadot/types-codec@^10.4.0", "@polkadot/types-codec@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-codec/-/types-codec-10.9.1.tgz#f30026d3dfeaa69c07c45fa66d1c39318fd232cc" + resolved "https://registry.npmjs.org/@polkadot/types-codec/-/types-codec-10.9.1.tgz" integrity sha512-mJ5OegKGraY1FLvEa8FopRCr3pQrhDkcn5RNOjmgJQozENVeRaxhk0NwxYz7IojFvSDnKnc6lNQfKaaSe5pLHg== dependencies: "@polkadot/util" "^12.3.1" @@ -912,7 +912,7 @@ "@polkadot/types-create@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-create/-/types-create-10.9.1.tgz#087d7e2af51cce558b67e3859613b932a3bdc0a3" + resolved "https://registry.npmjs.org/@polkadot/types-create/-/types-create-10.9.1.tgz" integrity sha512-OVz50MGTTuiuVnRP/zAx4CTuLioc0hsiwNwqN2lNhmIJGtnQ4Vy/7mQRsIWehiYz6g0Vzzm5B3qWkTXO1NSN5w== dependencies: "@polkadot/types-codec" "10.9.1" @@ -921,7 +921,7 @@ "@polkadot/types-known@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-known/-/types-known-10.9.1.tgz#fe0c7e55191aa843119edcaf9abb5d2471463a7d" + resolved "https://registry.npmjs.org/@polkadot/types-known/-/types-known-10.9.1.tgz" integrity sha512-zCMVWc4pJtkbMFPu72bD4IhvV/gkHXPX3C5uu92WdmCfnn0vEIEsMKWlVXVVvQQZKAqvs/awpqIfrUtEViOGEA== dependencies: "@polkadot/networks" "^12.3.1" @@ -933,15 +933,15 @@ "@polkadot/types-support@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/types-support/-/types-support-10.9.1.tgz#17a861aab8e5a225a4e20cefa2d16076ddd51baf" + resolved "https://registry.npmjs.org/@polkadot/types-support/-/types-support-10.9.1.tgz" integrity sha512-XsieuLDsszvMZQlleacQBfx07i/JkwQV/UxH9q8Hz7Okmaz9pEVEW1h3ka2/cPuC7a4l32JhaORBUYshBZNdJg== dependencies: "@polkadot/util" "^12.3.1" tslib "^2.5.3" -"@polkadot/types@10.9.1", "@polkadot/types@^10.4.0": +"@polkadot/types@^10.4.0", "@polkadot/types@10.9.1": version "10.9.1" - resolved "https://registry.yarnpkg.com/@polkadot/types/-/types-10.9.1.tgz#f111d00f7278ad3be95deba3d701fafefe080cb2" + resolved "https://registry.npmjs.org/@polkadot/types/-/types-10.9.1.tgz" integrity sha512-AG33i2ZGGfq7u+5rkAdGrXAQHHl844/Yv+junH5ZzX69xiCoWO1bH/yzDUNBdpki2GlACWvF9nLYh3F2tVF93w== dependencies: "@polkadot/keyring" "^12.3.1" @@ -953,9 +953,9 @@ rxjs "^7.8.1" tslib "^2.5.3" -"@polkadot/util-crypto@12.3.2", "@polkadot/util-crypto@^12.0.0", "@polkadot/util-crypto@^12.3.1", "@polkadot/util-crypto@^12.3.2": +"@polkadot/util-crypto@^12.0.0", "@polkadot/util-crypto@^12.3.1", "@polkadot/util-crypto@^12.3.2", "@polkadot/util-crypto@12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/util-crypto/-/util-crypto-12.3.2.tgz#42d810886904e06fa6e5db254c15f6ef80f4ab72" + resolved "https://registry.npmjs.org/@polkadot/util-crypto/-/util-crypto-12.3.2.tgz" integrity sha512-pTpx+YxolY0BDT4RcGmgeKbHHD/dI6Ll9xRsqmVdIjpcVVY20uDNTyXs81ZNtfKgyod1y9JQkfNv2Dz9iEpTkQ== dependencies: "@noble/curves" "1.1.0" @@ -969,9 +969,9 @@ "@scure/base" "1.1.1" tslib "^2.5.3" -"@polkadot/util@12.3.2", "@polkadot/util@^12.0.0", "@polkadot/util@^12.3.1", "@polkadot/util@^12.3.2": +"@polkadot/util@*", "@polkadot/util@^12.0.0", "@polkadot/util@^12.3.1", "@polkadot/util@^12.3.2", "@polkadot/util@12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-12.3.2.tgz#f46e147b0e6a426da5ba59df4ce65de1a3effe4a" + resolved "https://registry.npmjs.org/@polkadot/util/-/util-12.3.2.tgz" integrity sha512-y/JShcGyOamCUiSIg++XZuLHt1ktSKBaSH2K5Nw5NXlgP0+7am+GZzqPB8fQ4qhYLruEOv+YRiz0GC1Zr9S+wg== dependencies: "@polkadot/x-bigint" "12.3.2" @@ -984,7 +984,7 @@ "@polkadot/wasm-bridge@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-bridge/-/wasm-bridge-7.2.1.tgz#8464a96552207d2b49c6f32137b24132534b91ee" + resolved "https://registry.npmjs.org/@polkadot/wasm-bridge/-/wasm-bridge-7.2.1.tgz" integrity sha512-uV/LHREDBGBbHrrv7HTki+Klw0PYZzFomagFWII4lp6Toj/VCvRh5WMzooVC+g/XsBGosAwrvBhoModabyHx+A== dependencies: "@polkadot/wasm-util" "7.2.1" @@ -992,14 +992,14 @@ "@polkadot/wasm-crypto-asmjs@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.2.1.tgz#3e7a91e2905ab7354bc37b82f3e151a62bb024db" + resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-asmjs/-/wasm-crypto-asmjs-7.2.1.tgz" integrity sha512-z/d21bmxyVfkzGsKef/FWswKX02x5lK97f4NPBZ9XBeiFkmzlXhdSnu58/+b1sKsRAGdW/Rn/rTNRDhW0GqCAg== dependencies: tslib "^2.5.0" "@polkadot/wasm-crypto-init@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.2.1.tgz#9dbba41ed7d382575240f1483cf5a139ff2787bd" + resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-init/-/wasm-crypto-init-7.2.1.tgz" integrity sha512-GcEXtwN9LcSf32V9zSaYjHImFw16hCyo2Xzg4GLLDPPeaAAfbFr2oQMgwyDbvBrBjLKHVHjsPZyGhXae831amw== dependencies: "@polkadot/wasm-bridge" "7.2.1" @@ -1010,7 +1010,7 @@ "@polkadot/wasm-crypto-wasm@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.2.1.tgz#d2486322c725f6e5d2cc2d6abcb77ecbbaedc738" + resolved "https://registry.npmjs.org/@polkadot/wasm-crypto-wasm/-/wasm-crypto-wasm-7.2.1.tgz" integrity sha512-DqyXE4rSD0CVlLIw88B58+HHNyrvm+JAnYyuEDYZwCvzUWOCNos/DDg9wi/K39VAIsCCKDmwKqkkfIofuOj/lA== dependencies: "@polkadot/wasm-util" "7.2.1" @@ -1018,7 +1018,7 @@ "@polkadot/wasm-crypto@^7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-crypto/-/wasm-crypto-7.2.1.tgz#db671dcb73f1646dc13478b5ffc3be18c64babe1" + resolved "https://registry.npmjs.org/@polkadot/wasm-crypto/-/wasm-crypto-7.2.1.tgz" integrity sha512-SA2+33S9TAwGhniKgztVN6pxUKpGfN4Tre/eUZGUfpgRkT92wIUT2GpGWQE+fCCqGQgADrNiBcwt6XwdPqMQ4Q== dependencies: "@polkadot/wasm-bridge" "7.2.1" @@ -1028,16 +1028,16 @@ "@polkadot/wasm-util" "7.2.1" tslib "^2.5.0" -"@polkadot/wasm-util@7.2.1", "@polkadot/wasm-util@^7.2.1": +"@polkadot/wasm-util@*", "@polkadot/wasm-util@^7.2.1", "@polkadot/wasm-util@7.2.1": version "7.2.1" - resolved "https://registry.yarnpkg.com/@polkadot/wasm-util/-/wasm-util-7.2.1.tgz#fda233120ec02f77f0d14e4d3c7ad9ce06535fb8" + resolved "https://registry.npmjs.org/@polkadot/wasm-util/-/wasm-util-7.2.1.tgz" integrity sha512-FBSn/3aYJzhN0sYAYhHB8y9JL8mVgxLy4M1kUXYbyo+8GLRQEN5rns8Vcb8TAlIzBWgVTOOptYBvxo0oj0h7Og== dependencies: tslib "^2.5.0" -"@polkadot/x-bigint@12.3.2", "@polkadot/x-bigint@^12.3.1": +"@polkadot/x-bigint@^12.3.1", "@polkadot/x-bigint@12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-bigint/-/x-bigint-12.3.2.tgz#0e99489cc7938bed40762aaaed58ded6850ab54b" + resolved "https://registry.npmjs.org/@polkadot/x-bigint/-/x-bigint-12.3.2.tgz" integrity sha512-JLqLgfGXe/x+hZJETd5ZqfpVsbwyMsH5Nn1Q20ineMMjXN/ig+kVR8Mc15LXBMuw4g7LldFW6UUrotWnuMI8Yw== dependencies: "@polkadot/x-global" "12.3.2" @@ -1045,23 +1045,23 @@ "@polkadot/x-fetch@^12.3.1": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-fetch/-/x-fetch-12.3.2.tgz#7e8d2113268e792dd5d1b259ef13839c6aa77996" + resolved "https://registry.npmjs.org/@polkadot/x-fetch/-/x-fetch-12.3.2.tgz" integrity sha512-3IEuZ5S+RI/t33NsdPLIIa5COfDCfpUW2sbaByEczn75aD1jLqJZSEDwiBniJ2osyNd4uUxBf6e5jw7LAZeZJg== dependencies: "@polkadot/x-global" "12.3.2" node-fetch "^3.3.1" tslib "^2.5.3" -"@polkadot/x-global@12.3.2", "@polkadot/x-global@^12.3.1": +"@polkadot/x-global@^12.3.1", "@polkadot/x-global@12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-global/-/x-global-12.3.2.tgz#04ac0b0e559a35107f0b95ff7889fcade3796aa3" + resolved "https://registry.npmjs.org/@polkadot/x-global/-/x-global-12.3.2.tgz" integrity sha512-yVZq6oIegjlyh5rUZiTklgu+fL+W/DG1ypEa02683tUCB3avV5cA3PAHKptMSlb6FpweHu37lKKrqfAWrraDxg== dependencies: tslib "^2.5.3" -"@polkadot/x-randomvalues@12.3.2": +"@polkadot/x-randomvalues@*", "@polkadot/x-randomvalues@12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-randomvalues/-/x-randomvalues-12.3.2.tgz#43ac489a998098bdd40b3f82f28adb5b542db2a5" + resolved "https://registry.npmjs.org/@polkadot/x-randomvalues/-/x-randomvalues-12.3.2.tgz" integrity sha512-ywjIs8CWpvOGmq+3cGCNPOHxAjPHdBUiXyDccftx5BRVdmtbt36gK/V84bKr6Xs73FGu0jprUAOSRRsLZX/3dg== dependencies: "@polkadot/x-global" "12.3.2" @@ -1069,7 +1069,7 @@ "@polkadot/x-textdecoder@12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-textdecoder/-/x-textdecoder-12.3.2.tgz#bbd5682744f3552ce5d4d792ff48a3ca525eafcf" + resolved "https://registry.npmjs.org/@polkadot/x-textdecoder/-/x-textdecoder-12.3.2.tgz" integrity sha512-lY5bfA5xArJRWEJlYOlQQMJeTjWD8s0yMhchirVgf5xj8Id9vPGeUoneH+VFDEwgXxrqBvDFJ4smN4T/r6a/fg== dependencies: "@polkadot/x-global" "12.3.2" @@ -1077,7 +1077,7 @@ "@polkadot/x-textencoder@12.3.2": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-textencoder/-/x-textencoder-12.3.2.tgz#223e6f6dd78e2d81c6dcc6f244c76ceae7b08e32" + resolved "https://registry.npmjs.org/@polkadot/x-textencoder/-/x-textencoder-12.3.2.tgz" integrity sha512-iP3qEBiHzBckQ9zeY7ZHRWuu7mCEg5SMpOugs6UODRk8sx6KHzGQYlghBbWLit0uppPDVE0ifEwZ2n73djJHWQ== dependencies: "@polkadot/x-global" "12.3.2" @@ -1085,7 +1085,7 @@ "@polkadot/x-ws@^12.3.1": version "12.3.2" - resolved "https://registry.yarnpkg.com/@polkadot/x-ws/-/x-ws-12.3.2.tgz#422559dfbdaac4c965d5e1b406b6cc4529214f94" + resolved "https://registry.npmjs.org/@polkadot/x-ws/-/x-ws-12.3.2.tgz" integrity sha512-yM9Z64pLNlHpJE43+Xtr+iUXmYpFFY5u5hrke2PJt13O48H8f9Vb9cRaIh94appLyICoS0aekGhDkGH+MCspBA== dependencies: "@polkadot/x-global" "12.3.2" @@ -1094,36 +1094,36 @@ "@scure/base@1.1.1": version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" + resolved "https://registry.npmjs.org/@scure/base/-/base-1.1.1.tgz" integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== "@sinclair/typebox@^0.24.1": version "0.24.44" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.44.tgz#0a0aa3bf4a155a678418527342a3ee84bd8caa5c" + resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz" integrity sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg== "@sinonjs/commons@^1.7.0": version "1.8.3" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" + resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz" integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ== dependencies: type-detect "4.0.8" "@sinonjs/fake-timers@^9.1.2": version "9.1.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" + resolved "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz" integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== dependencies: "@sinonjs/commons" "^1.7.0" "@substrate/connect-extension-protocol@^1.0.1": version "1.0.1" - resolved "https://registry.yarnpkg.com/@substrate/connect-extension-protocol/-/connect-extension-protocol-1.0.1.tgz#fa5738039586c648013caa6a0c95c43265dbe77d" + resolved "https://registry.npmjs.org/@substrate/connect-extension-protocol/-/connect-extension-protocol-1.0.1.tgz" integrity sha512-161JhCC1csjH3GE5mPLEd7HbWtwNSPJBg3p1Ksz9SFlTzj/bgEwudiRN2y5i0MoLGCIJRYKyKGMxVnd29PzNjg== "@substrate/connect@0.7.26": version "0.7.26" - resolved "https://registry.yarnpkg.com/@substrate/connect/-/connect-0.7.26.tgz#a0ee5180c9cb2f29250d1219a32f7b7e7dea1196" + resolved "https://registry.npmjs.org/@substrate/connect/-/connect-0.7.26.tgz" integrity sha512-uuGSiroGuKWj1+38n1kY5HReer5iL9bRwPCzuoLtqAOmI1fGI0hsSI2LlNQMAbfRgr7VRHXOk5MTuQf5ulsFRw== dependencies: "@substrate/connect-extension-protocol" "^1.0.1" @@ -1132,39 +1132,39 @@ "@substrate/ss58-registry@^1.40.0": version "1.41.0" - resolved "https://registry.yarnpkg.com/@substrate/ss58-registry/-/ss58-registry-1.41.0.tgz#dd18e132f44b73c3cd31cf0db489c10af70bef36" + resolved "https://registry.npmjs.org/@substrate/ss58-registry/-/ss58-registry-1.41.0.tgz" integrity sha512-TLz5VkEaJRNFzf1Oiix9gqknKer3aKbLfjK9XHBFCIhdxlQpI+S6lZGu3wT4DHAGXPakYfXb8+9ZIOtWLcQ/2Q== "@tsconfig/node10@^1.0.7": version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + resolved "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz" integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== "@tsconfig/node12@^1.0.7": version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + resolved "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz" integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== "@tsconfig/node14@^1.0.0": version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + resolved "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz" integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== "@tsconfig/node16@^1.0.2": version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" + resolved "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz" integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== "@types/archiver@^5.3.2": version "5.3.2" - resolved "https://registry.yarnpkg.com/@types/archiver/-/archiver-5.3.2.tgz#a9f0bcb0f0b991400e7766d35f6e19d163bdadcc" + resolved "https://registry.npmjs.org/@types/archiver/-/archiver-5.3.2.tgz" integrity sha512-IctHreBuWE5dvBDz/0WeKtyVKVRs4h75IblxOACL92wU66v+HGAfEYAOyXkOFphvRJMhuXdI9huDXpX0FC6lCw== dependencies: "@types/readdir-glob" "*" "@types/babel__core@^7.1.14": version "7.1.19" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.19.tgz#7b497495b7d1b4812bdb9d02804d0576f43ee460" + resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz" integrity sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw== dependencies: "@babel/parser" "^7.1.0" @@ -1175,14 +1175,14 @@ "@types/babel__generator@*": version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" + resolved "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz" integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": version "7.4.1" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.1.tgz#3d1a48fd9d6c0edfd56f2ff578daed48f36c8969" + resolved "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz" integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== dependencies: "@babel/parser" "^7.1.0" @@ -1190,21 +1190,21 @@ "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": version "7.18.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.2.tgz#235bf339d17185bdec25e024ca19cce257cc7309" + resolved "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz" integrity sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg== dependencies: "@babel/types" "^7.3.0" "@types/bn.js@^5.1.1": version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" + resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.1.1.tgz" integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== dependencies: "@types/node" "*" "@types/docker-modem@*": version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/docker-modem/-/docker-modem-3.0.2.tgz#c49c902e17364fc724e050db5c1d2b298c6379d4" + resolved "https://registry.npmjs.org/@types/docker-modem/-/docker-modem-3.0.2.tgz" integrity sha512-qC7prjoEYR2QEe6SmCVfB1x3rfcQtUr1n4x89+3e0wSTMQ/KYCyf+/RAA9n2tllkkNc6//JMUZePdFRiGIWfaQ== dependencies: "@types/node" "*" @@ -1212,7 +1212,7 @@ "@types/dockerode@^3.3.16": version "3.3.16" - resolved "https://registry.yarnpkg.com/@types/dockerode/-/dockerode-3.3.16.tgz#3f6c90385a34af40ca8e07e20d26dea4d520eb7b" + resolved "https://registry.npmjs.org/@types/dockerode/-/dockerode-3.3.16.tgz" integrity sha512-ZAX2VrkTjwjk1808T8m6vMr+CFXSLiDD+tkEkLThI+v83AfzlYQZEWfZKwFyk1PWopSXkdDunmIhrF7sxt+zWg== dependencies: "@types/docker-modem" "*" @@ -1220,33 +1220,33 @@ "@types/graceful-fs@^4.1.3": version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" + resolved "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.6.tgz" integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== dependencies: "@types/node" "*" "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + resolved "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz" integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== "@types/istanbul-lib-report@*": version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + resolved "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + resolved "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz" integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@^28.0.0": version "28.1.8" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-28.1.8.tgz#6936409f3c9724ea431efd412ea0238a0f03b09b" + resolved "https://registry.npmjs.org/@types/jest/-/jest-28.1.8.tgz" integrity sha512-8TJkV++s7B6XqnDrzR1m/TT0A0h948Pnl/097veySPN67VRAgQ4gZ7n2KfJo2rVq6njQjdxU3GCCyDvAeuHoiw== dependencies: expect "^28.0.0" @@ -1254,27 +1254,27 @@ "@types/json-schema@^7.0.9": version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== "@types/node@*", "@types/node@^18.8.2": version "18.15.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f" + resolved "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz" integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== "@types/prettier@^2.1.5": version "2.7.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.1.tgz#dfd20e2dc35f027cdd6c1908e80a5ddc7499670e" + resolved "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz" integrity sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow== "@types/prop-types@*": version "15.7.5" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== "@types/react@^18.0.21": version "18.0.21" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.21.tgz#b8209e9626bb00a34c76f55482697edd2b43cc67" + resolved "https://registry.npmjs.org/@types/react/-/react-18.0.21.tgz" integrity sha512-7QUCOxvFgnD5Jk8ZKlUAhVcRj7GuJRjnjjiY/IUBWKgOlnvDvTMLD4RTF7NPyVmbRhNrbomZiOepg7M/2Kj1mA== dependencies: "@types/prop-types" "*" @@ -1283,26 +1283,26 @@ "@types/readdir-glob@*": version "1.1.1" - resolved "https://registry.yarnpkg.com/@types/readdir-glob/-/readdir-glob-1.1.1.tgz#27ac2db283e6aa3d110b14ff9da44fcd1a5c38b1" + resolved "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.1.tgz" integrity sha512-ImM6TmoF8bgOwvehGviEj3tRdRBbQujr1N+0ypaln/GWjaerOB26jb93vsRHmdMtvVQZQebOlqt2HROark87mQ== dependencies: "@types/node" "*" "@types/scheduler@*": version "0.16.2" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== "@types/ssh2-streams@*": version "0.1.9" - resolved "https://registry.yarnpkg.com/@types/ssh2-streams/-/ssh2-streams-0.1.9.tgz#8ca51b26f08750a780f82ee75ff18d7160c07a87" + resolved "https://registry.npmjs.org/@types/ssh2-streams/-/ssh2-streams-0.1.9.tgz" integrity sha512-I2J9jKqfmvXLR5GomDiCoHrEJ58hAOmFrekfFqmCFd+A6gaEStvWnPykoWUwld1PNg4G5ag1LwdA+Lz1doRJqg== dependencies: "@types/node" "*" "@types/ssh2@*", "@types/ssh2@^0.5.48": version "0.5.52" - resolved "https://registry.yarnpkg.com/@types/ssh2/-/ssh2-0.5.52.tgz#9dbd8084e2a976e551d5e5e70b978ed8b5965741" + resolved "https://registry.npmjs.org/@types/ssh2/-/ssh2-0.5.52.tgz" integrity sha512-lbLLlXxdCZOSJMCInKH2+9V/77ET2J6NPQHpFI0kda61Dd1KglJs+fPQBchizmzYSOJBgdTajhPqBO1xxLywvg== dependencies: "@types/node" "*" @@ -1310,29 +1310,29 @@ "@types/stack-utils@^2.0.0": version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" + resolved "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz" integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== "@types/valid-url@^1.0.3": version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/valid-url/-/valid-url-1.0.3.tgz#a124389fb953559c7f889795a98620e91adb3687" + resolved "https://registry.npmjs.org/@types/valid-url/-/valid-url-1.0.3.tgz" integrity sha512-+33x29mg+ecU88ODdWpqaie2upIuRkhujVLA7TuJjM823cNMbeggfI6NhxewaRaRF8dy+g33e4uIg/m5Mb3xDQ== "@types/yargs-parser@*": version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^17.0.8": version "17.0.13" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.13.tgz#34cced675ca1b1d51fcf4d34c3c6f0fa142a5c76" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz" integrity sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.33.0": version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz#778b2d9e7f293502c7feeea6c74dca8eb3e67511" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.39.0.tgz" integrity sha512-xVfKOkBm5iWMNGKQ2fwX5GVgBuHmZBO1tCRwXmY5oAIsPscfwm2UADDuNB8ZVYCtpQvJK4xpjrK7jEhcJ0zY9A== dependencies: "@typescript-eslint/scope-manager" "5.39.0" @@ -1344,9 +1344,9 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@^5.33.0": +"@typescript-eslint/parser@^5.0.0", "@typescript-eslint/parser@^5.33.0": version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.39.0.tgz#93fa0bc980a3a501e081824f6097f7ca30aaa22b" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.39.0.tgz" integrity sha512-PhxLjrZnHShe431sBAGHaNe6BDdxAASDySgsBCGxcBecVCi8NQWxQZMcizNA4g0pN51bBAn/FUfkWG3SDVcGlA== dependencies: "@typescript-eslint/scope-manager" "5.39.0" @@ -1356,7 +1356,7 @@ "@typescript-eslint/scope-manager@5.39.0": version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz#873e1465afa3d6c78d8ed2da68aed266a08008d0" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.39.0.tgz" integrity sha512-/I13vAqmG3dyqMVSZPjsbuNQlYS082Y7OMkwhCfLXYsmlI0ca4nkL7wJ/4gjX70LD4P8Hnw1JywUVVAwepURBw== dependencies: "@typescript-eslint/types" "5.39.0" @@ -1364,7 +1364,7 @@ "@typescript-eslint/type-utils@5.39.0": version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz#0a8c00f95dce4335832ad2dc6bc431c14e32a0a6" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.39.0.tgz" integrity sha512-KJHJkOothljQWzR3t/GunL0TPKY+fGJtnpl+pX+sJ0YiKTz3q2Zr87SGTmFqsCMFrLt5E0+o+S6eQY0FAXj9uA== dependencies: "@typescript-eslint/typescript-estree" "5.39.0" @@ -1374,12 +1374,12 @@ "@typescript-eslint/types@5.39.0": version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.39.0.tgz#f4e9f207ebb4579fd854b25c0bf64433bb5ed78d" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.39.0.tgz" integrity sha512-gQMZrnfEBFXK38hYqt8Lkwt8f4U6yq+2H5VDSgP/qiTzC8Nw8JO3OuSUOQ2qW37S/dlwdkHDntkZM6SQhKyPhw== "@typescript-eslint/typescript-estree@5.39.0": version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz#c0316aa04a1a1f4f7f9498e3c13ef1d3dc4cf88b" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.39.0.tgz" integrity sha512-qLFQP0f398sdnogJoLtd43pUgB18Q50QSA+BTE5h3sUxySzbWDpTSdgt4UyxNSozY/oDK2ta6HVAzvGgq8JYnA== dependencies: "@typescript-eslint/types" "5.39.0" @@ -1392,7 +1392,7 @@ "@typescript-eslint/utils@5.39.0": version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.39.0.tgz#b7063cca1dcf08d1d21b0d91db491161ad0be110" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.39.0.tgz" integrity sha512-+DnY5jkpOpgj+EBtYPyHRjXampJfC0yUZZzfzLuUWVZvCuKqSdJVC8UhdWipIw7VKNTfwfAPiOWzYkAwuIhiAg== dependencies: "@types/json-schema" "^7.0.9" @@ -1404,7 +1404,7 @@ "@typescript-eslint/visitor-keys@5.39.0": version "5.39.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz#8f41f7d241b47257b081ddba5d3ce80deaae61e2" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.39.0.tgz" integrity sha512-yyE3RPwOG+XJBLrhvsxAidUgybJVQ/hG8BhiJo0k8JSAYfk/CshVcxf0HwP4Jt7WZZ6vLmxdo1p6EyN3tzFTkg== dependencies: "@typescript-eslint/types" "5.39.0" @@ -1412,22 +1412,22 @@ acorn-jsx@^5.3.2: version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== acorn-walk@^8.1.1: version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + resolved "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz" integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== -acorn@^8.4.1, acorn@^8.8.0: +"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.4.1, acorn@^8.8.0: version "8.8.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz" integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" @@ -1437,38 +1437,38 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: ansi-escapes@^4.2.1: version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== dependencies: type-fest "^0.21.3" ansi-regex@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^3.2.1: version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== dependencies: color-convert "^1.9.0" ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== dependencies: color-convert "^2.0.1" ansi-styles@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== anymatch@^3.0.3: version "3.1.2" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" @@ -1476,7 +1476,7 @@ anymatch@^3.0.3: archiver-utils@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" + resolved "https://registry.npmjs.org/archiver-utils/-/archiver-utils-2.1.0.tgz" integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== dependencies: glob "^7.1.4" @@ -1492,7 +1492,7 @@ archiver-utils@^2.1.0: archiver@^5.3.1: version "5.3.1" - resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.1.tgz#21e92811d6f09ecfce649fbefefe8c79e57cbbb6" + resolved "https://registry.npmjs.org/archiver/-/archiver-5.3.1.tgz" integrity sha512-8KyabkmbYrH+9ibcTScQ1xCJC/CGcugdVIwB+53f5sZziXgwUh3iXlAlANMxcZyDEfTHMe6+Z5FofV8nopXP7w== dependencies: archiver-utils "^2.1.0" @@ -1505,66 +1505,66 @@ archiver@^5.3.1: arg@^4.1.0: version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== argparse@^1.0.7: version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz" integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== dependencies: sprintf-js "~1.0.2" argparse@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-union@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== asn1@^0.2.4, asn1@~0.2.3: version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" + resolved "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz" integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== dependencies: safer-buffer "~2.1.0" -assert-plus@1.0.0, assert-plus@^1.0.0: +assert-plus@^1.0.0, assert-plus@1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz" integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== async-lock@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.4.0.tgz#c8b6630eff68fbbdd8a5b6eb763dac3bfbb8bf02" + resolved "https://registry.npmjs.org/async-lock/-/async-lock-1.4.0.tgz" integrity sha512-coglx5yIWuetakm3/1dsX9hxCNox22h7+V80RQOu2XUUMidtArxKoZoOtHUPuR84SycKTXzgGzAUR5hJxujyJQ== async@^3.2.3: version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== asynckit@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== aws-sign2@~0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + resolved "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz" integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== aws4@^1.8.0: version "1.11.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" + resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -babel-jest@^28.1.3: +babel-jest@^28.0.0, babel-jest@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-28.1.3.tgz#c1187258197c099072156a0a121c11ee1e3917d5" + resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.3.tgz" integrity sha512-epUaPOEWMk3cWX0M/sPvCHHCe9fMFAa/9hXEgKP8nFfNl/jlGkE9ucq9NqkZGXLDduCJYS0UvSlPUwC0S+rH6Q== dependencies: "@jest/transform" "^28.1.3" @@ -1577,7 +1577,7 @@ babel-jest@^28.1.3: babel-plugin-istanbul@^6.1.1: version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + resolved "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz" integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" @@ -1588,7 +1588,7 @@ babel-plugin-istanbul@^6.1.1: babel-plugin-jest-hoist@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz#1952c4d0ea50f2d6d794353762278d1d8cca3fbe" + resolved "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.1.3.tgz" integrity sha512-Ys3tUKAmfnkRUpPdpa98eYrAR0nV+sSFUZZEGuQ2EbFd1y4SOLtD5QDNHAq+bb9a+bbXvYQC4b+ID/THIMcU6Q== dependencies: "@babel/template" "^7.3.3" @@ -1598,7 +1598,7 @@ babel-plugin-jest-hoist@^28.1.3: babel-preset-current-node-syntax@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + resolved "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz" integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== dependencies: "@babel/plugin-syntax-async-generators" "^7.8.4" @@ -1616,7 +1616,7 @@ babel-preset-current-node-syntax@^1.0.0: babel-preset-jest@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz#5dfc20b99abed5db994406c2b9ab94c73aaa419d" + resolved "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.1.3.tgz" integrity sha512-L+fupJvlWAHbQfn74coNX3zf60LXMJsezNvvx8eIh7iOR1luJ1poxYgQk1F8PYtNq/6QODDHCqsSnTFSWC491A== dependencies: babel-plugin-jest-hoist "^28.1.3" @@ -1624,43 +1624,43 @@ babel-preset-jest@^28.1.3: balanced-match@^1.0.0: version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== base-x@^3.0.2: version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + resolved "https://registry.npmjs.org/base-x/-/base-x-3.0.9.tgz" integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== dependencies: safe-buffer "^5.0.1" base64-js@^1.3.1: version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base64url-universal@^1.0.1: version "1.1.0" - resolved "https://registry.yarnpkg.com/base64url-universal/-/base64url-universal-1.1.0.tgz#94da6356c1d43ead55b1d91c045c0a5b09ec8181" + resolved "https://registry.npmjs.org/base64url-universal/-/base64url-universal-1.1.0.tgz" integrity sha512-WyftvZqye29YQ10ZnuiBeEj0lk8SN8xHU9hOznkLc85wS1cLTp6RpzlMrHxMPD9nH7S55gsBqMqgGyz93rqmkA== dependencies: base64url "^3.0.0" base64url@^3.0.0, base64url@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" + resolved "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz" integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz" integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== dependencies: tweetnacl "^0.14.3" bl@^4.0.3: version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + resolved "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz" integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== dependencies: buffer "^5.5.0" @@ -1669,12 +1669,12 @@ bl@^4.0.3: bn.js@^5.2.1: version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== brace-expansion@^1.1.7: version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== dependencies: balanced-match "^1.0.0" @@ -1682,21 +1682,21 @@ brace-expansion@^1.1.7: brace-expansion@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== dependencies: balanced-match "^1.0.0" braces@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== dependencies: fill-range "^7.0.1" -browserslist@^4.21.3: +browserslist@^4.21.3, "browserslist@>= 4.21.0": version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz" integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== dependencies: caniuse-lite "^1.0.30001400" @@ -1706,38 +1706,38 @@ browserslist@^4.21.3: bs-logger@0.x: version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + resolved "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz" integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== dependencies: fast-json-stable-stringify "2.x" bs58@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + resolved "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz" integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== dependencies: base-x "^3.0.2" bser@2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz" integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== dependencies: node-int64 "^0.4.0" buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: version "0.2.13" - resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" + resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== buffer-from@^1.0.0: version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer@^5.5.0: version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + resolved "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz" integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== dependencies: base64-js "^1.3.1" @@ -1745,52 +1745,52 @@ buffer@^5.5.0: buildcheck@0.0.5: version "0.0.5" - resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.5.tgz#5b7c0830b25dc61422032eeb5c18bfcaa9eebb8d" + resolved "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.5.tgz" integrity sha512-jYWpRy8eedl/JZqkOeq0X0bNcaK04hXKhIi4gYsDKZUJWRjJJWViYfsMXO0BJQ40zSLcdLoa+iqe48Kz2PtQag== byline@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + resolved "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz" integrity sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q== callsites@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== camelcase@^5.3.1: version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== camelcase@^6.2.0: version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001400: version "1.0.30001416" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001416.tgz#29692af8a6a11412f2d3cf9a59d588fcdd21ce4c" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001416.tgz" integrity sha512-06wzzdAkCPZO+Qm4e/eNghZBDfVNDsCgw33T27OwBH9unE9S478OYw//Q2L7Npf/zBzs7rjZOszIFQkwQKAEqA== canonicalize@^1.0.1: version "1.0.8" - resolved "https://registry.yarnpkg.com/canonicalize/-/canonicalize-1.0.8.tgz#24d1f1a00ed202faafd9bf8e63352cd4450c6df1" + resolved "https://registry.npmjs.org/canonicalize/-/canonicalize-1.0.8.tgz" integrity sha512-0CNTVCLZggSh7bc5VkX5WWPWO+cyZbNd07IHIsSXLia/eAq+r836hgk+8BKoEh7949Mda87VUOitx5OddVj64A== caseless@~0.12.0: version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== cbor-web@^8.0.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/cbor-web/-/cbor-web-8.1.0.tgz#c1148e91ca6bfc0f5c07c1df164854596e2e33d6" + resolved "https://registry.npmjs.org/cbor-web/-/cbor-web-8.1.0.tgz" integrity sha512-2hWHHMVrfffgoEmsAUh8vCxHoLa1vgodtC73+C5cSarkJlwTapnqAzcHINlP6Ej0DXuP4OmmJ9LF+JaNM5Lj/g== chalk@^2.0.0: version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== dependencies: ansi-styles "^3.2.1" @@ -1799,7 +1799,7 @@ chalk@^2.0.0: chalk@^4.0.0: version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== dependencies: ansi-styles "^4.1.0" @@ -1807,27 +1807,27 @@ chalk@^4.0.0: char-regex@^1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + resolved "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz" integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== chownr@^1.1.1: version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + resolved "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== ci-info@^3.2.0: version "3.4.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.4.0.tgz#b28484fd436cbc267900364f096c9dc185efb251" + resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz" integrity sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug== cjs-module-lexer@^1.0.0: version "1.2.2" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" + resolved "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== cliui@^8.0.1: version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + resolved "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz" integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== dependencies: string-width "^4.2.0" @@ -1836,53 +1836,53 @@ cliui@^8.0.1: co@^4.6.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + resolved "https://registry.npmjs.org/co/-/co-4.6.0.tgz" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== collect-v8-coverage@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" + resolved "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz" integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== color-convert@^1.9.0: version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== dependencies: color-name "1.1.3" color-convert@^2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + resolved "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz" integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== dependencies: color-name "~1.1.4" -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - color-name@~1.1.4: version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" commander@^2.20.3: version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== compress-commons@^4.1.0: version "4.1.1" - resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.1.tgz#df2a09a7ed17447642bad10a85cc9a19e5c42a7d" + resolved "https://registry.npmjs.org/compress-commons/-/compress-commons-4.1.1.tgz" integrity sha512-QLdDLCKNV2dtoTorqgxngQCMA+gWXkM/Nwu7FpeBhk/RdkzimqC3jueb/FDmaZeXh+uby1jkBqE3xArsLBE5wQ== dependencies: buffer-crc32 "^0.2.13" @@ -1892,24 +1892,24 @@ compress-commons@^4.1.0: concat-map@0.0.1: version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: version "1.8.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" + resolved "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== dependencies: safe-buffer "~5.1.1" -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@~1.0.0, core-util-is@1.0.2: version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== cpu-features@~0.0.4: version "0.0.6" - resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.6.tgz#607e82a4d563343f64b7dd90a33f2b1d821214b5" + resolved "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.6.tgz" integrity sha512-Rj33pk//oVNh25YjsBaKtOkXNW7IARYxejWJosJkXqVPpbK+FrdpThPk6f4m3d+CEh2qMlkGx/SFt2Y1XSWN6g== dependencies: buildcheck "0.0.5" @@ -1917,12 +1917,12 @@ cpu-features@~0.0.4: crc-32@^1.2.0: version "1.2.2" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== crc32-stream@^4.0.2: version "4.0.2" - resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.2.tgz#c922ad22b38395abe9d3870f02fa8134ed709007" + resolved "https://registry.npmjs.org/crc32-stream/-/crc32-stream-4.0.2.tgz" integrity sha512-DxFZ/Hk473b/muq1VJ///PMNLj0ZMnzye9thBpmjpJKCc5eMgB95aK8zCGrGfQ90cWo561Te6HK9D+j4KPdM6w== dependencies: crc-32 "^1.2.0" @@ -1930,17 +1930,17 @@ crc32-stream@^4.0.2: create-require@^1.1.0: version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + resolved "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== credentials-context@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/credentials-context/-/credentials-context-1.0.0.tgz#a63cb4b7e0a4ca4460d247b7c9370a58b10ebac9" + resolved "https://registry.npmjs.org/credentials-context/-/credentials-context-1.0.0.tgz" integrity sha512-rF3GPhTUGY58xlpuVRif/1i0BxVpynpmFdGNS81S2ezdKPSKoFke5ZOZWB8ZUvGi8bV8CuDM+ZcM/uf4z0PQVQ== cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: path-key "^3.1.0" @@ -1949,7 +1949,7 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: crypto-ld@^3.7.0: version "3.9.0" - resolved "https://registry.yarnpkg.com/crypto-ld/-/crypto-ld-3.9.0.tgz#4f42849a143b5d65f28b018d80bc0fee6cd37ba8" + resolved "https://registry.npmjs.org/crypto-ld/-/crypto-ld-3.9.0.tgz" integrity sha512-PFE7V6A2QNnUp6iiPVEZI4p8wsztkEWLbY1BAXVnclm/aw4KGwpJ+1Ds4vQUCJ5BsWxj15fwE5rHQ8AWaWB2nw== dependencies: base64url-universal "^1.0.1" @@ -1961,80 +1961,80 @@ crypto-ld@^3.7.0: csstype@^3.0.2: version "3.1.1" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9" + resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz" integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw== dashdash@^1.12.0: version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + resolved "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz" integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== dependencies: assert-plus "^1.0.0" data-uri-to-buffer@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" + resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz" integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" dedent@^0.7.0: version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-is@^0.1.3: version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== deepmerge@^4.2.2: version "4.2.2" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + resolved "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== delayed-stream@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== detect-newline@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== diff-sequences@^28.1.1: version "28.1.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" + resolved "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.1.1.tgz" integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== diff@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + resolved "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== dir-glob@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== dependencies: path-type "^4.0.0" docker-compose@^0.23.19: version "0.23.19" - resolved "https://registry.yarnpkg.com/docker-compose/-/docker-compose-0.23.19.tgz#9947726e2fe67bdfa9e8efe1ff15aa0de2e10eb8" + resolved "https://registry.npmjs.org/docker-compose/-/docker-compose-0.23.19.tgz" integrity sha512-v5vNLIdUqwj4my80wxFDkNH+4S85zsRuH29SO7dCWVWPCMt/ohZBsGN6g6KXWifT0pzQ7uOxqEKCYCDPJ8Vz4g== dependencies: yaml "^1.10.2" docker-modem@^3.0.0: version "3.0.8" - resolved "https://registry.yarnpkg.com/docker-modem/-/docker-modem-3.0.8.tgz#ef62c8bdff6e8a7d12f0160988c295ea8705e77a" + resolved "https://registry.npmjs.org/docker-modem/-/docker-modem-3.0.8.tgz" integrity sha512-f0ReSURdM3pcKPNS30mxOHSbaFLcknGmQjwSfmbcdOw1XWKXVhukM3NJHhr7NpY9BIyyWQb0EBo3KQvvuU5egQ== dependencies: debug "^4.1.1" @@ -2044,7 +2044,7 @@ docker-modem@^3.0.0: dockerode@^3.3.5: version "3.3.5" - resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-3.3.5.tgz#7ae3f40f2bec53ae5e9a741ce655fff459745629" + resolved "https://registry.npmjs.org/dockerode/-/dockerode-3.3.5.tgz" integrity sha512-/0YNa3ZDNeLr/tSckmD69+Gq+qVNhvKfAHNeZJBnp7EOP6RGKV8ORrJHkUn20So5wU+xxT7+1n5u8PjHbfjbSA== dependencies: "@balena/dockerignore" "^1.0.2" @@ -2053,14 +2053,14 @@ dockerode@^3.3.5: doctrine@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: esutils "^2.0.2" ecc-jsbn@~0.1.1: version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz" integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== dependencies: jsbn "~0.1.0" @@ -2068,63 +2068,68 @@ ecc-jsbn@~0.1.1: electron-to-chromium@^1.4.251: version "1.4.272" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.272.tgz#cedebaeec5d9879da85b127e65a55c6b4c58344e" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.272.tgz" integrity sha512-KS6gPPGNrzpVv9HzFVq+Etd0AjZEPr5pvaTBn2yD6KV4+cKW4I0CJoJNgmTG6gUQPAMZ4wIPtcOuoou3qFAZCA== emittery@^0.10.2: version "0.10.2" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.10.2.tgz#902eec8aedb8c41938c46e9385e9db7e03182933" + resolved "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz" integrity sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw== emoji-regex@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + resolved "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" error-ex@^1.3.1: version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" error-stack-parser@^1.3.6: version "1.3.6" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-1.3.6.tgz#e0e73b93e417138d1cd7c0b746b1a4a14854c292" + resolved "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-1.3.6.tgz" integrity sha512-xhuSYd8wLgOXwNgjcPeXMPL/IiiA1Huck+OPvClpJViVNNlJVtM41o+1emp7bPvlCJwCatFX2DWc05/DgfbWzA== dependencies: stackframe "^0.3.1" escalade@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-string-regexp@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== escape-string-regexp@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== escape-string-regexp@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +eslint-config-prettier@^9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz" + integrity sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw== + eslint-scope@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== dependencies: esrecurse "^4.3.0" @@ -2132,7 +2137,7 @@ eslint-scope@^5.1.1: eslint-scope@^7.1.1: version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz" integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== dependencies: esrecurse "^4.3.0" @@ -2140,24 +2145,24 @@ eslint-scope@^7.1.1: eslint-utils@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== dependencies: eslint-visitor-keys "^2.0.0" eslint-visitor-keys@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== eslint-visitor-keys@^3.3.0: version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@>=8.14.0: +eslint@*, "eslint@^6.0.0 || ^7.0.0 || ^8.0.0", eslint@>=5, eslint@>=7.0.0, eslint@>=8.14.0: version "8.24.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.24.0.tgz#489516c927a5da11b3979dbfb2679394523383c8" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz" integrity sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ== dependencies: "@eslint/eslintrc" "^1.3.2" @@ -2202,7 +2207,7 @@ eslint@>=8.14.0: espree@^9.4.0: version "9.4.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.4.0.tgz#cd4bc3d6e9336c433265fc0aa016fc1aaf182f8a" + resolved "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz" integrity sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw== dependencies: acorn "^8.8.0" @@ -2211,51 +2216,51 @@ espree@^9.4.0: esprima@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + resolved "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz" integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== dependencies: estraverse "^5.1.0" esrecurse@^4.3.0: version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" estraverse@^4.1.1: version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== estraverse@^5.1.0, estraverse@^5.2.0: version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== esutils@^2.0.2: version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== eventemitter3@^4.0.7: version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== eventemitter3@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== execa@^5.0.0: version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== dependencies: cross-spawn "^7.0.3" @@ -2270,12 +2275,12 @@ execa@^5.0.0: exit@^0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + resolved "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== expect@^28.0.0, expect@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + resolved "https://registry.npmjs.org/expect/-/expect-28.1.3.tgz" integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== dependencies: "@jest/expect-utils" "^28.1.3" @@ -2286,22 +2291,22 @@ expect@^28.0.0, expect@^28.1.3: extend@~3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extsprintf@1.3.0, extsprintf@^1.2.0: +extsprintf@^1.2.0, extsprintf@1.3.0: version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + resolved "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz" integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.9: version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" + resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== dependencies: "@nodelib/fs.stat" "^2.0.2" @@ -2310,33 +2315,33 @@ fast-glob@^3.2.9: merge2 "^1.3.0" micromatch "^4.0.4" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: +fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@2.x: version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== fast-levenshtein@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: version "1.13.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + resolved "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz" integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== dependencies: reusify "^1.0.4" fb-watchman@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + resolved "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz" integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== dependencies: bser "2.1.1" fetch-blob@^3.1.2, fetch-blob@^3.1.4: version "3.2.0" - resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + resolved "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz" integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== dependencies: node-domexception "^1.0.0" @@ -2344,21 +2349,21 @@ fetch-blob@^3.1.2, fetch-blob@^3.1.4: file-entry-cache@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== dependencies: flat-cache "^3.0.4" fill-range@^7.0.1: version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== dependencies: to-regex-range "^5.0.1" find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" @@ -2366,7 +2371,7 @@ find-up@^4.0.0, find-up@^4.1.0: find-up@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== dependencies: locate-path "^6.0.0" @@ -2374,7 +2379,7 @@ find-up@^5.0.0: flat-cache@^3.0.4: version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== dependencies: flatted "^3.1.0" @@ -2382,17 +2387,17 @@ flat-cache@^3.0.4: flatted@^3.1.0: version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== forever-agent@~0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + resolved "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz" integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== form-data@~2.3.2: version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + resolved "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz" integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== dependencies: asynckit "^0.4.0" @@ -2401,19 +2406,19 @@ form-data@~2.3.2: formdata-polyfill@^4.0.10: version "4.0.10" - resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + resolved "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz" integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== dependencies: fetch-blob "^3.1.2" fs-constants@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + resolved "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== fs-extra@^8.1.0: version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== dependencies: graceful-fs "^4.2.0" @@ -2422,73 +2427,68 @@ fs-extra@^8.1.0: fs.realpath@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - function-bind@^1.1.1: version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== gensync@^1.0.0-beta.2: version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== get-caller-file@^2.0.5: version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-package-type@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + resolved "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz" integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== get-port@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + resolved "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== get-stdin@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-7.0.0.tgz#8d5de98f15171a125c5e516643c7a6d0ea8a96f6" + resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz" integrity sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ== get-stream@^6.0.0: version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== getpass@^0.1.1: version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + resolved "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz" integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== dependencies: assert-plus "^1.0.0" glob-parent@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" glob-parent@^6.0.1: version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" glob@^7.1.3, glob@^7.1.4: version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== dependencies: fs.realpath "^1.0.0" @@ -2500,19 +2500,19 @@ glob@^7.1.3, glob@^7.1.4: globals@^11.1.0: version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.15.0: version "13.17.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" + resolved "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz" integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== dependencies: type-fest "^0.20.2" globby@^11.1.0: version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" @@ -2524,22 +2524,22 @@ globby@^11.1.0: graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.9: version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== grapheme-splitter@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== har-schema@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== har-validator@~5.1.3: version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== dependencies: ajv "^6.12.3" @@ -2547,29 +2547,29 @@ har-validator@~5.1.3: has-flag@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== has-flag@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== has@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" html-escaper@^2.0.0: version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + resolved "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== http-signature@~1.2.0: version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== dependencies: assert-plus "^1.0.0" @@ -2578,22 +2578,22 @@ http-signature@~1.2.0: human-signals@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== ieee754@^1.1.13: version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" @@ -2601,7 +2601,7 @@ import-fresh@^3.0.0, import-fresh@^3.2.1: import-local@^3.0.2: version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + resolved "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz" integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== dependencies: pkg-dir "^4.2.0" @@ -2609,94 +2609,94 @@ import-local@^3.0.2: imurmurhash@^0.1.4: version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== inflight@^1.0.4: version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== dependencies: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@2: version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== is-arrayish@^0.2.1: version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== is-core-module@^2.9.0: version "2.10.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz" integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== dependencies: has "^1.0.3" is-extglob@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== is-generator-fn@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + resolved "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== dependencies: is-extglob "^2.1.1" is-number@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== is-stream@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== is-typedarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + resolved "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== isarray@~1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== isexe@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== isstream@~0.1.2: version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + resolved "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + resolved "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz" integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz#31d18bdd127f825dd02ea7bfdfd906f8ab840e9f" + resolved "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz" integrity sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A== dependencies: "@babel/core" "^7.12.3" @@ -2707,7 +2707,7 @@ istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: istanbul-lib-report@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" + resolved "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz" integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== dependencies: istanbul-lib-coverage "^3.0.0" @@ -2716,7 +2716,7 @@ istanbul-lib-report@^3.0.0: istanbul-lib-source-maps@^4.0.0: version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + resolved "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz" integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== dependencies: debug "^4.1.1" @@ -2725,7 +2725,7 @@ istanbul-lib-source-maps@^4.0.0: istanbul-reports@^3.1.3: version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz" integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== dependencies: html-escaper "^2.0.0" @@ -2733,7 +2733,7 @@ istanbul-reports@^3.1.3: jest-changed-files@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-28.1.3.tgz#d9aeee6792be3686c47cb988a8eaf82ff4238831" + resolved "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.1.3.tgz" integrity sha512-esaOfUWJXk2nfZt9SPyC8gA1kNfdKLkQWyzsMlqq8msYSlNKfmZxfRgZn4Cd4MGVUF+7v6dBs0d5TOAKa7iIiA== dependencies: execa "^5.0.0" @@ -2741,7 +2741,7 @@ jest-changed-files@^28.1.3: jest-circus@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-28.1.3.tgz#d14bd11cf8ee1a03d69902dc47b6bd4634ee00e4" + resolved "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.3.tgz" integrity sha512-cZ+eS5zc79MBwt+IhQhiEp0OeBddpc1n8MBo1nMB8A7oPMKEO+Sre+wHaLJexQUj9Ya/8NOBY0RESUgYjB6fow== dependencies: "@jest/environment" "^28.1.3" @@ -2766,7 +2766,7 @@ jest-circus@^28.1.3: jest-cli@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-28.1.3.tgz#558b33c577d06de55087b8448d373b9f654e46b2" + resolved "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.3.tgz" integrity sha512-roY3kvrv57Azn1yPgdTebPAXvdR2xfezaKKYzVxZ6It/5NCxzJym6tUI5P1zkdWhfUYkxEI9uZWcQdaFLo8mJQ== dependencies: "@jest/core" "^28.1.3" @@ -2784,7 +2784,7 @@ jest-cli@^28.1.3: jest-config@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-28.1.3.tgz#e315e1f73df3cac31447eed8b8740a477392ec60" + resolved "https://registry.npmjs.org/jest-config/-/jest-config-28.1.3.tgz" integrity sha512-MG3INjByJ0J4AsNBm7T3hsuxKQqFIiRo/AUqb1q9LRKI5UU6Aar9JHbr9Ivn1TVwfUD9KirRoM/T6u8XlcQPHQ== dependencies: "@babel/core" "^7.11.6" @@ -2812,7 +2812,7 @@ jest-config@^28.1.3: jest-diff@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + resolved "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.3.tgz" integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== dependencies: chalk "^4.0.0" @@ -2822,14 +2822,14 @@ jest-diff@^28.1.3: jest-docblock@^28.1.1: version "28.1.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-28.1.1.tgz#6f515c3bf841516d82ecd57a62eed9204c2f42a8" + resolved "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.1.1.tgz" integrity sha512-3wayBVNiOYx0cwAbl9rwm5kKFP8yHH3d/fkEaL02NPTkDojPtheGB7HZSFY4wzX+DxyrvhXz0KSCVksmCknCuA== dependencies: detect-newline "^3.0.0" jest-each@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-28.1.3.tgz#bdd1516edbe2b1f3569cfdad9acd543040028f81" + resolved "https://registry.npmjs.org/jest-each/-/jest-each-28.1.3.tgz" integrity sha512-arT1z4sg2yABU5uogObVPvSlSMQlDA48owx07BDPAiasW0yYpYHYOo4HHLz9q0BVzDVU4hILFjzJw0So9aCL/g== dependencies: "@jest/types" "^28.1.3" @@ -2840,7 +2840,7 @@ jest-each@^28.1.3: jest-environment-node@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-28.1.3.tgz#7e74fe40eb645b9d56c0c4b70ca4357faa349be5" + resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.3.tgz" integrity sha512-ugP6XOhEpjAEhGYvp5Xj989ns5cB1K6ZdjBYuS30umT4CQEETaxSiPcZ/E1kFktX4GkrcM4qu07IIlDYX1gp+A== dependencies: "@jest/environment" "^28.1.3" @@ -2852,12 +2852,12 @@ jest-environment-node@^28.1.3: jest-get-type@^28.0.2: version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" + resolved "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz" integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== jest-haste-map@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-28.1.3.tgz#abd5451129a38d9841049644f34b034308944e2b" + resolved "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.3.tgz" integrity sha512-3S+RQWDXccXDKSWnkHa/dPwt+2qwA8CJzR61w3FoYCvoo3Pn8tvGcysmMF0Bj0EX5RYvAI2EIvC57OmotfdtKA== dependencies: "@jest/types" "^28.1.3" @@ -2876,7 +2876,7 @@ jest-haste-map@^28.1.3: jest-leak-detector@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz#a6685d9b074be99e3adee816ce84fd30795e654d" + resolved "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.3.tgz" integrity sha512-WFVJhnQsiKtDEo5lG2mM0v40QWnBM+zMdHHyJs8AWZ7J0QZJS59MsyKeJHWhpBZBH32S48FOVvGyOFT1h0DlqA== dependencies: jest-get-type "^28.0.2" @@ -2884,7 +2884,7 @@ jest-leak-detector@^28.1.3: jest-matcher-utils@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + resolved "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz" integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== dependencies: chalk "^4.0.0" @@ -2894,7 +2894,7 @@ jest-matcher-utils@^28.1.3: jest-message-util@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + resolved "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.3.tgz" integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== dependencies: "@babel/code-frame" "^7.12.13" @@ -2909,7 +2909,7 @@ jest-message-util@^28.1.3: jest-mock@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-28.1.3.tgz#d4e9b1fc838bea595c77ab73672ebf513ab249da" + resolved "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.3.tgz" integrity sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA== dependencies: "@jest/types" "^28.1.3" @@ -2917,25 +2917,25 @@ jest-mock@^28.1.3: jest-pnp-resolver@^1.2.2: version "1.2.2" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" + resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== jest-regex-util@^28.0.2: version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" + resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz" integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== jest-resolve-dependencies@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz#8c65d7583460df7275c6ea2791901fa975c1fe66" + resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.3.tgz" integrity sha512-qa0QO2Q0XzQoNPouMbCc7Bvtsem8eQgVPNkwn9LnS+R2n8DaVDPL/U1gngC0LTl1RYXJU0uJa2BMC2DbTfFrHA== dependencies: jest-regex-util "^28.0.2" jest-snapshot "^28.1.3" -jest-resolve@^28.1.3: +jest-resolve@*, jest-resolve@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-28.1.3.tgz#cfb36100341ddbb061ec781426b3c31eb51aa0a8" + resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.3.tgz" integrity sha512-Z1W3tTjE6QaNI90qo/BJpfnvpxtaFTFw5CDgwpyE/Kz8U/06N1Hjf4ia9quUhCh39qIGWF1ZuxFiBiJQwSEYKQ== dependencies: chalk "^4.0.0" @@ -2950,7 +2950,7 @@ jest-resolve@^28.1.3: jest-runner@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-28.1.3.tgz#5eee25febd730b4713a2cdfd76bdd5557840f9a1" + resolved "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.3.tgz" integrity sha512-GkMw4D/0USd62OVO0oEgjn23TM+YJa2U2Wu5zz9xsQB1MxWKDOlrnykPxnMsN0tnJllfLPinHTka61u0QhaxBA== dependencies: "@jest/console" "^28.1.3" @@ -2977,7 +2977,7 @@ jest-runner@^28.1.3: jest-runtime@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-28.1.3.tgz#a57643458235aa53e8ec7821949e728960d0605f" + resolved "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.3.tgz" integrity sha512-NU+881ScBQQLc1JHG5eJGU7Ui3kLKrmwCPPtYsJtBykixrM2OhVQlpMmFWJjMyDfdkGgBMNjXCGB/ebzsgNGQw== dependencies: "@jest/environment" "^28.1.3" @@ -3005,7 +3005,7 @@ jest-runtime@^28.1.3: jest-snapshot@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-28.1.3.tgz#17467b3ab8ddb81e2f605db05583d69388fc0668" + resolved "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.3.tgz" integrity sha512-4lzMgtiNlc3DU/8lZfmqxN3AYD6GGLbl+72rdBpXvcV+whX7mDrREzkPdp2RnmfIiWBg1YbuFSkXduF2JcafJg== dependencies: "@babel/core" "^7.11.6" @@ -3034,7 +3034,7 @@ jest-snapshot@^28.1.3: jest-util@^28.0.0, jest-util@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + resolved "https://registry.npmjs.org/jest-util/-/jest-util-28.1.3.tgz" integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== dependencies: "@jest/types" "^28.1.3" @@ -3046,7 +3046,7 @@ jest-util@^28.0.0, jest-util@^28.1.3: jest-validate@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-28.1.3.tgz#e322267fd5e7c64cea4629612c357bbda96229df" + resolved "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.3.tgz" integrity sha512-SZbOGBWEsaTxBGCOpsRWlXlvNkvTkY0XxRfh7zYmvd8uL5Qzyg0CHAXiXKROflh801quA6+/DsT4ODDthOC/OA== dependencies: "@jest/types" "^28.1.3" @@ -3058,7 +3058,7 @@ jest-validate@^28.1.3: jest-watcher@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-28.1.3.tgz#c6023a59ba2255e3b4c57179fc94164b3e73abd4" + resolved "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.3.tgz" integrity sha512-t4qcqj9hze+jviFPUN3YAtAEeFnr/azITXQEMARf5cMwKY2SMBRnCQTXLixTl20OR6mLh9KLMrgVJgJISym+1g== dependencies: "@jest/test-result" "^28.1.3" @@ -3072,7 +3072,7 @@ jest-watcher@^28.1.3: jest-worker@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-28.1.3.tgz#7e3c4ce3fa23d1bb6accb169e7f396f98ed4bb98" + resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.3.tgz" integrity sha512-CqRA220YV/6jCo8VWvAt1KKx6eek1VIHMPeLEbpcfSfkEeWyBNppynM/o6q+Wmw+sOhos2ml34wZbSX3G13//g== dependencies: "@types/node" "*" @@ -3081,7 +3081,7 @@ jest-worker@^28.1.3: jest@^28.0.0: version "28.1.3" - resolved "https://registry.yarnpkg.com/jest/-/jest-28.1.3.tgz#e9c6a7eecdebe3548ca2b18894a50f45b36dfc6b" + resolved "https://registry.npmjs.org/jest/-/jest-28.1.3.tgz" integrity sha512-N4GT5on8UkZgH0O5LUavMRV1EDEhNTL0KEfRmDIeZHSV7p2XgLoY9t9VDUgL6o+yfdgYHVxuz81G8oB9VG5uyA== dependencies: "@jest/core" "^28.1.3" @@ -3091,17 +3091,17 @@ jest@^28.0.0: js-sdsl@^4.1.4: version "4.1.5" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.1.5.tgz#1ff1645e6b4d1b028cd3f862db88c9d887f26e2a" + resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.5.tgz" integrity sha512-08bOAKweV2NUC1wqTtf3qZlnpOX/R2DU9ikpjOHs0H+ibQv3zpncVQg6um4uYtRtrwIX8M4Nh3ytK4HGlYAq7Q== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== js-yaml@^3.13.1: version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" @@ -3109,61 +3109,61 @@ js-yaml@^3.13.1: js-yaml@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: argparse "^2.0.1" jsbn@~0.1.0: version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + resolved "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== jsesc@^2.5.1: version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + resolved "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz" integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== json-parse-even-better-errors@^2.3.0: version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + 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== json-schema-traverse@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== json-schema@0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" + resolved "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz" integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz" integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== json5@^2.2.1, json5@^2.2.2: version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + resolved "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== jsonfile@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz" integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== optionalDependencies: graceful-fs "^4.1.6" jsonld-signatures@^5.0.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/jsonld-signatures/-/jsonld-signatures-5.2.0.tgz#2f6210c3aad0a50f925991ce3e91c78856c0752d" + resolved "https://registry.npmjs.org/jsonld-signatures/-/jsonld-signatures-5.2.0.tgz" integrity sha512-/dGgMElXc3oBS+/OUwMc3DTK4riHKLE9Lk7NF1Upz2ZlBTNfnOw5uLRkFQOJFBDqDEm5hK6hIfkoC/rCWFh9tQ== dependencies: base64url "^3.0.1" @@ -3175,7 +3175,7 @@ jsonld-signatures@^5.0.0: jsonld@^2.0.2: version "2.0.2" - resolved "https://registry.yarnpkg.com/jsonld/-/jsonld-2.0.2.tgz#f5d0631de828ce6dee3a14f08cbdc6a53174cd15" + resolved "https://registry.npmjs.org/jsonld/-/jsonld-2.0.2.tgz" integrity sha512-/TQzRe75/3h2khu57IUojha5oat+M82bm8RYw0jLhlmmPrW/kTWAZ9nGzKPfZWnPYnVVJJMQVc/pU8HCmpv9xg== dependencies: canonicalize "^1.0.1" @@ -3187,7 +3187,7 @@ jsonld@^2.0.2: jsprim@^1.2.2: version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" + resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== dependencies: assert-plus "1.0.0" @@ -3197,24 +3197,24 @@ jsprim@^1.2.2: kleur@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== lazystream@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638" + resolved "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz" integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw== dependencies: readable-stream "^2.0.5" leven@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== levn@^0.4.1: version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== dependencies: prelude-ls "^1.2.1" @@ -3222,116 +3222,116 @@ levn@^0.4.1: lines-and-columns@^1.1.6: version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== locate-path@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== dependencies: p-locate "^4.1.0" locate-path@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== dependencies: p-locate "^5.0.0" lodash.defaults@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + resolved "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz" integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== lodash.difference@^4.5.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" + resolved "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz" integrity sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA== lodash.flatten@^4.4.0: version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + resolved "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz" integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== lodash.isplainobject@^4.0.6: version "4.0.6" - resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" + resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== lodash.memoize@4.x: version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + resolved "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz" integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== lodash.merge@^4.6.2: version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== lodash.union@^4.6.0: version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + resolved "https://registry.npmjs.org/lodash.union/-/lodash.union-4.6.0.tgz" integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw== lodash@^4.17.21: version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== loose-envify@^1.1.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== dependencies: js-tokens "^3.0.0 || ^4.0.0" lru-cache@^5.1.1: version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== dependencies: yallist "^3.0.2" lru-cache@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" make-dir@^3.0.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== dependencies: semver "^6.0.0" -make-error@1.x, make-error@^1.1.1: +make-error@^1.1.1, make-error@1.x: version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + resolved "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== makeerror@1.0.12: version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + resolved "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz" integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== dependencies: tmpl "1.0.5" merge-stream@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: braces "^3.0.2" @@ -3339,68 +3339,68 @@ micromatch@^4.0.4: mime-db@1.52.0: version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== mime-types@^2.1.12, mime-types@~2.1.19: version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" mimic-fn@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" minimatch@^5.1.0: version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + resolved "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz" integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== dependencies: brace-expansion "^2.0.1" mkdirp-classic@^0.5.2: version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== mkdirp@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== mock-socket@^9.2.1: version "9.2.1" - resolved "https://registry.yarnpkg.com/mock-socket/-/mock-socket-9.2.1.tgz#cc9c0810aa4d0afe02d721dcb2b7e657c00e2282" + resolved "https://registry.npmjs.org/mock-socket/-/mock-socket-9.2.1.tgz" integrity sha512-aw9F9T9G2zpGipLLhSNh6ZpgUyUl4frcVmRN08uE1NWPWg43Wx6+sGPDbQ7E5iFZZDJW5b5bypMeAEHqTbIFag== ms@2.1.2: version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== nan@^2.16.0, nan@^2.17.0: version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" + resolved "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz" integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== natural-compare@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== nock@^13.3.1: version "13.3.2" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.3.2.tgz#bfa6be92d37f744b1b758ea89b1105cdaf5c8b3f" + resolved "https://registry.npmjs.org/nock/-/nock-13.3.2.tgz" integrity sha512-CwbljitiWJhF1gL83NbanhoKs1l23TDlRioNraPTZrzZIEooPemrHRj5m0FZCPkB1ecdYCSWWGcHysJgX/ngnQ== dependencies: debug "^4.1.0" @@ -3410,19 +3410,19 @@ nock@^13.3.1: node-domexception@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + resolved "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz" integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== node-fetch@^2.6.9: version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz" integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== dependencies: whatwg-url "^5.0.0" node-fetch@^3.3.1: version "3.3.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.1.tgz" integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== dependencies: data-uri-to-buffer "^4.0.0" @@ -3431,58 +3431,58 @@ node-fetch@^3.3.1: node-forge@^0.10.0, node-forge@~0.10.0: version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" + resolved "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz" integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== node-gyp-build@^4.3.0: version "4.5.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" + resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz" integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg== node-int64@^0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + resolved "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== node-releases@^2.0.6: version "2.0.6" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz" integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== normalize-path@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== npm-run-path@^4.0.1: version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: path-key "^3.0.0" oauth-sign@~0.9.0: version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== dependencies: wrappy "1" onetime@^5.1.2: version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" optionator@^0.9.1: version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== dependencies: deep-is "^0.1.3" @@ -3494,52 +3494,52 @@ optionator@^0.9.1: p-limit@^2.2.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== dependencies: p-try "^2.0.0" p-limit@^3.0.2, p-limit@^3.1.0: version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: yocto-queue "^0.1.0" p-locate@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== dependencies: p-limit "^2.2.0" p-locate@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== dependencies: p-limit "^3.0.2" p-try@^2.0.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@^2.0.4: version "2.0.4" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" + resolved "https://registry.npmjs.org/pako/-/pako-2.0.4.tgz" integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== parent-module@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== dependencies: callsites "^3.0.0" parse-json@^5.2.0: version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== dependencies: "@babel/code-frame" "^7.0.0" @@ -3549,64 +3549,64 @@ parse-json@^5.2.0: path-exists@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== path-is-absolute@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== path-parse@^1.0.7: version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-type@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== performance-now@^2.1.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + resolved "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== picocolors@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== pirates@^4.0.4: version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== pkg-dir@^4.2.0: version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== dependencies: find-up "^4.0.0" prelude-ls@^1.2.1: version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== pretty-format@^28.0.0, pretty-format@^28.1.3: version "28.1.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz" integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== dependencies: "@jest/schemas" "^28.1.3" @@ -3616,12 +3616,12 @@ pretty-format@^28.0.0, pretty-format@^28.1.3: process-nextick-args@~2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== prompts@^2.0.1: version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + resolved "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz" integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== dependencies: kleur "^3.0.3" @@ -3629,24 +3629,24 @@ prompts@^2.0.1: propagate@^2.0.0: version "2.0.1" - resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" + resolved "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz" integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== properties-reader@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/properties-reader/-/properties-reader-2.2.0.tgz#41d837fe143d8d5f2386b6a869a1975c0b2c595c" + resolved "https://registry.npmjs.org/properties-reader/-/properties-reader-2.2.0.tgz" integrity sha512-CgVcr8MwGoBKK24r9TwHfZkLLaNFHQ6y4wgT9w/XzdpacOOi5ciH4hcuLechSDAwXsfrGQtI2JTutY2djOx2Ow== dependencies: mkdirp "^1.0.4" psl@^1.1.28: version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== pump@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + resolved "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz" integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== dependencies: end-of-stream "^1.1.0" @@ -3654,22 +3654,22 @@ pump@^3.0.0: punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== qs@~6.5.2: version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" + resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== queue-microtask@^1.2.2: version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== rdf-canonize@^1.0.2: version "1.2.0" - resolved "https://registry.yarnpkg.com/rdf-canonize/-/rdf-canonize-1.2.0.tgz#9872b2cc6ed92a9969e834f9f042addaf0d4f7f9" + resolved "https://registry.npmjs.org/rdf-canonize/-/rdf-canonize-1.2.0.tgz" integrity sha512-MQdcRDz4+82nUrEb3hNQangBDpmep15uMmnWclGi/1KS0bNVc8oHpoNI0PFLHZsvwgwRzH31bO1JAScqUAstvw== dependencies: node-forge "^0.10.0" @@ -3677,19 +3677,32 @@ rdf-canonize@^1.0.2: react-is@^18.0.0: version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== react@^18.2.0: version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== dependencies: loose-envify "^1.1.0" -readable-stream@^2.0.0, readable-stream@^2.0.5: +readable-stream@^2.0.0: + version "2.3.8" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + 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" + +readable-stream@^2.0.5: version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== dependencies: core-util-is "~1.0.0" @@ -3702,7 +3715,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.5: readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0: version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== dependencies: inherits "^2.0.3" @@ -3711,19 +3724,19 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.5.0, readable readdir-glob@^1.0.0: version "1.1.3" - resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.3.tgz#c3d831f51f5e7bfa62fa2ffbe4b508c640f09584" + resolved "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz" integrity sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA== dependencies: minimatch "^5.1.0" regexpp@^3.2.0: version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== request@^2.88.0: version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== dependencies: aws-sign2 "~0.7.0" @@ -3749,34 +3762,34 @@ request@^2.88.0: require-directory@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== resolve-cwd@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== dependencies: resolve-from "^5.0.0" resolve-from@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== resolve-from@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== resolve.exports@^1.1.0: version "1.1.0" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" + resolved "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz" integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== resolve@^1.20.0: version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== dependencies: is-core-module "^2.9.0" @@ -3785,94 +3798,108 @@ resolve@^1.20.0: reusify@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== dependencies: glob "^7.1.3" run-parallel@^1.1.9: version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== dependencies: queue-microtask "^1.2.2" rxjs@^7.8.1: version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== security-context@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/security-context/-/security-context-4.0.0.tgz#e73f5d22bee9c7699a02eaaced359d001dc948e9" + resolved "https://registry.npmjs.org/security-context/-/security-context-4.0.0.tgz" integrity sha512-yiDCS7tpKQl6p4NG57BdKLTSNLFfj5HosBIzXBl4jZf/qorJzSzbEUIdLhN+vVYgyLlvjixY8DPPTgqI8zvNCA== -semver@7.x, semver@^7.3.5, semver@^7.3.7: +semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.3.5: version "7.5.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz" integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.7: + version "7.5.0" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz" + integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== + dependencies: + lru-cache "^6.0.0" + +semver@7.x: + version "7.5.0" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz" + integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== + dependencies: + lru-cache "^6.0.0" serialize-error@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-5.0.0.tgz#a7ebbcdb03a5d71a6ed8461ffe0fc1a1afed62ac" + resolved "https://registry.npmjs.org/serialize-error/-/serialize-error-5.0.0.tgz" integrity sha512-/VtpuyzYf82mHYTtI4QKtwHa79vAdU5OQpNPAmE/0UDdlGT0ZxHwC+J6gXkw29wwoVI8fMPsfcVHOwXtUQYYQA== dependencies: type-fest "^0.8.0" shebang-command@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== dependencies: shebang-regex "^3.0.0" shebang-regex@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== sisteransi@^1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== slash@^3.0.0: version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== smoldot@1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/smoldot/-/smoldot-1.0.4.tgz#e4c38cedad68d699a11b5b9ce72bb75c891bfd98" + resolved "https://registry.npmjs.org/smoldot/-/smoldot-1.0.4.tgz" integrity sha512-N3TazI1C4GGrseFH/piWyZCCCRJTRx2QhDfrUKRT4SzILlW5m8ayZ3QTKICcz1C/536T9cbHHJyP7afxI6Mi1A== dependencies: pako "^2.0.4" @@ -3880,42 +3907,42 @@ smoldot@1.0.4: sodium-native@^3.2.0: version "3.4.1" - resolved "https://registry.yarnpkg.com/sodium-native/-/sodium-native-3.4.1.tgz#44616c07ccecea15195f553af88b3e574b659741" + resolved "https://registry.npmjs.org/sodium-native/-/sodium-native-3.4.1.tgz" integrity sha512-PaNN/roiFWzVVTL6OqjzYct38NSXewdl2wz8SRB51Br/MLIJPrbM3XexhVWkq7D3UWMysfrhKVf1v1phZq6MeQ== dependencies: node-gyp-build "^4.3.0" source-map-support@0.5.13: version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz" integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" -source-map@0.5.6: - version "0.5.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" - integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA== - source-map@^0.6.0, source-map@^0.6.1: version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@0.5.6: + version "0.5.6" + resolved "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" + integrity sha512-MjZkVp0NHr5+TPihLcadqnlVoGIoWo4IBHptutGh9wI3ttUYvCG26HkSuDi+K6lsZ25syXJXcctwgyVCt//xqA== + split-ca@^1.0.1: version "1.0.1" - resolved "https://registry.yarnpkg.com/split-ca/-/split-ca-1.0.1.tgz#6c83aff3692fa61256e0cd197e05e9de157691a6" + resolved "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz" integrity sha512-Q5thBSxp5t8WPTTJQS59LrGqOZqOsrhDGDVm8azCqIBjSBd7nd9o2PM+mDulQQkh8h//4U6hFZnc/mul8t5pWQ== sprintf-js@~1.0.2: version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== ssh-remote-port-forward@^1.0.4: version "1.0.4" - resolved "https://registry.yarnpkg.com/ssh-remote-port-forward/-/ssh-remote-port-forward-1.0.4.tgz#72b0c5df8ec27ca300c75805cc6b266dee07e298" + resolved "https://registry.npmjs.org/ssh-remote-port-forward/-/ssh-remote-port-forward-1.0.4.tgz" integrity sha512-x0LV1eVDwjf1gmG7TTnfqIzf+3VPRz7vrNIjX6oYLbeCrf/PeVY6hkT68Mg+q02qXxQhrLjB0jfgvhevoCRmLQ== dependencies: "@types/ssh2" "^0.5.48" @@ -3923,7 +3950,7 @@ ssh-remote-port-forward@^1.0.4: ssh2@^1.11.0, ssh2@^1.4.0: version "1.11.0" - resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.11.0.tgz#ce60186216971e12f6deb553dcf82322498fe2e4" + resolved "https://registry.npmjs.org/ssh2/-/ssh2-1.11.0.tgz" integrity sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw== dependencies: asn1 "^0.2.4" @@ -3934,7 +3961,7 @@ ssh2@^1.11.0, ssh2@^1.4.0: sshpk@^1.7.0: version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" + resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz" integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== dependencies: asn1 "~0.2.3" @@ -3949,31 +3976,31 @@ sshpk@^1.7.0: stack-generator@^1.0.7: version "1.1.0" - resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-1.1.0.tgz#36f6a920751a6c10f499a13c32cbb5f51a0b8b25" + resolved "https://registry.npmjs.org/stack-generator/-/stack-generator-1.1.0.tgz" integrity sha512-sZDVjwC56vZoo+a5t0LH/1sMQLWYLi/r+Z2ztyCAOhOX3QBP34GWxK0FWf2eU1TIU2CJKCKBAtDZycUh/ZKMlw== dependencies: stackframe "^1.0.2" stack-utils@^2.0.3: version "2.0.5" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" + resolved "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz" integrity sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA== dependencies: escape-string-regexp "^2.0.0" stackframe@^0.3.1, stackframe@~0.3: version "0.3.1" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4" + resolved "https://registry.npmjs.org/stackframe/-/stackframe-0.3.1.tgz" integrity sha512-XmoiF4T5nuWEp2x2w92WdGjdHGY/cZa6LIbRsDRQR/Xlk4uW0PAUlH1zJYVffocwKpCdwyuypIp25xsSXEtZHw== stackframe@^1.0.2: version "1.3.4" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + resolved "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz" integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== stacktrace-gps@^2.4.3: version "2.4.4" - resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-2.4.4.tgz#69c827e9d6d6f41cf438d7f195e2e3cbfcf28c44" + resolved "https://registry.npmjs.org/stacktrace-gps/-/stacktrace-gps-2.4.4.tgz" integrity sha512-msFhuMEEklQLUtaJ+GeCDjzUN+PamfHWQiK3C1LnbHjoxSeF5dAxiE+aJkptNMmMNOropGFJ7G3ZT7dPZHgDaQ== dependencies: source-map "0.5.6" @@ -3981,16 +4008,23 @@ stacktrace-gps@^2.4.3: stacktrace-js@1.3.1: version "1.3.1" - resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-1.3.1.tgz#67cab2589af5c417b962f7369940277bb3b6a18b" + resolved "https://registry.npmjs.org/stacktrace-js/-/stacktrace-js-1.3.1.tgz" integrity sha512-b+5voFnXqg9TWdOE50soXL+WuOreYUm1Ukg9U7rzEWGL4+gcVxIcFasNBtOffVX0I1lYqVZj0PZXZvTt5e3YRQ== dependencies: error-stack-parser "^1.3.6" stack-generator "^1.0.7" stacktrace-gps "^2.4.3" +string_decoder@^1.1.1, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + string-length@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== dependencies: char-regex "^1.0.2" @@ -3998,66 +4032,59 @@ string-length@^4.0.1: string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string_decoder@^1.1.1, string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" strip-bom@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== strip-final-newline@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== supports-color@^5.3.0: version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== dependencies: has-flag "^3.0.0" supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== dependencies: has-flag "^4.0.0" supports-color@^8.0.0: version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== dependencies: has-flag "^4.0.0" supports-hyperlinks@^2.0.0: version "2.3.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" + resolved "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz" integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== dependencies: has-flag "^4.0.0" @@ -4065,12 +4092,12 @@ supports-hyperlinks@^2.0.0: supports-preserve-symlinks-flag@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== tar-fs@^2.1.1: version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== dependencies: chownr "^1.1.1" @@ -4080,7 +4107,7 @@ tar-fs@^2.1.1: tar-fs@~2.0.1: version "2.0.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.1.tgz#e44086c1c60d31a4f0cf893b1c4e155dabfae9e2" + resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.1.tgz" integrity sha512-6tzWDMeroL87uF/+lin46k+Q+46rAJ0SyPGz7OW7wTgblI273hsBqk2C1j0/xNadNLKDTUL9BukSjB7cwgmlPA== dependencies: chownr "^1.1.1" @@ -4090,7 +4117,7 @@ tar-fs@~2.0.1: tar-stream@^2.0.0, tar-stream@^2.1.4, tar-stream@^2.2.0: version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== dependencies: bl "^4.0.3" @@ -4101,7 +4128,7 @@ tar-stream@^2.0.0, tar-stream@^2.1.4, tar-stream@^2.2.0: terminal-link@^2.0.0: version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + resolved "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz" integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== dependencies: ansi-escapes "^4.2.1" @@ -4109,7 +4136,7 @@ terminal-link@^2.0.0: test-exclude@^6.0.0: version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + resolved "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz" integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== dependencies: "@istanbuljs/schema" "^0.1.2" @@ -4118,7 +4145,7 @@ test-exclude@^6.0.0: testcontainers@^9.5.0: version "9.5.0" - resolved "https://registry.yarnpkg.com/testcontainers/-/testcontainers-9.5.0.tgz#a2163ac803dec3944fdc6d433f8005f61274562e" + resolved "https://registry.npmjs.org/testcontainers/-/testcontainers-9.5.0.tgz" integrity sha512-XdLZec7CN8/eXfT/A0zR03J2bNIpwLM3O3kLbp1OZPpZTNtjnR1zsdhS688o2qAx5+FS+xZ8nHL+vm3UBMnfHg== dependencies: "@balena/dockerignore" "^1.0.2" @@ -4138,29 +4165,29 @@ testcontainers@^9.5.0: text-table@^0.2.0: version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== tmpl@1.0.5: version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + resolved "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz" integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== to-fast-properties@^2.0.0: version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + resolved "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== to-regex-range@^5.0.1: version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== dependencies: is-number "^7.0.0" tough-cookie@~2.5.0: version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== dependencies: psl "^1.1.28" @@ -4168,12 +4195,12 @@ tough-cookie@~2.5.0: tr46@~0.0.3: version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== ts-jest@^28.0.8: version "28.0.8" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-28.0.8.tgz#cd204b8e7a2f78da32cf6c95c9a6165c5b99cc73" + resolved "https://registry.npmjs.org/ts-jest/-/ts-jest-28.0.8.tgz" integrity sha512-5FaG0lXmRPzApix8oFG8RKjAz4ehtm8yMKOTy5HX3fY6W8kmvOrmcY0hKDElW52FJov+clhUbrKAqofnj4mXTg== dependencies: bs-logger "0.x" @@ -4185,9 +4212,9 @@ ts-jest@^28.0.8: semver "7.x" yargs-parser "^21.0.1" -ts-node@^10.9.1: +ts-node@^10.9.1, ts-node@>=9.0.0: version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz" integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== dependencies: "@cspotcode/source-map-support" "^0.8.0" @@ -4206,90 +4233,90 @@ ts-node@^10.9.1: tslib@^1.8.1: version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.1.0: version "2.4.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz" integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tslib@^2.5.0, tslib@^2.5.3: version "2.6.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz" integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== tsutils@^3.21.0: version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== dependencies: tslib "^1.8.1" tunnel-agent@^0.6.0: version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + resolved "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz" integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== dependencies: safe-buffer "^5.0.1" tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== tweetnacl@^1.0.3: version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz" integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== dependencies: prelude-ls "^1.2.1" type-detect@4.0.8: version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + resolved "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== type-fest@^0.20.2: version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== type-fest@^0.21.3: version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== type-fest@^0.8.0: version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== typescript-logging@^1.0.0: version "1.0.1" - resolved "https://registry.yarnpkg.com/typescript-logging/-/typescript-logging-1.0.1.tgz#e0f8157943780cf5943aacd53b04cb73d108a0f9" + resolved "https://registry.npmjs.org/typescript-logging/-/typescript-logging-1.0.1.tgz" integrity sha512-zp28ABme0m5q/nXabBaY9Hv/35N8lMH4FsvhpUO0zVi4vFs3uKlb5br2it61HAZF5k+U0aP6E67j0VD0IzXGpQ== dependencies: stacktrace-js "1.3.1" -typescript@^4.7.4: +typescript@^4.7.4, typescript@>=2.7, "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta", typescript@>=4.3: version "4.8.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.4.tgz#c464abca159669597be5f96b8943500b238e60e6" + resolved "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz" integrity sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ== universalify@^0.1.0: version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + resolved "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== update-browserslist-db@^1.0.9: version "1.0.9" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz#2924d3927367a38d5c555413a7ce138fc95fcb18" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz" integrity sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg== dependencies: escalade "^3.1.1" @@ -4297,34 +4324,34 @@ update-browserslist-db@^1.0.9: uri-js@^4.2.2: version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== dependencies: punycode "^2.1.0" util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== uuid@^3.3.2: version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== uuid@^9.0.0: version "9.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== v8-compile-cache-lib@^3.0.1: version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + resolved "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== v8-to-istanbul@^9.0.1: version "9.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz" integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" @@ -4333,7 +4360,7 @@ v8-to-istanbul@^9.0.1: vc-js@^0.6.4: version "0.6.4" - resolved "https://registry.yarnpkg.com/vc-js/-/vc-js-0.6.4.tgz#49f408c590260d28c25a3ca4e30ece0de61c3ae1" + resolved "https://registry.npmjs.org/vc-js/-/vc-js-0.6.4.tgz" integrity sha512-ogwYys94k8mFyFZEn1Ru3nIA5Z/9C4iCU4grNWUYOYVWldcsn6UDp6erYFbaSkilzv7RK3cQu5N8prkxfHpZwA== dependencies: commander "^2.20.3" @@ -4347,7 +4374,7 @@ vc-js@^0.6.4: verror@1.10.0: version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== dependencies: assert-plus "^1.0.0" @@ -4356,24 +4383,24 @@ verror@1.10.0: walker@^1.0.8: version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + resolved "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz" integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== dependencies: makeerror "1.0.12" web-streams-polyfill@^3.0.3: version "3.2.1" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz" integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== webidl-conversions@^3.0.0: version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-url@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" @@ -4381,19 +4408,19 @@ whatwg-url@^5.0.0: which@^2.0.1: version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" word-wrap@^1.2.3: version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== wrap-ansi@^7.0.0: version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" @@ -4402,12 +4429,12 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^4.0.1: version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + resolved "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz" integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== dependencies: imurmurhash "^0.1.4" @@ -4415,47 +4442,47 @@ write-file-atomic@^4.0.1: ws@^8.13.0: version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + resolved "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz" integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== ws@^8.8.1: version "8.9.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.9.0.tgz#2a994bb67144be1b53fe2d23c53c028adeb7f45e" + resolved "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz" integrity sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg== xmldom@0.1.19: version "0.1.19" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.19.tgz#631fc07776efd84118bf25171b37ed4d075a0abc" + resolved "https://registry.npmjs.org/xmldom/-/xmldom-0.1.19.tgz" integrity sha512-pDyxjQSFQgNHkU+yjvoF+GXVGJU7e9EnOg/KcGMDihBIKjTsOeDYaECwC/O9bsUWKY+Sd9izfE43JXC46EOHKA== y18n@^5.0.5: version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== yallist@^3.0.2: version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== yallist@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== yaml@^1.10.2: version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yargs-parser@^21.0.1, yargs-parser@^21.1.1: version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz" integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs@^17.3.1: version "17.7.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz" integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== dependencies: cliui "^8.0.1" @@ -4468,7 +4495,7 @@ yargs@^17.3.1: yargs@^17.7.2: version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" @@ -4481,17 +4508,17 @@ yargs@^17.7.2: yn@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + resolved "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== yocto-queue@^0.1.0: version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== zip-stream@^4.1.0: version "4.1.0" - resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.0.tgz#51dd326571544e36aa3f756430b313576dc8fc79" + resolved "https://registry.npmjs.org/zip-stream/-/zip-stream-4.1.0.tgz" integrity sha512-zshzwQW7gG7hjpBlgeQP9RuyPGNxvJdzR8SUM3QhxCnLjWN2E7j3dOvpeDcQoETfHx0urRS7EtmVToql7YpU4A== dependencies: archiver-utils "^2.1.0" From 7cc83fa8d9d825cc6f66dc10f7a93ea55aa1626c Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Thu, 10 Aug 2023 14:15:45 +0200 Subject: [PATCH 21/39] fmt --- src/utils/TypeGuards.ts | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/utils/TypeGuards.ts b/src/utils/TypeGuards.ts index 322a19e..8ec47c4 100644 --- a/src/utils/TypeGuards.ts +++ b/src/utils/TypeGuards.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -import { IAttestation, ICredentialPresentation } from '@kiltprotocol/types' +import { IAttestation, ICredentialPresentation, IRequestCredentialContent } from '@kiltprotocol/types' import type { IMessage, @@ -7,27 +7,33 @@ import type { IRejectAttestation, IRequestAttestation, IRequestCredential, - IRequestCredentialContent, ISubmitAttestation, ISubmitCredential, ISubmitTerms, } from '../types' export function isIMessage(message: any): message is IMessage { + if ( + typeof message !== 'object' || + !('body' in message) || + !('type' in message.body) || + !('createdAt' in message) || + !('sender' in message) || + !('receiver' in message) || + typeof message.createdAt !== 'number' || + typeof message.sender !== 'string' || + typeof message.receiver !== 'string' + ) { + return false + } + + const { messageId, receivedAt, inReplyTo, references } = message + return ( - typeof message === 'object' && - 'body' in message && - 'type' in message.body && - 'createdAt' in message && - 'sender' in message && - 'receiver' in message && - typeof message.createdAt === 'number' && - typeof message.sender === 'string' && - typeof message.receiver === 'string' && - (typeof message.messageId === 'undefined' || typeof message.messageId === 'string') && - (typeof message.receivedAt === 'undefined' || typeof message.receivedAt === 'number') && - (typeof message.inReplyTo === 'undefined' || typeof message.inReplyTo === 'string') && - (Array.isArray(message.references) || typeof message.references === 'undefined') + (typeof messageId === 'undefined' || typeof messageId === 'string') && + (typeof receivedAt === 'undefined' || typeof receivedAt === 'number') && + (typeof inReplyTo === 'undefined' || typeof inReplyTo === 'string') && + (Array.isArray(references) || typeof references === 'undefined') ) } @@ -54,6 +60,7 @@ export function isSubmitTerms( (cTypes === undefined || Array.isArray(cTypes)) ) } + export function isSubmitAttestation( message: IMessage<{ type: string; content: unknown }> ): message is IMessage { @@ -102,6 +109,7 @@ export function isRequestAttestation(message: IMessage): message is IMessage Date: Thu, 10 Aug 2023 15:52:01 +0200 Subject: [PATCH 22/39] feat: errors --- ...geTypes.ts => CredentialApiMessageType.ts} | 15 ++++----- src/messaging/Error.ts | 19 ++++++++++++ src/messaging/Message.test.ts | 31 ++++++++++--------- src/messaging/MessageEnvelope.ts | 9 +++--- src/messaging/index.ts | 2 +- src/quote/Error.ts | 14 +++++++++ src/quote/Quote.ts | 7 +++-- 7 files changed, 66 insertions(+), 31 deletions(-) rename src/messaging/{CredentialApiMessageTypes.ts => CredentialApiMessageType.ts} (89%) create mode 100644 src/messaging/Error.ts create mode 100644 src/quote/Error.ts diff --git a/src/messaging/CredentialApiMessageTypes.ts b/src/messaging/CredentialApiMessageType.ts similarity index 89% rename from src/messaging/CredentialApiMessageTypes.ts rename to src/messaging/CredentialApiMessageType.ts index b04e18a..ac2788a 100644 --- a/src/messaging/CredentialApiMessageTypes.ts +++ b/src/messaging/CredentialApiMessageType.ts @@ -6,7 +6,7 @@ */ import { Attestation, Claim, Credential, CType, Quote } from '@kiltprotocol/core' -import { DataUtils, SDKErrors } from '@kiltprotocol/utils' +import { DataUtils } from '@kiltprotocol/utils' import * as Did from '@kiltprotocol/did' import { isHex } from '@polkadot/util' @@ -19,6 +19,7 @@ import { isIRequestCredential, } from '../utils' import { verifyMessageEnvelope } from './MessageEnvelope' +import * as MessageError from './Error' import type { IMessage } from '../types' /** @@ -49,7 +50,7 @@ export function verifyMessageBody(message: IMessage): void { Attestation.verifyDataStructure(message.body.content.attestation) } else if (isRejectAttestation(message)) { if (!isHex(message.body.content)) { - throw new SDKErrors.HashMalformedError() + throw new MessageError.HashMalformedError() } } else if (isIRequestCredential(message)) { message.body.content.cTypes.forEach(({ cTypeHash, trustedAttesters, requiredProperties }) => { @@ -63,11 +64,11 @@ export function verifyMessageBody(message: IMessage): void { message.body.content.forEach((presentation) => { Credential.verifyDataStructure(presentation) if (!Did.isDidSignature(presentation.claimerSignature)) { - throw new SDKErrors.SignatureMalformedError() + throw new MessageError.SignatureMalformedError() } }) } else { - throw new SDKErrors.UnknownMessageBodyTypeError() + throw new MessageError.UnknownMessageBodyTypeError() } } @@ -82,16 +83,16 @@ export function verifyMessageBody(message: IMessage): void { export function ensureOwnerIsSender(message: IMessage): void { if (isRequestAttestation(message)) { if (!Did.isSameSubject(message.body.content.credential.claim.owner, message.sender)) { - throw new SDKErrors.IdentityMismatchError('Claim', 'Sender') + throw new MessageError.IdentityMismatchError('Claim', 'Sender') } } else if (isSubmitAttestation(message)) { if (!Did.isSameSubject(message.body.content.attestation.owner, message.sender)) { - throw new SDKErrors.IdentityMismatchError('Attestation', 'Sender') + throw new MessageError.IdentityMismatchError('Attestation', 'Sender') } } else if (isSubmitCredential(message)) { message.body.content.forEach((presentation) => { if (!Did.isSameSubject(presentation.claim.owner, message.sender)) { - throw new SDKErrors.IdentityMismatchError('Claims', 'Sender') + throw new MessageError.IdentityMismatchError('Claims', 'Sender') } }) } diff --git a/src/messaging/Error.ts b/src/messaging/Error.ts new file mode 100644 index 0000000..8b6c873 --- /dev/null +++ b/src/messaging/Error.ts @@ -0,0 +1,19 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +export declare class MessageError extends Error {} + +export declare class HashMalformedError extends MessageError { + constructor(hash?: string, type?: string) +} + +export declare class SignatureMalformedError extends MessageError {} +export declare class UnknownMessageBodyTypeError extends MessageError {} +export declare class DecodingMessageError extends MessageError {} +export declare class IdentityMismatchError extends MessageError { + constructor(context?: string, type?: string) +} diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index e9366ff..042f332 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -10,8 +10,9 @@ import { u8aToHex } from '@polkadot/util' import { Attestation, CType, Claim, Credential, Quote } from '@kiltprotocol/core' import * as Did from '@kiltprotocol/did' -import { init } from '@kiltprotocol/sdk-js' -import { Crypto, SDKErrors } from '@kiltprotocol/utils' +import { SDKErrors, init } from '@kiltprotocol/sdk-js' +import * as MessageError from './Error' +import { Crypto } from '@kiltprotocol/utils' import type { DidDocument, DidKey, @@ -35,7 +36,7 @@ import { } from '../tests' import { fromBody, verifyRequiredCTypeProperties } from './utils' import { decrypt, encrypt, verifyMessageEnvelope } from './MessageEnvelope' -import { ensureOwnerIsSender, verify, verifyMessageBody } from './CredentialApiMessageTypes' +import { ensureOwnerIsSender, verify, verifyMessageBody } from './CredentialApiMessageType' import type { IEncryptedMessage, IMessage, @@ -145,7 +146,7 @@ describe('Messaging', () => { decrypt(encryptedMessageWrongContent, bobEncKey.decrypt, { resolveKey, }) - ).rejects.toThrowError(SDKErrors.DecodingMessageError) + ).rejects.toThrowError(MessageError.DecodingMessageError) const encryptedWrongBody = await aliceEncKey.encrypt(aliceLightDid)({ data: Crypto.coToUInt8('{ wrong JSON'), @@ -219,7 +220,7 @@ describe('Messaging', () => { // Should throw if the sender and the owner are two different entities. expect(() => ensureOwnerIsSender(fromBody(requestAttestationBody, bobFullDid.uri, aliceFullDid.uri))).toThrowError( - SDKErrors.IdentityMismatchError + MessageError.IdentityMismatchError ) const attestation = { @@ -246,7 +247,7 @@ describe('Messaging', () => { // Should throw if the sender and the owner are two different entities. expect(() => ensureOwnerIsSender(fromBody(submitAttestationBody, aliceFullDid.uri, bobFullDid.uri))).toThrowError( - SDKErrors.IdentityMismatchError + MessageError.IdentityMismatchError ) const submitClaimsForCTypeBody: ISubmitCredential = { @@ -268,7 +269,7 @@ describe('Messaging', () => { // Should throw if the sender and the owner are two different entities. expect(() => ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, bobFullDid.uri, aliceFullDid.uri)) - ).toThrowError(SDKErrors.IdentityMismatchError) + ).toThrowError(MessageError.IdentityMismatchError) }) it('verifies the message with sender is the owner (as light DID)', async () => { @@ -377,7 +378,7 @@ describe('Messaging', () => { // Should throw if the sender and the owner are two different entities. expect(() => ensureOwnerIsSender(fromBody(requestAttestationBody, bobLightDid.uri, aliceLightDid.uri)) - ).toThrowError(SDKErrors.IdentityMismatchError) + ).toThrowError(MessageError.IdentityMismatchError) const attestation = { delegationId: null, @@ -427,7 +428,7 @@ describe('Messaging', () => { // Should throw if the sender and the owner are two different entities. expect(() => ensureOwnerIsSender(fromBody(submitAttestationBody, aliceLightDid.uri, bobLightDid.uri))).toThrowError( - SDKErrors.IdentityMismatchError + MessageError.IdentityMismatchError ) const submitClaimsForCTypeBody: ISubmitCredential = { @@ -463,7 +464,7 @@ describe('Messaging', () => { // Should throw if the sender and the owner are two different entities. expect(() => ensureOwnerIsSender(fromBody(submitClaimsForCTypeBody, bobLightDid.uri, aliceLightDid.uri)) - ).toThrowError(SDKErrors.IdentityMismatchError) + ).toThrowError(MessageError.IdentityMismatchError) }) }) @@ -722,7 +723,7 @@ describe('Error checking / Verification', () => { }) it('message body verifier should throw errors on faulty bodies', () => { submitTermsBody.content.delegationId = 'this is not a delegation id' - expect(() => verifyMessageBody(messageSubmitTerms)).toThrowError(SDKErrors.HashMalformedError) + expect(() => verifyMessageBody(messageSubmitTerms)).toThrowError(MessageError.HashMalformedError) submitCredentialBody.content[0].claimerSignature = { signature: 'this is not the claimers signature', @@ -733,17 +734,17 @@ describe('Error checking / Verification', () => { // @ts-ignore submitAttestationBody.content.attestation.claimHash = 'this is not the claim hash' expect(() => verifyMessageBody(messageSubmitAttestationForClaim)).toThrowError( - SDKErrors.UnknownMessageBodyTypeError + MessageError.UnknownMessageBodyTypeError ) // @ts-ignore rejectAttestationForClaimBody.content = 'this is not the root hash' expect(() => verifyMessageBody(messageRejectAttestationForClaim)).toThrowError( - SDKErrors.UnknownMessageBodyTypeError + MessageError.UnknownMessageBodyTypeError ) // @ts-ignore requestCredentialBody.content.cTypes[0].cTypeHash = 'this is not a cTypeHash' - expect(() => verifyMessageBody(messageRequestCredential)).toThrowError(SDKErrors.UnknownMessageBodyTypeError) + expect(() => verifyMessageBody(messageRequestCredential)).toThrowError(MessageError.UnknownMessageBodyTypeError) - expect(() => verifyMessageBody({} as IMessage)).toThrowError(SDKErrors.UnknownMessageBodyTypeError) + expect(() => verifyMessageBody({} as IMessage)).toThrowError(MessageError.UnknownMessageBodyTypeError) }) }) diff --git a/src/messaging/MessageEnvelope.ts b/src/messaging/MessageEnvelope.ts index 49a4af2..8230741 100644 --- a/src/messaging/MessageEnvelope.ts +++ b/src/messaging/MessageEnvelope.ts @@ -8,6 +8,7 @@ import { DecryptCallback, DidResolveKey, DidResourceUri, EncryptCallback } from '@kiltprotocol/types' import * as Did from '@kiltprotocol/did' import { SDKErrors } from '@kiltprotocol/sdk-js' +import * as MessageError from './Error' import { hexToU8a, stringToU8a, u8aToHex, u8aToString } from '@polkadot/util' import type { IEncryptedMessage, IEncryptedMessageContents, IMessage } from '../types' @@ -73,9 +74,7 @@ export async function decrypt( }) ).data } catch (cause) { - throw new SDKErrors.DecodingMessageError(undefined, { - cause: cause as Error, - }) + throw new MessageError.DecodingMessageError(cause) } const decoded = u8aToString(data) @@ -95,7 +94,7 @@ export async function decrypt( } if (sender !== senderKeyDetails.controller) { - throw new SDKErrors.IdentityMismatchError('Encryption key', 'Sender') + throw new MessageError.IdentityMismatchError('Encryption key', 'Sender') } return decrypted @@ -124,7 +123,7 @@ export async function encrypt( ): Promise { const receiverKey = await resolveKey(receiverKeyUri, 'keyAgreement') if (message.receiver !== receiverKey.controller) { - throw new SDKErrors.IdentityMismatchError('receiver public key', 'receiver') + throw new MessageError.IdentityMismatchError('receiver public key', 'receiver') } const toEncrypt: IEncryptedMessageContents = { diff --git a/src/messaging/index.ts b/src/messaging/index.ts index c46e121..0c64b79 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -25,4 +25,4 @@ export * from './utils' export * from './MessageEnvelope' -export * from './CredentialApiMessageTypes' +export * from './CredentialApiMessageType' diff --git a/src/quote/Error.ts b/src/quote/Error.ts new file mode 100644 index 0000000..d99f85b --- /dev/null +++ b/src/quote/Error.ts @@ -0,0 +1,14 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + +export declare class QuoteError extends Error {} + +export declare class HashMalformedError extends QuoteError { + constructor(hash?: string, type?: string) +} + +export declare class QuoteUnverifiableError extends QuoteError {} diff --git a/src/quote/Quote.ts b/src/quote/Quote.ts index d92c7bf..b4012f6 100644 --- a/src/quote/Quote.ts +++ b/src/quote/Quote.ts @@ -24,7 +24,8 @@ import type { DidResolveKey, DidUri, } from '@kiltprotocol/types' -import { Crypto, JsonSchema, SDKErrors } from '@kiltprotocol/utils' +import { Crypto, JsonSchema } from '@kiltprotocol/utils' +import * as QuoteError from './Error' import { resolveKey, verifyDidSignature, signatureToJson, signatureFromJson } from '@kiltprotocol/did' import { QuoteSchema } from './QuoteSchema' @@ -62,7 +63,7 @@ export function validateQuoteSchema(schema: JsonSchema.Schema, validate: unknown */ export async function createAttesterSignedQuote(quoteInput: IQuote, sign: SignCallback): Promise { if (!validateQuoteSchema(QuoteSchema, quoteInput)) { - throw new SDKErrors.QuoteUnverifiableError() + throw new QuoteError.QuoteUnverifiableError() } const signature = await sign({ @@ -102,7 +103,7 @@ export async function verifyAttesterSignedQuote( const messages: string[] = [] if (!validateQuoteSchema(QuoteSchema, basicQuote, messages)) { - throw new SDKErrors.QuoteUnverifiableError() + throw new QuoteError.QuoteUnverifiableError() } } From 0c97d2b05773f0997dabb796eab1ffd9cbc920e6 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Thu, 10 Aug 2023 15:56:22 +0200 Subject: [PATCH 23/39] feat: catch --- src/messaging/MessageEnvelope.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/messaging/MessageEnvelope.ts b/src/messaging/MessageEnvelope.ts index 8230741..d494140 100644 --- a/src/messaging/MessageEnvelope.ts +++ b/src/messaging/MessageEnvelope.ts @@ -74,7 +74,7 @@ export async function decrypt( }) ).data } catch (cause) { - throw new MessageError.DecodingMessageError(cause) + throw new MessageError.DecodingMessageError(cause as string) } const decoded = u8aToString(data) From 6bfd5d8b6b6b03af30c3e82b372bf405c5294270 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Thu, 10 Aug 2023 16:09:00 +0200 Subject: [PATCH 24/39] refactor: errors --- src/messaging/Error.ts | 6 +++++- src/messaging/Message.test.ts | 8 ++++---- src/messaging/MessageEnvelope.ts | 3 +-- src/messaging/utils.ts | 5 +++-- src/quote/Error.ts | 2 ++ src/quote/Quote.test.ts | 11 ++++++----- 6 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/messaging/Error.ts b/src/messaging/Error.ts index 8b6c873..fa9e84c 100644 --- a/src/messaging/Error.ts +++ b/src/messaging/Error.ts @@ -6,7 +6,6 @@ */ export declare class MessageError extends Error {} - export declare class HashMalformedError extends MessageError { constructor(hash?: string, type?: string) } @@ -14,6 +13,11 @@ export declare class HashMalformedError extends MessageError { export declare class SignatureMalformedError extends MessageError {} export declare class UnknownMessageBodyTypeError extends MessageError {} export declare class DecodingMessageError extends MessageError {} +export declare class CTypeUnknownPropertiesError extends MessageError {} +export declare class InvalidDidFormatError extends MessageError {} +export declare class DidError extends MessageError { + constructor(context?: string, type?: string) +} export declare class IdentityMismatchError extends MessageError { constructor(context?: string, type?: string) } diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index 042f332..63ba6df 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -10,7 +10,7 @@ import { u8aToHex } from '@polkadot/util' import { Attestation, CType, Claim, Credential, Quote } from '@kiltprotocol/core' import * as Did from '@kiltprotocol/did' -import { SDKErrors, init } from '@kiltprotocol/sdk-js' +import { init } from '@kiltprotocol/sdk-js' import * as MessageError from './Error' import { Crypto } from '@kiltprotocol/utils' import type { @@ -666,11 +666,11 @@ describe('Error checking / Verification', () => { it('Checking required properties for given CType', () => { expect(() => verifyRequiredCTypeProperties(['id', 'name'], testCType)).toThrowError( - SDKErrors.CTypeUnknownPropertiesError + MessageError.CTypeUnknownPropertiesError ) expect(() => verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties)).not.toThrowError( - SDKErrors.CTypeUnknownPropertiesError + MessageError.CTypeUnknownPropertiesError ) expect(() => verifyRequiredCTypeProperties(['id', 'name'], testCTypeWithMultipleProperties)).not.toThrowError() @@ -707,7 +707,7 @@ describe('Error checking / Verification', () => { it('message envelope verifier should throw errors on faulty envelopes', () => { // @ts-ignore messageSubmitTerms.sender = 'this is not a sender did' - expect(() => verifyMessageEnvelope(messageSubmitTerms)).toThrowError(SDKErrors.InvalidDidFormatError) + expect(() => verifyMessageEnvelope(messageSubmitTerms)).toThrowError(MessageError.InvalidDidFormatError) // @ts-ignore messageRequestAttestationForClaim.messageId = 12 expect(() => verifyMessageEnvelope(messageRequestAttestationForClaim)).toThrowError(TypeError) diff --git a/src/messaging/MessageEnvelope.ts b/src/messaging/MessageEnvelope.ts index d494140..9fae83a 100644 --- a/src/messaging/MessageEnvelope.ts +++ b/src/messaging/MessageEnvelope.ts @@ -7,7 +7,6 @@ import { DecryptCallback, DidResolveKey, DidResourceUri, EncryptCallback } from '@kiltprotocol/types' import * as Did from '@kiltprotocol/did' -import { SDKErrors } from '@kiltprotocol/sdk-js' import * as MessageError from './Error' import { hexToU8a, stringToU8a, u8aToHex, u8aToString } from '@polkadot/util' @@ -60,7 +59,7 @@ export async function decrypt( const { fragment } = Did.parse(receiverKeyUri) if (!fragment) { - throw new SDKErrors.DidError(`No fragment for the receiver key ID "${receiverKeyUri}"`) + throw new MessageError.DidError(`No fragment for the receiver key ID "${receiverKeyUri}"`) } let data: Uint8Array diff --git a/src/messaging/utils.ts b/src/messaging/utils.ts index db56fc7..97d7b14 100644 --- a/src/messaging/utils.ts +++ b/src/messaging/utils.ts @@ -7,7 +7,8 @@ import { ICType } from '@kiltprotocol/types' import { IMessage, MessageBody } from '../types' -import { CType, SDKErrors } from '@kiltprotocol/sdk-js' +import * as MessageError from './Error' +import { CType } from '@kiltprotocol/sdk-js' import { UUID } from '@kiltprotocol/utils' /** @@ -40,6 +41,6 @@ export function verifyRequiredCTypeProperties(requiredProperties: string[], cTyp const unknownProperties = requiredProperties.find((property) => !(property in cType.properties)) if (unknownProperties) { - throw new SDKErrors.CTypeUnknownPropertiesError() + throw new MessageError.CTypeUnknownPropertiesError() } } diff --git a/src/quote/Error.ts b/src/quote/Error.ts index d99f85b..eb27420 100644 --- a/src/quote/Error.ts +++ b/src/quote/Error.ts @@ -12,3 +12,5 @@ export declare class HashMalformedError extends QuoteError { } export declare class QuoteUnverifiableError extends QuoteError {} +export declare class SignatureUnverifiableError extends QuoteError {} +export declare class DidSubjectMismatchError extends QuoteError {} diff --git a/src/quote/Quote.test.ts b/src/quote/Quote.test.ts index 333273e..83d74a5 100644 --- a/src/quote/Quote.test.ts +++ b/src/quote/Quote.test.ts @@ -20,12 +20,13 @@ import type { IQuoteAttesterSigned, ResolvedDidKey, } from '@kiltprotocol/types' -import { Crypto, SDKErrors } from '@kiltprotocol/utils' +import { Crypto } from '@kiltprotocol/utils' import { Credential, CType } from '@kiltprotocol/sdk-js' import { createLocalDemoFullDidFromKeypair, makeSigningKeyTool } from '../tests' import * as Quote from './Quote' import { QuoteSchema } from './QuoteSchema' +import * as QuoteError from './Error' describe('Quote', () => { let claimerIdentity: DidDocument @@ -193,7 +194,7 @@ describe('Quote', () => { Quote.verifyAttesterSignedQuote(messedWithCurrency, { didResolveKey: mockResolveKey, }) - ).rejects.toThrow(SDKErrors.SignatureUnverifiableError) + ).rejects.toThrow(QuoteError.SignatureUnverifiableError) const messedWithRootHash: IQuoteAgreement = { ...quoteBothAgreed, rootHash: '0x1234', @@ -202,7 +203,7 @@ describe('Quote', () => { Quote.verifyQuoteAgreement(messedWithRootHash, { didResolveKey: mockResolveKey, }) - ).rejects.toThrow(SDKErrors.SignatureUnverifiableError) + ).rejects.toThrow(QuoteError.SignatureUnverifiableError) }) it('complains if attesterDid does not match attester signature', async () => { @@ -224,7 +225,7 @@ describe('Quote', () => { Quote.verifyAttesterSignedQuote(wrongSignerAttester, { didResolveKey: mockResolveKey, }) - ).rejects.toThrow(SDKErrors.DidSubjectMismatchError) + ).rejects.toThrow(QuoteError.DidSubjectMismatchError) }) it('complains if claimerDid does not match claimer signature', async () => { @@ -246,6 +247,6 @@ describe('Quote', () => { Quote.verifyQuoteAgreement(wrongSignerClaimer, { didResolveKey: mockResolveKey, }) - ).rejects.toThrow(SDKErrors.DidSubjectMismatchError) + ).rejects.toThrow(QuoteError.DidSubjectMismatchError) }) }) From 878fe28fdba2c01e3572a372b0471c91e6c29062 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Thu, 10 Aug 2023 16:17:29 +0200 Subject: [PATCH 25/39] feat: default type --- src/utils/TypeGuards.ts | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/utils/TypeGuards.ts b/src/utils/TypeGuards.ts index 8ec47c4..4e962de 100644 --- a/src/utils/TypeGuards.ts +++ b/src/utils/TypeGuards.ts @@ -37,9 +37,7 @@ export function isIMessage(message: any): message ) } -export function isSubmitTerms( - message: IMessage<{ type: string; content: unknown }> -): message is IMessage { +export function isSubmitTerms(message: IMessage): message is IMessage { if ( !isIMessage(message) || message.body.type !== 'submit-terms' || @@ -61,9 +59,7 @@ export function isSubmitTerms( ) } -export function isSubmitAttestation( - message: IMessage<{ type: string; content: unknown }> -): message is IMessage { +export function isSubmitAttestation(message: IMessage): message is IMessage { if (!isIMessage(message) || message.body.type !== 'submit-attestation') { return false } @@ -91,9 +87,7 @@ export function isIAttestation(body: any): body is IAttestation { ) } -export function isRejectAttestation( - message: IMessage<{ type: string; content: unknown }> -): message is IMessage { +export function isRejectAttestation(message: IMessage): message is IMessage { return ( isIMessage(message) && message.body.type === 'reject-attestation' && @@ -118,9 +112,7 @@ export function isRequestAttestation(message: IMessage): message is IMessage -): message is IMessage { +export function isIRequestCredential(message: IMessage): message is IMessage { return ( isIMessage(message) && message.body.type === 'request-credential' && @@ -153,9 +145,7 @@ export function isIRequestCredentialContent(body: any): body is IRequestCredenti return true } -export function isSubmitCredential( - message: IMessage<{ type: string; content: unknown }> -): message is IMessage { +export function isSubmitCredential(message: IMessage): message is IMessage { return ( isIMessage(message) && message.body.type === 'submit-credential' && From 1aa812a8482b8641c297902b984c84586cb6215d Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Fri, 11 Aug 2023 09:51:30 +0200 Subject: [PATCH 26/39] newline --- src/quote/Quote.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/quote/Quote.test.ts b/src/quote/Quote.test.ts index 83d74a5..e93bbbf 100644 --- a/src/quote/Quote.test.ts +++ b/src/quote/Quote.test.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable @typescript-eslint/ban-ts-comment */ + /** * Copyright (c) 2018-2023, BOTLabs GmbH. * From 792dc5d514524b0d302cca1f4458d62646525713 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Fri, 11 Aug 2023 09:55:28 +0200 Subject: [PATCH 27/39] refactor: change return type --- src/messaging/CredentialApiMessageType.ts | 3 ++- src/tests/index.ts | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/messaging/CredentialApiMessageType.ts b/src/messaging/CredentialApiMessageType.ts index ac2788a..ac81073 100644 --- a/src/messaging/CredentialApiMessageType.ts +++ b/src/messaging/CredentialApiMessageType.ts @@ -104,8 +104,9 @@ export function ensureOwnerIsSender(message: IMessage): void { * * @param decryptedMessage The decrypted message to check. */ -export function verify(decryptedMessage: IMessage): void { +export function assertKnownMessage(decryptedMessage: IMessage): IMessage['body'] { verifyMessageBody(decryptedMessage) verifyMessageEnvelope(decryptedMessage) ensureOwnerIsSender(decryptedMessage) + return decryptedMessage.body } diff --git a/src/tests/index.ts b/src/tests/index.ts index 68a3e17..bf4c9a1 100644 --- a/src/tests/index.ts +++ b/src/tests/index.ts @@ -1,2 +1,9 @@ +/** + * Copyright (c) 2018-2023, BOTLabs GmbH. + * + * This source code is licensed under the BSD 4-Clause "Original" license + * found in the LICENSE file in the root directory of this source tree. + */ + export * from './messageUtils' export * from './utils' From 1b23e4c4aaf2d88f8f1f7e7532022f12dde4abdc Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Mon, 14 Aug 2023 12:51:04 +0200 Subject: [PATCH 28/39] fmt --- src/types/Imported.ts | 6 +----- src/types/Message.ts | 43 ++++++++++++++++++++++++------------------- src/types/Quote.ts | 3 +-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/types/Imported.ts b/src/types/Imported.ts index f832284..6026d8b 100644 --- a/src/types/Imported.ts +++ b/src/types/Imported.ts @@ -5,11 +5,7 @@ * found in the LICENSE file in the root directory of this source tree. */ -export type { - ISubmittableResult, - AnyNumber, - AnyJson, -} from '@polkadot/types/types' +export type { ISubmittableResult, AnyNumber, AnyJson } from '@polkadot/types/types' export type { BN } from '@polkadot/util' export type { HexString } from '@polkadot/util/types' export type { Prefix } from '@polkadot/util-crypto/address/types' diff --git a/src/types/Message.ts b/src/types/Message.ts index f9de4d7..93c7511 100644 --- a/src/types/Message.ts +++ b/src/types/Message.ts @@ -1,4 +1,14 @@ -import type { ICredential, ICredentialPresentation, IAttestation, CTypeHash, DidResourceUri, DidUri, IDelegationNode, PartialClaim, ICType } from '@kiltprotocol/types' +import type { + ICredential, + ICredentialPresentation, + IAttestation, + CTypeHash, + DidResourceUri, + DidUri, + IDelegationNode, + PartialClaim, + ICType, +} from '@kiltprotocol/types' import type { IQuoteAgreement, IQuoteAttesterSigned } from './Quote' /** @@ -30,12 +40,11 @@ export type MessageBodyType = | 'submit-credential' | 'reject-terms' -export interface IMessageBodyBase { +export interface IMessageBodyBase { content: Content type: Type } - /** * - `body` - The body of the message, see [[MessageBody]]. * - `createdAt` - The timestamp of the message construction. @@ -46,7 +55,7 @@ export interface IMessageBodyBase { +export interface IMessage { body: Body createdAt: number sender: DidUri @@ -61,19 +70,18 @@ export interface IMessage; +export type IError = IMessageBodyBase<'error', { name?: string; message?: string }> /** * Rejection messages signal the intentional cancelling of an individual step in the flow. */ -export type IReject = IMessageBodyBase<'reject', {name? : string, message?: string}>; +export type IReject = IMessageBodyBase<'reject', { name?: string; message?: string }> /** * An attester utilizes the message to propose a claim. The purpose of the extension is to enable * the user to authorize and endorse the claims prepared by the attester. */ -export type ISubmitTerms = IMessageBodyBase<'submit-terms', ITerms>; - +export type ISubmitTerms = IMessageBodyBase<'submit-terms', ITerms> /** * The content of the [IRequestAttestation] message. @@ -90,7 +98,6 @@ export interface IRequestAttestationContent { */ export type IRequestAttestation = IMessageBodyBase<'request-attestation', IRequestAttestationContent> - /** * The content of the [IRequestPayment] message. */ @@ -104,7 +111,6 @@ export interface IRequestPaymentContent { */ export type IRequestPayment = IMessageBodyBase<'request-payment', IRequestPaymentContent> - /** * The content of the [ISubmitAttestation] message. */ @@ -117,15 +123,11 @@ export interface ISubmitAttestationContent { */ export type ISubmitAttestation = IMessageBodyBase<'submit-attestation', ISubmitAttestationContent> - /** * If the attester does not approve the attestation request, the extension receives the [IRejectAttestation] message. */ export type IRejectAttestation = IMessageBodyBase<'reject-attestation', ICredential['rootHash']> - - - /** * The content of the [ISubmitTerms] message. */ @@ -141,7 +143,6 @@ export interface ITerms { cTypes?: ICType[] } - /** Message to submit credentials from the extension or dapp.*/ export type ISubmitCredential = IMessageBodyBase<'submit-credential', ICredentialPresentation[]> @@ -159,7 +160,6 @@ export interface IRequestCredentialContent { export type IRequestCredential = IMessageBodyBase<'request-credential', IRequestCredentialContent> - /** * The content of the [IConfirmPayment] message. */ @@ -172,7 +172,6 @@ export interface IConfirmPaymentContent { blockHash: string } - /** * After the user has authorized the payment and it has been transferred, * the extension confirms the transfer to the attester by sending the [IConfirmPayment] message. @@ -182,7 +181,10 @@ export type IConfirmPayment = IMessageBodyBase<'confirm-payment', IConfirmPaymen /** * Everything which is part of the encrypted and protected part of the [[IMessage]]. */ -export type IEncryptedMessageContents = Omit, 'receivedAt'> +export type IEncryptedMessageContents = Omit< + IMessage, + 'receivedAt' +> /** * Removes the plaintext [[IEncryptedMessageContents]] from an [[IMessage]] and instead includes them in encrypted form. @@ -192,7 +194,10 @@ export type IEncryptedMessageContents = Pick, 'receivedAt'> & { +export type IEncryptedMessage = Pick< + IMessage, + 'receivedAt' +> & { receiverKeyUri: DidResourceUri senderKeyUri: DidResourceUri ciphertext: string diff --git a/src/types/Quote.ts b/src/types/Quote.ts index b6e94e2..6450650 100644 --- a/src/types/Quote.ts +++ b/src/types/Quote.ts @@ -28,7 +28,7 @@ export interface IQuote { * Signed quote from attester */ export interface IQuoteAttesterSigned extends IQuote { - // Signature of the attester + // Signature of the attester attesterSignature: DidSignature } @@ -42,4 +42,3 @@ export interface IQuoteAgreement extends IQuoteAttesterSigned { // The signature of the claimer. claimerSignature: DidSignature } - From b0bb518a2225564520a064a3023849b2e91811b7 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Mon, 14 Aug 2023 12:53:19 +0200 Subject: [PATCH 29/39] fix tests --- src/messaging/Message.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index 63ba6df..b507b98 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -36,7 +36,7 @@ import { } from '../tests' import { fromBody, verifyRequiredCTypeProperties } from './utils' import { decrypt, encrypt, verifyMessageEnvelope } from './MessageEnvelope' -import { ensureOwnerIsSender, verify, verifyMessageBody } from './CredentialApiMessageType' +import { ensureOwnerIsSender, assertKnownMessage, verifyMessageBody } from './CredentialApiMessageType' import type { IEncryptedMessage, IMessage, @@ -133,7 +133,7 @@ describe('Messaging', () => { const decryptedMessage = await decrypt(encryptedMessage, bobEncKey.decrypt, { resolveKey }) expect(JSON.stringify(message.body)).toEqual(JSON.stringify(decryptedMessage.body)) - expect(() => verify(decryptedMessage)).not.toThrow() + expect(() => assertKnownMessage(decryptedMessage)).not.toThrow() const encryptedMessageWrongContent = JSON.parse( JSON.stringify(encryptedMessage) From c76cc9b2ad4581a298e5e2384c03463ff48d6731 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Mon, 21 Aug 2023 17:23:52 +0200 Subject: [PATCH 30/39] change response --- src/messaging/CredentialApiMessageType.ts | 11 ++++++---- src/messaging/Message.test.ts | 26 +++++++++++------------ 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/messaging/CredentialApiMessageType.ts b/src/messaging/CredentialApiMessageType.ts index ac81073..635fab9 100644 --- a/src/messaging/CredentialApiMessageType.ts +++ b/src/messaging/CredentialApiMessageType.ts @@ -20,14 +20,14 @@ import { } from '../utils' import { verifyMessageEnvelope } from './MessageEnvelope' import * as MessageError from './Error' -import type { IMessage } from '../types' +import type { IMessage, MessageBody } from '../types' /** * Checks if the message body is well-formed. * * @param body The message body. */ -export function verifyMessageBody(message: IMessage): void { +export function isKnownMessageBody(message: IMessage): message is IMessage { if (isSubmitTerms(message)) { const { body } = message Claim.verifyDataStructure(body.content.claim) @@ -70,6 +70,7 @@ export function verifyMessageBody(message: IMessage): void { } else { throw new MessageError.UnknownMessageBodyTypeError() } + return true } /** @@ -104,8 +105,10 @@ export function ensureOwnerIsSender(message: IMessage): void { * * @param decryptedMessage The decrypted message to check. */ -export function assertKnownMessage(decryptedMessage: IMessage): IMessage['body'] { - verifyMessageBody(decryptedMessage) +export function assertKnownMessage(decryptedMessage: IMessage): IMessage['body'] { + if (!isKnownMessageBody(decryptedMessage)) { + throw new MessageError.UnknownMessageBodyTypeError() + } verifyMessageEnvelope(decryptedMessage) ensureOwnerIsSender(decryptedMessage) return decryptedMessage.body diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index b507b98..897950e 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -36,7 +36,7 @@ import { } from '../tests' import { fromBody, verifyRequiredCTypeProperties } from './utils' import { decrypt, encrypt, verifyMessageEnvelope } from './MessageEnvelope' -import { ensureOwnerIsSender, assertKnownMessage, verifyMessageBody } from './CredentialApiMessageType' +import { ensureOwnerIsSender, assertKnownMessage, isKnownMessageBody } from './CredentialApiMessageType' import type { IEncryptedMessage, IMessage, @@ -687,13 +687,13 @@ describe('Error checking / Verification', () => { messageSubmitCredential = fromBody(submitCredentialBody, identityAlice.uri, identityBob.uri) }) it('message body verifier should not throw errors on correct bodies', () => { - expect(() => verifyMessageBody(messageSubmitTerms)).not.toThrowError() + expect(() => isKnownMessageBody(messageSubmitTerms)).not.toThrowError() - expect(() => verifyMessageBody(messageRequestAttestationForClaim)).not.toThrowError() - expect(() => verifyMessageBody(messageSubmitAttestationForClaim)).not.toThrowError() - expect(() => verifyMessageBody(messageRejectAttestationForClaim)).not.toThrowError() - expect(() => verifyMessageBody(messageRequestCredential)).not.toThrowError() - expect(() => verifyMessageBody(messageSubmitCredential)).not.toThrowError() + expect(() => isKnownMessageBody(messageRequestAttestationForClaim)).not.toThrowError() + expect(() => isKnownMessageBody(messageSubmitAttestationForClaim)).not.toThrowError() + expect(() => isKnownMessageBody(messageRejectAttestationForClaim)).not.toThrowError() + expect(() => isKnownMessageBody(messageRequestCredential)).not.toThrowError() + expect(() => isKnownMessageBody(messageSubmitCredential)).not.toThrowError() }) it('message envelope verifier should not throw errors on correct envelopes', () => { @@ -723,28 +723,28 @@ describe('Error checking / Verification', () => { }) it('message body verifier should throw errors on faulty bodies', () => { submitTermsBody.content.delegationId = 'this is not a delegation id' - expect(() => verifyMessageBody(messageSubmitTerms)).toThrowError(MessageError.HashMalformedError) + expect(() => isKnownMessageBody(messageSubmitTerms)).toThrowError(MessageError.HashMalformedError) submitCredentialBody.content[0].claimerSignature = { signature: 'this is not the claimers signature', // @ts-ignore keyUri: 'this is not a key id', } - expect(() => verifyMessageBody(messageSubmitCredential)).toThrowError() + expect(() => isKnownMessageBody(messageSubmitCredential)).toThrowError() // @ts-ignore submitAttestationBody.content.attestation.claimHash = 'this is not the claim hash' - expect(() => verifyMessageBody(messageSubmitAttestationForClaim)).toThrowError( + expect(() => isKnownMessageBody(messageSubmitAttestationForClaim)).toThrowError( MessageError.UnknownMessageBodyTypeError ) // @ts-ignore rejectAttestationForClaimBody.content = 'this is not the root hash' - expect(() => verifyMessageBody(messageRejectAttestationForClaim)).toThrowError( + expect(() => isKnownMessageBody(messageRejectAttestationForClaim)).toThrowError( MessageError.UnknownMessageBodyTypeError ) // @ts-ignore requestCredentialBody.content.cTypes[0].cTypeHash = 'this is not a cTypeHash' - expect(() => verifyMessageBody(messageRequestCredential)).toThrowError(MessageError.UnknownMessageBodyTypeError) + expect(() => isKnownMessageBody(messageRequestCredential)).toThrowError(MessageError.UnknownMessageBodyTypeError) - expect(() => verifyMessageBody({} as IMessage)).toThrowError(MessageError.UnknownMessageBodyTypeError) + expect(() => isKnownMessageBody({} as IMessage)).toThrowError(MessageError.UnknownMessageBodyTypeError) }) }) From dfaafcdc9cf68ef2a9b111183104cb4c795dc49e Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Tue, 22 Aug 2023 13:30:26 +0200 Subject: [PATCH 31/39] fix tests --- src/messaging/CredentialApiMessageType.ts | 11 ++++----- src/messaging/Message.test.ts | 28 ++++++++++++----------- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/messaging/CredentialApiMessageType.ts b/src/messaging/CredentialApiMessageType.ts index 635fab9..0f9237b 100644 --- a/src/messaging/CredentialApiMessageType.ts +++ b/src/messaging/CredentialApiMessageType.ts @@ -27,7 +27,7 @@ import type { IMessage, MessageBody } from '../types' * * @param body The message body. */ -export function isKnownMessageBody(message: IMessage): message is IMessage { +export function assertKnownMessageBody(message: IMessage): void { if (isSubmitTerms(message)) { const { body } = message Claim.verifyDataStructure(body.content.claim) @@ -70,7 +70,6 @@ export function isKnownMessageBody(message: IMessage): message is IMessage['body'] { - if (!isKnownMessageBody(decryptedMessage)) { - throw new MessageError.UnknownMessageBodyTypeError() - } +export function assertKnownMessage(decryptedMessage: IMessage): MessageBody { + assertKnownMessageBody(decryptedMessage) verifyMessageEnvelope(decryptedMessage) ensureOwnerIsSender(decryptedMessage) - return decryptedMessage.body + return decryptedMessage.body as MessageBody } diff --git a/src/messaging/Message.test.ts b/src/messaging/Message.test.ts index 897950e..1d726cc 100644 --- a/src/messaging/Message.test.ts +++ b/src/messaging/Message.test.ts @@ -36,7 +36,7 @@ import { } from '../tests' import { fromBody, verifyRequiredCTypeProperties } from './utils' import { decrypt, encrypt, verifyMessageEnvelope } from './MessageEnvelope' -import { ensureOwnerIsSender, assertKnownMessage, isKnownMessageBody } from './CredentialApiMessageType' +import { ensureOwnerIsSender, assertKnownMessage, assertKnownMessageBody } from './CredentialApiMessageType' import type { IEncryptedMessage, IMessage, @@ -687,13 +687,13 @@ describe('Error checking / Verification', () => { messageSubmitCredential = fromBody(submitCredentialBody, identityAlice.uri, identityBob.uri) }) it('message body verifier should not throw errors on correct bodies', () => { - expect(() => isKnownMessageBody(messageSubmitTerms)).not.toThrowError() + expect(() => assertKnownMessageBody(messageSubmitTerms)).not.toThrowError() - expect(() => isKnownMessageBody(messageRequestAttestationForClaim)).not.toThrowError() - expect(() => isKnownMessageBody(messageSubmitAttestationForClaim)).not.toThrowError() - expect(() => isKnownMessageBody(messageRejectAttestationForClaim)).not.toThrowError() - expect(() => isKnownMessageBody(messageRequestCredential)).not.toThrowError() - expect(() => isKnownMessageBody(messageSubmitCredential)).not.toThrowError() + expect(() => assertKnownMessageBody(messageRequestAttestationForClaim)).not.toThrowError() + expect(() => assertKnownMessageBody(messageSubmitAttestationForClaim)).not.toThrowError() + expect(() => assertKnownMessageBody(messageRejectAttestationForClaim)).not.toThrowError() + expect(() => assertKnownMessageBody(messageRequestCredential)).not.toThrowError() + expect(() => assertKnownMessageBody(messageSubmitCredential)).not.toThrowError() }) it('message envelope verifier should not throw errors on correct envelopes', () => { @@ -723,28 +723,30 @@ describe('Error checking / Verification', () => { }) it('message body verifier should throw errors on faulty bodies', () => { submitTermsBody.content.delegationId = 'this is not a delegation id' - expect(() => isKnownMessageBody(messageSubmitTerms)).toThrowError(MessageError.HashMalformedError) + expect(() => assertKnownMessageBody(messageSubmitTerms)).toThrowError(MessageError.HashMalformedError) submitCredentialBody.content[0].claimerSignature = { signature: 'this is not the claimers signature', // @ts-ignore keyUri: 'this is not a key id', } - expect(() => isKnownMessageBody(messageSubmitCredential)).toThrowError() + expect(() => assertKnownMessageBody(messageSubmitCredential)).toThrowError() // @ts-ignore submitAttestationBody.content.attestation.claimHash = 'this is not the claim hash' - expect(() => isKnownMessageBody(messageSubmitAttestationForClaim)).toThrowError( + expect(() => assertKnownMessageBody(messageSubmitAttestationForClaim)).toThrowError( MessageError.UnknownMessageBodyTypeError ) // @ts-ignore rejectAttestationForClaimBody.content = 'this is not the root hash' - expect(() => isKnownMessageBody(messageRejectAttestationForClaim)).toThrowError( + expect(() => assertKnownMessageBody(messageRejectAttestationForClaim)).toThrowError( MessageError.UnknownMessageBodyTypeError ) // @ts-ignore requestCredentialBody.content.cTypes[0].cTypeHash = 'this is not a cTypeHash' - expect(() => isKnownMessageBody(messageRequestCredential)).toThrowError(MessageError.UnknownMessageBodyTypeError) + expect(() => assertKnownMessageBody(messageRequestCredential)).toThrowError( + MessageError.UnknownMessageBodyTypeError + ) - expect(() => isKnownMessageBody({} as IMessage)).toThrowError(MessageError.UnknownMessageBodyTypeError) + expect(() => assertKnownMessageBody({} as IMessage)).toThrowError(MessageError.UnknownMessageBodyTypeError) }) }) From 22073b287c2e5ef8d5d4a2f07201f65861ff04ab Mon Sep 17 00:00:00 2001 From: Adel Golghalyani <48685760+Ad96el@users.noreply.github.com> Date: Tue, 22 Aug 2023 15:01:46 +0200 Subject: [PATCH 32/39] namespace Co-authored-by: Raphael Flechtner <39338561+rflechtner@users.noreply.github.com> --- src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2286ada..5a01c74 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,3 +1,3 @@ export { getExtensions, watchExtensions, initializeKiltExtensionAPI } from './getExtension' -export * from './messaging' -export * from './quote' +export * as Message from './messaging' +export * as Quote from './quote' From e06c1ecee069939a21d1324cb5dbc0b44fa48399 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 23 Aug 2023 11:10:52 +0200 Subject: [PATCH 33/39] do not export verifyMessageEnvelope --- src/messaging/MessageEnvelope.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/messaging/MessageEnvelope.ts b/src/messaging/MessageEnvelope.ts index 9fae83a..cf1bbd2 100644 --- a/src/messaging/MessageEnvelope.ts +++ b/src/messaging/MessageEnvelope.ts @@ -17,7 +17,7 @@ import type { IEncryptedMessage, IEncryptedMessageContents, IMessage } from '../ * * @param message The message object. */ -export function verifyMessageEnvelope(message: IMessage): void { +function verifyMessageEnvelope(message: IMessage): void { const { messageId, createdAt, receiver, sender, receivedAt, inReplyTo } = message if (messageId !== undefined && typeof messageId !== 'string') { throw new TypeError('Message id is expected to be a string') @@ -92,6 +92,7 @@ export async function decrypt( references, } + verifyMessageEnvelope(decrypted) if (sender !== senderKeyDetails.controller) { throw new MessageError.IdentityMismatchError('Encryption key', 'Sender') } @@ -120,6 +121,7 @@ export async function encrypt( resolveKey?: DidResolveKey } = {} ): Promise { + verifyMessageEnvelope(message) const receiverKey = await resolveKey(receiverKeyUri, 'keyAgreement') if (message.receiver !== receiverKey.controller) { throw new MessageError.IdentityMismatchError('receiver public key', 'receiver') From 0a2ffb99c122c17f358bd9701cf0754cbc2e8027 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 23 Aug 2023 11:13:37 +0200 Subject: [PATCH 34/39] reduce interface --- src/messaging/index.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/messaging/index.ts b/src/messaging/index.ts index 0c64b79..d444b93 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -23,6 +23,7 @@ * found in the LICENSE file in the root directory of this source tree. */ -export * from './utils' +export { fromBody } from './utils' export * from './MessageEnvelope' -export * from './CredentialApiMessageType' +export { assertKnownMessage } from './CredentialApiMessageType' +export * from './Error' From 3969f723cc55bd834d102e1261fe33b4b2246d64 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 23 Aug 2023 12:53:13 +0200 Subject: [PATCH 35/39] change body type --- src/messaging/MessageEnvelope.ts | 2 +- src/messaging/index.ts | 2 +- src/messaging/utils.ts | 9 +++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/messaging/MessageEnvelope.ts b/src/messaging/MessageEnvelope.ts index cf1bbd2..8834c75 100644 --- a/src/messaging/MessageEnvelope.ts +++ b/src/messaging/MessageEnvelope.ts @@ -17,7 +17,7 @@ import type { IEncryptedMessage, IEncryptedMessageContents, IMessage } from '../ * * @param message The message object. */ -function verifyMessageEnvelope(message: IMessage): void { +export function verifyMessageEnvelope(message: IMessage): void { const { messageId, createdAt, receiver, sender, receivedAt, inReplyTo } = message if (messageId !== undefined && typeof messageId !== 'string') { throw new TypeError('Message id is expected to be a string') diff --git a/src/messaging/index.ts b/src/messaging/index.ts index d444b93..9be1f71 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -24,6 +24,6 @@ */ export { fromBody } from './utils' -export * from './MessageEnvelope' +export { encrypt, decrypt } from './MessageEnvelope' export { assertKnownMessage } from './CredentialApiMessageType' export * from './Error' diff --git a/src/messaging/utils.ts b/src/messaging/utils.ts index 97d7b14..c71a2c7 100644 --- a/src/messaging/utils.ts +++ b/src/messaging/utils.ts @@ -6,7 +6,7 @@ */ import { ICType } from '@kiltprotocol/types' -import { IMessage, MessageBody } from '../types' +import { IMessage, IMessageBodyBase } from '../types' import * as MessageError from './Error' import { CType } from '@kiltprotocol/sdk-js' import { UUID } from '@kiltprotocol/utils' @@ -20,7 +20,12 @@ import { UUID } from '@kiltprotocol/utils' * @param receiver The DID of the receiver. * @returns The message created. */ -export function fromBody(body: MessageBody, sender: IMessage['sender'], receiver: IMessage['receiver']): IMessage { + +export function fromBody( + body: Body, + sender: IMessage['sender'], + receiver: IMessage['receiver'] +): IMessage { return { body, createdAt: Date.now(), From b5316c59a2e5c29e62eecdad852eda451d6abb89 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 23 Aug 2023 16:23:58 +0200 Subject: [PATCH 36/39] remove comments --- src/messaging/index.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/messaging/index.ts b/src/messaging/index.ts index 9be1f71..706886b 100644 --- a/src/messaging/index.ts +++ b/src/messaging/index.ts @@ -10,17 +10,6 @@ * * All messages are **encrypted** with the encryption keys of the involved identities. * Messages are encrypted using authenticated encryption: the two parties authenticate to each other, but the message authentication provides repudiation possibilities. - * - * The [[Message]] class exposes methods to construct and verify messages. - * - * @module @kiltprotocol/messaging - */ - -/** - * Copyright (c) 2018-2023, BOTLabs GmbH. - * - * This source code is licensed under the BSD 4-Clause "Original" license - * found in the LICENSE file in the root directory of this source tree. */ export { fromBody } from './utils' From 64f5d520fd2b092d5549199aedcfa49274db9ea8 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Wed, 23 Aug 2023 16:24:23 +0200 Subject: [PATCH 37/39] message body --- src/messaging/utils.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/messaging/utils.ts b/src/messaging/utils.ts index c71a2c7..9eaf68e 100644 --- a/src/messaging/utils.ts +++ b/src/messaging/utils.ts @@ -6,7 +6,7 @@ */ import { ICType } from '@kiltprotocol/types' -import { IMessage, IMessageBodyBase } from '../types' +import { IMessage, MessageBody } from '../types' import * as MessageError from './Error' import { CType } from '@kiltprotocol/sdk-js' import { UUID } from '@kiltprotocol/utils' @@ -21,11 +21,11 @@ import { UUID } from '@kiltprotocol/utils' * @returns The message created. */ -export function fromBody( - body: Body, +export function fromBody( + body: MessageBody, sender: IMessage['sender'], receiver: IMessage['receiver'] -): IMessage { +): IMessage { return { body, createdAt: Date.now(), From 7d348a036e45e46627abe0693ed3080b841d5885 Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Thu, 24 Aug 2023 13:37:59 +0200 Subject: [PATCH 38/39] from body generic --- src/messaging/utils.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/messaging/utils.ts b/src/messaging/utils.ts index 9eaf68e..9052498 100644 --- a/src/messaging/utils.ts +++ b/src/messaging/utils.ts @@ -21,11 +21,11 @@ import { UUID } from '@kiltprotocol/utils' * @returns The message created. */ -export function fromBody( - body: MessageBody, +export function fromBody( + body: Body, sender: IMessage['sender'], receiver: IMessage['receiver'] -): IMessage { +): IMessage { return { body, createdAt: Date.now(), From a93d11054e6275f556670f92f40169417e71550b Mon Sep 17 00:00:00 2001 From: Adel Golghalyani Date: Tue, 29 Aug 2023 11:05:47 +0200 Subject: [PATCH 39/39] refactor types --- src/messaging/CredentialApiMessageType.ts | 6 ++--- src/types/Message.ts | 30 +++++++++++------------ src/utils/TypeGuards.ts | 4 +-- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/messaging/CredentialApiMessageType.ts b/src/messaging/CredentialApiMessageType.ts index 0f9237b..7c7c037 100644 --- a/src/messaging/CredentialApiMessageType.ts +++ b/src/messaging/CredentialApiMessageType.ts @@ -20,7 +20,7 @@ import { } from '../utils' import { verifyMessageEnvelope } from './MessageEnvelope' import * as MessageError from './Error' -import type { IMessage, MessageBody } from '../types' +import type { IMessage, CredentialApiMessageBody } from '../types' /** * Checks if the message body is well-formed. @@ -104,9 +104,9 @@ export function ensureOwnerIsSender(message: IMessage): void { * * @param decryptedMessage The decrypted message to check. */ -export function assertKnownMessage(decryptedMessage: IMessage): MessageBody { +export function assertKnownMessage(decryptedMessage: IMessage): CredentialApiMessageBody { assertKnownMessageBody(decryptedMessage) verifyMessageEnvelope(decryptedMessage) ensureOwnerIsSender(decryptedMessage) - return decryptedMessage.body as MessageBody + return decryptedMessage.body as CredentialApiMessageBody } diff --git a/src/types/Message.ts b/src/types/Message.ts index 93c7511..8ea125d 100644 --- a/src/types/Message.ts +++ b/src/types/Message.ts @@ -15,7 +15,7 @@ import type { IQuoteAgreement, IQuoteAttesterSigned } from './Quote' * All possible message types which are defined in the KILT Credential API (Spec version 3.2) * https://github.com/KILTprotocol/spec-ext-credential-api */ -export type MessageBody = +export type CredentialApiMessageBody = | IError | IReject | ISubmitTerms @@ -40,7 +40,7 @@ export type MessageBodyType = | 'submit-credential' | 'reject-terms' -export interface IMessageBodyBase { +export interface MessageBody { content: Content type: Type } @@ -55,7 +55,7 @@ export interface IMessageBodyBase { +export interface IMessage { body: Body createdAt: number sender: DidUri @@ -70,18 +70,18 @@ export interface IMessage +export type IError = MessageBody<'error', { name?: string; message?: string }> /** * Rejection messages signal the intentional cancelling of an individual step in the flow. */ -export type IReject = IMessageBodyBase<'reject', { name?: string; message?: string }> +export type IReject = MessageBody<'reject', { name?: string; message?: string }> /** * An attester utilizes the message to propose a claim. The purpose of the extension is to enable * the user to authorize and endorse the claims prepared by the attester. */ -export type ISubmitTerms = IMessageBodyBase<'submit-terms', ITerms> +export type ISubmitTerms = MessageBody<'submit-terms', ITerms> /** * The content of the [IRequestAttestation] message. @@ -96,7 +96,7 @@ export interface IRequestAttestationContent { * The extension only sends the request with active consent of the user. This is the first step * where the user’s DID is revealed to the dApp. */ -export type IRequestAttestation = IMessageBodyBase<'request-attestation', IRequestAttestationContent> +export type IRequestAttestation = MessageBody<'request-attestation', IRequestAttestationContent> /** * The content of the [IRequestPayment] message. @@ -109,7 +109,7 @@ export interface IRequestPaymentContent { /** * An attester can send this message if it wants the user to transfer payment in KILT Coins by themselves without interrupting the flow. */ -export type IRequestPayment = IMessageBodyBase<'request-payment', IRequestPaymentContent> +export type IRequestPayment = MessageBody<'request-payment', IRequestPaymentContent> /** * The content of the [ISubmitAttestation] message. @@ -121,12 +121,12 @@ export interface ISubmitAttestationContent { /** * The attester sends the valid credential to the extension. */ -export type ISubmitAttestation = IMessageBodyBase<'submit-attestation', ISubmitAttestationContent> +export type ISubmitAttestation = MessageBody<'submit-attestation', ISubmitAttestationContent> /** * If the attester does not approve the attestation request, the extension receives the [IRejectAttestation] message. */ -export type IRejectAttestation = IMessageBodyBase<'reject-attestation', ICredential['rootHash']> +export type IRejectAttestation = MessageBody<'reject-attestation', ICredential['rootHash']> /** * The content of the [ISubmitTerms] message. @@ -144,7 +144,7 @@ export interface ITerms { } /** Message to submit credentials from the extension or dapp.*/ -export type ISubmitCredential = IMessageBodyBase<'submit-credential', ICredentialPresentation[]> +export type ISubmitCredential = MessageBody<'submit-credential', ICredentialPresentation[]> /** * The content of the [IRequestCredential] message. @@ -158,7 +158,7 @@ export interface IRequestCredentialContent { challenge?: string } -export type IRequestCredential = IMessageBodyBase<'request-credential', IRequestCredentialContent> +export type IRequestCredential = MessageBody<'request-credential', IRequestCredentialContent> /** * The content of the [IConfirmPayment] message. @@ -176,12 +176,12 @@ export interface IConfirmPaymentContent { * After the user has authorized the payment and it has been transferred, * the extension confirms the transfer to the attester by sending the [IConfirmPayment] message. */ -export type IConfirmPayment = IMessageBodyBase<'confirm-payment', IConfirmPaymentContent> +export type IConfirmPayment = MessageBody<'confirm-payment', IConfirmPaymentContent> /** * Everything which is part of the encrypted and protected part of the [[IMessage]]. */ -export type IEncryptedMessageContents = Omit< +export type IEncryptedMessageContents = Omit< IMessage, 'receivedAt' > @@ -194,7 +194,7 @@ export type IEncryptedMessageContents = Pick< +export type IEncryptedMessage = Pick< IMessage, 'receivedAt' > & { diff --git a/src/utils/TypeGuards.ts b/src/utils/TypeGuards.ts index 4e962de..dccf2d5 100644 --- a/src/utils/TypeGuards.ts +++ b/src/utils/TypeGuards.ts @@ -3,7 +3,7 @@ import { IAttestation, ICredentialPresentation, IRequestCredentialContent } from import type { IMessage, - IMessageBodyBase, + MessageBody, IRejectAttestation, IRequestAttestation, IRequestCredential, @@ -12,7 +12,7 @@ import type { ISubmitTerms, } from '../types' -export function isIMessage(message: any): message is IMessage { +export function isIMessage(message: any): message is IMessage { if ( typeof message !== 'object' || !('body' in message) ||