diff --git a/.eslintrc.js b/.eslintrc.js index c669beed73..51535e4a4d 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -99,7 +99,7 @@ module.exports = { }, }, { - files: ['demo/**'], + files: ['demo/**', 'demo-openid/**'], rules: { 'no-console': 'off', }, @@ -112,6 +112,7 @@ module.exports = { 'jest.*.ts', 'samples/**', 'demo/**', + 'demo-openid/**', 'scripts/**', '**/tests/**', ], diff --git a/.gitignore b/.gitignore index 4d15c7409b..f28d97e7c3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,9 @@ build .vscode yarn-error.log .idea +credo-*.tgz +# Keeping this one in for now to prevent accidental +# old build still in the local repository getting pushed aries-framework-*.tgz coverage .DS_Store diff --git a/README.md b/README.md index 8f8ee6c0c2..3c765712d7 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ See [Supported Features](https://credo.js.org/guides/features) on the Credo webs - @aries-framework/indy-vdr + @credo-ts/indy-vdr @credo-ts/indy-vdr version @@ -125,10 +125,10 @@ See [Supported Features](https://credo.js.org/guides/features) on the Credo webs - @credo-ts/openid4vc-client + @credo-ts/openid4vc - - @credo-ts/openid4vc-client version + + @credo-ts/openid4vc version @@ -171,6 +171,14 @@ See [Supported Features](https://credo.js.org/guides/features) on the Credo webs + + @credo-ts/openid4vc-client (deprecated in favour of @credo-ts/openid4vc) + + + @credo-ts/openid4vc-client version + + + ## Getting Started diff --git a/demo-openid/README.md b/demo-openid/README.md new file mode 100644 index 0000000000..d5c5f22620 --- /dev/null +++ b/demo-openid/README.md @@ -0,0 +1,89 @@ +

DEMO

+ +This is the Credo OpenID4VC demo. Walk through the Credo flow yourself together with agents Alice and Faber. + +Alice, a former student of Faber College, connects with the College, is issued a credential about her degree and then is asked by the College for a proof. + +## Features + +- ✅ Creating a connection +- ✅ Offering a credential +- ✅ Requesting a proof +- ✅ Sending basic messages + +## Getting Started + +### Platform Specific Setup + +In order to use Credo some platform specific dependencies and setup is required. See our guides below to quickly set up you project with Credo for NodeJS, React Native. + +- [NodeJS](https://credo.js.org/guides/getting-started/installation/nodejs) + +### Run the demo + +These are the steps for running the Credo OpenID4VC demo: + +Clone the Credo git repository: + +```sh +git clone https://github.com/openwallet-foundation/credo-ts.git +``` + +Open two different terminals next to each other and in both, go to the demo folder: + +```sh +cd credo-ts/demo-openid +``` + +Install the project in one of the terminals: + +```sh +yarn install +``` + +In the left terminal run Alice: + +```sh +yarn alice +``` + +In the right terminal run Faber: + +```sh +yarn faber +``` + +### Usage + +To set up a connection: + +- Select 'receive connection invitation' in Alice and 'create connection invitation' in Faber +- Faber will print a invitation link which you then copy and paste to Alice +- You have now set up a connection! + +To offer a credential: + +- Select 'offer credential' in Faber +- Faber will start with registering a schema and the credential definition accordingly +- You have now send a credential offer to Alice! +- Go to Alice to accept the incoming credential offer by selecting 'yes'. + +To request a proof: + +- Select 'request proof' in Faber +- Faber will create a new proof attribute and will then send a proof request to Alice! +- Go to Alice to accept the incoming proof request + +To send a basic message: + +- Select 'send message' in either one of the Agents +- Type your message and press enter +- Message sent! + +Exit: + +- Select 'exit' to shutdown the agent. + +Restart: + +- Select 'restart', to shutdown the current agent and start a new one diff --git a/demo-openid/package.json b/demo-openid/package.json new file mode 100644 index 0000000000..e6fa775559 --- /dev/null +++ b/demo-openid/package.json @@ -0,0 +1,36 @@ +{ + "name": "afj-demo-openid", + "version": "1.0.0", + "private": true, + "repository": { + "type": "git", + "url": "https://github.com/openwallet-foundation/credo-ts", + "directory": "demo-openid" + }, + "license": "Apache-2.0", + "scripts": { + "issuer": "ts-node src/IssuerInquirer.ts", + "holder": "ts-node src/HolderInquirer.ts", + "verifier": "ts-node src/VerifierInquirer.ts", + "refresh": "rm -rf ./node_modules ./yarn.lock && yarn" + }, + "dependencies": { + "@hyperledger/anoncreds-nodejs": "^0.2.0-dev.9", + "@hyperledger/aries-askar-nodejs": "^0.2.0-dev.6", + "@hyperledger/indy-vdr-nodejs": "^0.2.0-dev.6", + "express": "^4.18.1", + "inquirer": "^8.2.5" + }, + "devDependencies": { + "@credo-ts/openid4vc": "*", + "@credo-ts/askar": "*", + "@credo-ts/core": "*", + "@credo-ts/node": "*", + "@types/express": "^4.17.13", + "@types/figlet": "^1.5.4", + "@types/inquirer": "^8.2.6", + "clear": "^0.1.0", + "figlet": "^1.5.2", + "ts-node": "^10.4.0" + } +} diff --git a/demo-openid/src/BaseAgent.ts b/demo-openid/src/BaseAgent.ts new file mode 100644 index 0000000000..f0c79a4e86 --- /dev/null +++ b/demo-openid/src/BaseAgent.ts @@ -0,0 +1,61 @@ +import type { InitConfig, KeyDidCreateOptions, ModulesMap, VerificationMethod } from '@credo-ts/core' +import type { Express } from 'express' + +import { Agent, DidKey, HttpOutboundTransport, KeyType, TypedArrayEncoder } from '@credo-ts/core' +import { HttpInboundTransport, agentDependencies } from '@credo-ts/node' +import express from 'express' + +import { greenText } from './OutputClass' + +export class BaseAgent { + public app: Express + public port: number + public name: string + public config: InitConfig + public agent: Agent + public did!: string + public didKey!: DidKey + public kid!: string + public verificationMethod!: VerificationMethod + + public constructor({ port, name, modules }: { port: number; name: string; modules: AgentModules }) { + this.name = name + this.port = port + this.app = express() + + const config = { + label: name, + walletConfig: { id: name, key: name }, + } satisfies InitConfig + + this.config = config + + this.agent = new Agent({ config, dependencies: agentDependencies, modules }) + + const httpInboundTransport = new HttpInboundTransport({ app: this.app, port: this.port }) + const httpOutboundTransport = new HttpOutboundTransport() + + this.agent.registerInboundTransport(httpInboundTransport) + this.agent.registerOutboundTransport(httpOutboundTransport) + } + + public async initializeAgent(secretPrivateKey: string) { + await this.agent.initialize() + + const didCreateResult = await this.agent.dids.create({ + method: 'key', + options: { keyType: KeyType.Ed25519 }, + secret: { privateKey: TypedArrayEncoder.fromString(secretPrivateKey) }, + }) + + this.did = didCreateResult.didState.did as string + this.didKey = DidKey.fromDid(this.did) + this.kid = `${this.did}#${this.didKey.key.fingerprint}` + + const verificationMethod = didCreateResult.didState.didDocument?.dereferenceKey(this.kid, ['authentication']) + if (!verificationMethod) throw new Error('No verification method found') + this.verificationMethod = verificationMethod + + console.log(greenText(`\nAgent ${this.name} created!\n`)) + } +} diff --git a/demo-openid/src/BaseInquirer.ts b/demo-openid/src/BaseInquirer.ts new file mode 100644 index 0000000000..358d72b632 --- /dev/null +++ b/demo-openid/src/BaseInquirer.ts @@ -0,0 +1,55 @@ +import { prompt } from 'inquirer' + +import { Title } from './OutputClass' + +export enum ConfirmOptions { + Yes = 'yes', + No = 'no', +} + +export class BaseInquirer { + public optionsInquirer: { type: string; prefix: string; name: string; message: string; choices: string[] } + public inputInquirer: { type: string; prefix: string; name: string; message: string; choices: string[] } + + public constructor() { + this.optionsInquirer = { + type: 'list', + prefix: '', + name: 'options', + message: '', + choices: [], + } + + this.inputInquirer = { + type: 'input', + prefix: '', + name: 'input', + message: '', + choices: [], + } + } + + public inquireOptions(promptOptions: string[]) { + this.optionsInquirer.message = Title.OptionsTitle + this.optionsInquirer.choices = promptOptions + return this.optionsInquirer + } + + public inquireInput(title: string) { + this.inputInquirer.message = title + return this.inputInquirer + } + + public inquireConfirmation(title: string) { + this.optionsInquirer.message = title + this.optionsInquirer.choices = [ConfirmOptions.Yes, ConfirmOptions.No] + return this.optionsInquirer + } + + public async inquireMessage() { + this.inputInquirer.message = Title.MessageTitle + const message = await prompt([this.inputInquirer]) + + return message.input[0] === 'q' ? null : message.input + } +} diff --git a/demo-openid/src/Holder.ts b/demo-openid/src/Holder.ts new file mode 100644 index 0000000000..762ce5ee31 --- /dev/null +++ b/demo-openid/src/Holder.ts @@ -0,0 +1,101 @@ +import type { OpenId4VciResolvedCredentialOffer, OpenId4VcSiopResolvedAuthorizationRequest } from '@credo-ts/openid4vc' + +import { AskarModule } from '@credo-ts/askar' +import { + W3cJwtVerifiableCredential, + W3cJsonLdVerifiableCredential, + DifPresentationExchangeService, +} from '@credo-ts/core' +import { OpenId4VcHolderModule } from '@credo-ts/openid4vc' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' + +import { BaseAgent } from './BaseAgent' +import { Output } from './OutputClass' + +function getOpenIdHolderModules() { + return { + askar: new AskarModule({ ariesAskar }), + openId4VcHolder: new OpenId4VcHolderModule(), + } as const +} + +export class Holder extends BaseAgent> { + public constructor(port: number, name: string) { + super({ port, name, modules: getOpenIdHolderModules() }) + } + + public static async build(): Promise { + const holder = new Holder(3000, 'OpenId4VcHolder ' + Math.random().toString()) + await holder.initializeAgent('96213c3d7fc8d4d6754c7a0fd969598e') + + return holder + } + + public async resolveCredentialOffer(credentialOffer: string) { + return await this.agent.modules.openId4VcHolder.resolveCredentialOffer(credentialOffer) + } + + public async requestAndStoreCredentials( + resolvedCredentialOffer: OpenId4VciResolvedCredentialOffer, + credentialsToRequest: string[] + ) { + const credentials = await this.agent.modules.openId4VcHolder.acceptCredentialOfferUsingPreAuthorizedCode( + resolvedCredentialOffer, + { + credentialsToRequest, + // TODO: add jwk support for holder binding + credentialBindingResolver: async () => ({ + method: 'did', + didUrl: this.verificationMethod.id, + }), + } + ) + + const storedCredentials = await Promise.all( + credentials.map((credential) => { + if (credential instanceof W3cJwtVerifiableCredential || credential instanceof W3cJsonLdVerifiableCredential) { + return this.agent.w3cCredentials.storeCredential({ credential }) + } else { + return this.agent.sdJwtVc.store(credential.compact) + } + }) + ) + + return storedCredentials + } + + public async resolveProofRequest(proofRequest: string) { + const resolvedProofRequest = await this.agent.modules.openId4VcHolder.resolveSiopAuthorizationRequest(proofRequest) + + return resolvedProofRequest + } + + public async acceptPresentationRequest(resolvedPresentationRequest: OpenId4VcSiopResolvedAuthorizationRequest) { + const presentationExchangeService = this.agent.dependencyManager.resolve(DifPresentationExchangeService) + + if (!resolvedPresentationRequest.presentationExchange) { + throw new Error('Missing presentation exchange on resolved authorization request') + } + + const submissionResult = await this.agent.modules.openId4VcHolder.acceptSiopAuthorizationRequest({ + authorizationRequest: resolvedPresentationRequest.authorizationRequest, + presentationExchange: { + credentials: presentationExchangeService.selectCredentialsForRequest( + resolvedPresentationRequest.presentationExchange.credentialsForRequest + ), + }, + }) + + return submissionResult.serverResponse + } + + public async exit() { + console.log(Output.Exit) + await this.agent.shutdown() + process.exit(0) + } + + public async restart() { + await this.agent.shutdown() + } +} diff --git a/demo-openid/src/HolderInquirer.ts b/demo-openid/src/HolderInquirer.ts new file mode 100644 index 0000000000..899ffca1fc --- /dev/null +++ b/demo-openid/src/HolderInquirer.ts @@ -0,0 +1,198 @@ +import type { SdJwtVcRecord, W3cCredentialRecord } from '@credo-ts/core/src' +import type { OpenId4VcSiopResolvedAuthorizationRequest, OpenId4VciResolvedCredentialOffer } from '@credo-ts/openid4vc' + +import { DifPresentationExchangeService } from '@credo-ts/core/src' +import console, { clear } from 'console' +import { textSync } from 'figlet' +import { prompt } from 'inquirer' + +import { BaseInquirer, ConfirmOptions } from './BaseInquirer' +import { Holder } from './Holder' +import { Title, greenText, redText } from './OutputClass' + +export const runHolder = async () => { + clear() + console.log(textSync('Holder', { horizontalLayout: 'full' })) + const holder = await HolderInquirer.build() + await holder.processAnswer() +} + +enum PromptOptions { + ResolveCredentialOffer = 'Resolve a credential offer.', + RequestCredential = 'Accept the credential offer.', + ResolveProofRequest = 'Resolve a proof request.', + AcceptPresentationRequest = 'Accept the presentation request.', + Exit = 'Exit', + Restart = 'Restart', +} + +export class HolderInquirer extends BaseInquirer { + public holder: Holder + public resolvedCredentialOffer?: OpenId4VciResolvedCredentialOffer + public resolvedPresentationRequest?: OpenId4VcSiopResolvedAuthorizationRequest + + public constructor(holder: Holder) { + super() + this.holder = holder + } + + public static async build(): Promise { + const holder = await Holder.build() + return new HolderInquirer(holder) + } + + private async getPromptChoice() { + const promptOptions = [PromptOptions.ResolveCredentialOffer, PromptOptions.ResolveProofRequest] + + if (this.resolvedCredentialOffer) promptOptions.push(PromptOptions.RequestCredential) + if (this.resolvedPresentationRequest) promptOptions.push(PromptOptions.AcceptPresentationRequest) + + return prompt([this.inquireOptions(promptOptions.map((o) => o.valueOf()))]) + } + + public async processAnswer() { + const choice = await this.getPromptChoice() + + switch (choice.options) { + case PromptOptions.ResolveCredentialOffer: + await this.resolveCredentialOffer() + break + case PromptOptions.RequestCredential: + await this.requestCredential() + break + case PromptOptions.ResolveProofRequest: + await this.resolveProofRequest() + break + case PromptOptions.AcceptPresentationRequest: + await this.acceptPresentationRequest() + break + case PromptOptions.Exit: + await this.exit() + break + case PromptOptions.Restart: + await this.restart() + return + } + await this.processAnswer() + } + + public async exitUseCase(title: string) { + const confirm = await prompt([this.inquireConfirmation(title)]) + if (confirm.options === ConfirmOptions.No) { + return false + } else if (confirm.options === ConfirmOptions.Yes) { + return true + } + } + + public async resolveCredentialOffer() { + const credentialOffer = await prompt([this.inquireInput('Enter credential offer: ')]) + const resolvedCredentialOffer = await this.holder.resolveCredentialOffer(credentialOffer.input) + this.resolvedCredentialOffer = resolvedCredentialOffer + + console.log(greenText(`Received credential offer for the following credentials.`)) + console.log(greenText(resolvedCredentialOffer.offeredCredentials.map((credential) => credential.id).join('\n'))) + } + + public async requestCredential() { + if (!this.resolvedCredentialOffer) { + throw new Error('No credential offer resolved yet.') + } + + const credentialsThatCanBeRequested = this.resolvedCredentialOffer.offeredCredentials.map( + (credential) => credential.id + ) + + const choice = await prompt([this.inquireOptions(credentialsThatCanBeRequested)]) + + const credentialToRequest = this.resolvedCredentialOffer.offeredCredentials.find( + (credential) => credential.id === choice.options + ) + if (!credentialToRequest) throw new Error('Credential to request not found.') + + console.log(greenText(`Requesting the following credential '${credentialToRequest.id}'`)) + + const credentials = await this.holder.requestAndStoreCredentials( + this.resolvedCredentialOffer, + this.resolvedCredentialOffer.offeredCredentials.map((o) => o.id) + ) + + console.log(greenText(`Received and stored the following credentials.`)) + console.log('') + credentials.forEach(this.printCredential) + } + + public async resolveProofRequest() { + const proofRequestUri = await prompt([this.inquireInput('Enter proof request: ')]) + this.resolvedPresentationRequest = await this.holder.resolveProofRequest(proofRequestUri.input) + + const presentationDefinition = this.resolvedPresentationRequest?.presentationExchange?.definition + console.log(greenText(`Presentation Purpose: '${presentationDefinition?.purpose}'`)) + + if (this.resolvedPresentationRequest?.presentationExchange?.credentialsForRequest.areRequirementsSatisfied) { + const selectedCredentials = Object.values( + this.holder.agent.dependencyManager + .resolve(DifPresentationExchangeService) + .selectCredentialsForRequest(this.resolvedPresentationRequest.presentationExchange.credentialsForRequest) + ).flatMap((e) => e) + console.log( + greenText( + `All requirements for creating the presentation are satisfied. The following credentials will be shared`, + true + ) + ) + selectedCredentials.forEach(this.printCredential) + } else { + console.log(redText(`No credentials available that satisfy the proof request.`)) + } + } + + public async acceptPresentationRequest() { + if (!this.resolvedPresentationRequest) throw new Error('No presentation request resolved yet.') + + console.log(greenText(`Accepting the presentation request.`)) + + const serverResponse = await this.holder.acceptPresentationRequest(this.resolvedPresentationRequest) + + if (serverResponse.status >= 200 && serverResponse.status < 300) { + console.log(`received success status code '${serverResponse.status}'`) + } else { + console.log(`received error status code '${serverResponse.status}'`) + } + } + + public async exit() { + const confirm = await prompt([this.inquireConfirmation(Title.ConfirmTitle)]) + if (confirm.options === ConfirmOptions.No) { + return + } else if (confirm.options === ConfirmOptions.Yes) { + await this.holder.exit() + } + } + + public async restart() { + const confirm = await prompt([this.inquireConfirmation(Title.ConfirmTitle)]) + if (confirm.options === ConfirmOptions.No) { + await this.processAnswer() + return + } else if (confirm.options === ConfirmOptions.Yes) { + await this.holder.restart() + await runHolder() + } + } + + private printCredential = (credential: W3cCredentialRecord | SdJwtVcRecord) => { + if (credential.type === 'W3cCredentialRecord') { + console.log(greenText(`W3cCredentialRecord with claim format ${credential.credential.claimFormat}`, true)) + console.log(JSON.stringify(credential.credential.jsonCredential, null, 2)) + console.log('') + } else { + console.log(greenText(`SdJwtVcRecord`, true)) + const prettyClaims = this.holder.agent.sdJwtVc.fromCompact(credential.compactSdJwtVc).prettyClaims + console.log(JSON.stringify(prettyClaims, null, 2)) + console.log('') + } + } +} + +void runHolder() diff --git a/demo-openid/src/Issuer.ts b/demo-openid/src/Issuer.ts new file mode 100644 index 0000000000..2189f7858c --- /dev/null +++ b/demo-openid/src/Issuer.ts @@ -0,0 +1,181 @@ +import type { DidKey } from '@credo-ts/core' +import type { + OpenId4VcCredentialHolderBinding, + OpenId4VcCredentialHolderDidBinding, + OpenId4VciCredentialRequestToCredentialMapper, + OpenId4VciCredentialSupportedWithId, + OpenId4VcIssuerRecord, +} from '@credo-ts/openid4vc' + +import { AskarModule } from '@credo-ts/askar' +import { + ClaimFormat, + parseDid, + CredoError, + W3cCredential, + W3cCredentialSubject, + W3cIssuer, + w3cDate, +} from '@credo-ts/core' +import { OpenId4VcIssuerModule, OpenId4VciCredentialFormatProfile } from '@credo-ts/openid4vc' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' +import { Router } from 'express' + +import { BaseAgent } from './BaseAgent' +import { Output } from './OutputClass' + +export const universityDegreeCredential = { + id: 'UniversityDegreeCredential', + format: OpenId4VciCredentialFormatProfile.JwtVcJson, + types: ['VerifiableCredential', 'UniversityDegreeCredential'], +} satisfies OpenId4VciCredentialSupportedWithId + +export const openBadgeCredential = { + id: 'OpenBadgeCredential', + format: OpenId4VciCredentialFormatProfile.JwtVcJson, + types: ['VerifiableCredential', 'OpenBadgeCredential'], +} satisfies OpenId4VciCredentialSupportedWithId + +export const universityDegreeCredentialSdJwt = { + id: 'UniversityDegreeCredential-sdjwt', + format: OpenId4VciCredentialFormatProfile.SdJwtVc, + vct: 'UniversityDegreeCredential', +} satisfies OpenId4VciCredentialSupportedWithId + +export const credentialsSupported = [ + universityDegreeCredential, + openBadgeCredential, + universityDegreeCredentialSdJwt, +] satisfies OpenId4VciCredentialSupportedWithId[] + +function getCredentialRequestToCredentialMapper({ + issuerDidKey, +}: { + issuerDidKey: DidKey +}): OpenId4VciCredentialRequestToCredentialMapper { + return async ({ holderBinding, credentialsSupported }) => { + const credentialSupported = credentialsSupported[0] + + if (credentialSupported.id === universityDegreeCredential.id) { + assertDidBasedHolderBinding(holderBinding) + + return { + format: ClaimFormat.JwtVc, + credential: new W3cCredential({ + type: universityDegreeCredential.types, + issuer: new W3cIssuer({ + id: issuerDidKey.did, + }), + credentialSubject: new W3cCredentialSubject({ + id: parseDid(holderBinding.didUrl).did, + }), + issuanceDate: w3cDate(Date.now()), + }), + verificationMethod: `${issuerDidKey.did}#${issuerDidKey.key.fingerprint}`, + } + } + + if (credentialSupported.id === openBadgeCredential.id) { + assertDidBasedHolderBinding(holderBinding) + + return { + format: ClaimFormat.JwtVc, + credential: new W3cCredential({ + type: openBadgeCredential.types, + issuer: new W3cIssuer({ + id: issuerDidKey.did, + }), + credentialSubject: new W3cCredentialSubject({ + id: parseDid(holderBinding.didUrl).did, + }), + issuanceDate: w3cDate(Date.now()), + }), + verificationMethod: `${issuerDidKey.did}#${issuerDidKey.key.fingerprint}`, + } + } + + if (credentialSupported.id === universityDegreeCredentialSdJwt.id) { + return { + format: ClaimFormat.SdJwtVc, + payload: { vct: universityDegreeCredentialSdJwt.vct, university: 'innsbruck', degree: 'bachelor' }, + holder: holderBinding, + issuer: { + method: 'did', + didUrl: `${issuerDidKey.did}#${issuerDidKey.key.fingerprint}`, + }, + disclosureFrame: { university: true, degree: true }, + } + } + + throw new Error('Invalid request') + } +} + +export class Issuer extends BaseAgent<{ + askar: AskarModule + openId4VcIssuer: OpenId4VcIssuerModule +}> { + public issuerRecord!: OpenId4VcIssuerRecord + + public constructor(port: number, name: string) { + const openId4VciRouter = Router() + + super({ + port, + name, + modules: { + askar: new AskarModule({ ariesAskar }), + openId4VcIssuer: new OpenId4VcIssuerModule({ + baseUrl: 'http://localhost:2000/oid4vci', + router: openId4VciRouter, + endpoints: { + credential: { + credentialRequestToCredentialMapper: (...args) => + getCredentialRequestToCredentialMapper({ issuerDidKey: this.didKey })(...args), + }, + }, + }), + }, + }) + + this.app.use('/oid4vci', openId4VciRouter) + } + + public static async build(): Promise { + const issuer = new Issuer(2000, 'OpenId4VcIssuer ' + Math.random().toString()) + await issuer.initializeAgent('96213c3d7fc8d4d6754c7a0fd969598f') + issuer.issuerRecord = await issuer.agent.modules.openId4VcIssuer.createIssuer({ + credentialsSupported, + }) + + return issuer + } + + public async createCredentialOffer(offeredCredentials: string[]) { + const { credentialOffer } = await this.agent.modules.openId4VcIssuer.createCredentialOffer({ + issuerId: this.issuerRecord.issuerId, + offeredCredentials, + preAuthorizedCodeFlowConfig: { userPinRequired: false }, + }) + + return credentialOffer + } + + public async exit() { + console.log(Output.Exit) + await this.agent.shutdown() + process.exit(0) + } + + public async restart() { + await this.agent.shutdown() + } +} + +function assertDidBasedHolderBinding( + holderBinding: OpenId4VcCredentialHolderBinding +): asserts holderBinding is OpenId4VcCredentialHolderDidBinding { + if (holderBinding.method !== 'did') { + throw new CredoError('Only did based holder bindings supported for this credential type') + } +} diff --git a/demo-openid/src/IssuerInquirer.ts b/demo-openid/src/IssuerInquirer.ts new file mode 100644 index 0000000000..dca38ed86a --- /dev/null +++ b/demo-openid/src/IssuerInquirer.ts @@ -0,0 +1,88 @@ +import { clear } from 'console' +import { textSync } from 'figlet' +import { prompt } from 'inquirer' + +import { BaseInquirer, ConfirmOptions } from './BaseInquirer' +import { Issuer, credentialsSupported } from './Issuer' +import { Title, purpleText } from './OutputClass' + +export const runIssuer = async () => { + clear() + console.log(textSync('Issuer', { horizontalLayout: 'full' })) + const issuer = await IssuerInquirer.build() + await issuer.processAnswer() +} + +enum PromptOptions { + CreateCredentialOffer = 'Create a credential offer', + Exit = 'Exit', + Restart = 'Restart', +} + +export class IssuerInquirer extends BaseInquirer { + public issuer: Issuer + public promptOptionsString: string[] + + public constructor(issuer: Issuer) { + super() + this.issuer = issuer + this.promptOptionsString = Object.values(PromptOptions) + } + + public static async build(): Promise { + const issuer = await Issuer.build() + return new IssuerInquirer(issuer) + } + + private async getPromptChoice() { + return prompt([this.inquireOptions(this.promptOptionsString)]) + } + + public async processAnswer() { + const choice = await this.getPromptChoice() + + switch (choice.options) { + case PromptOptions.CreateCredentialOffer: + await this.createCredentialOffer() + break + case PromptOptions.Exit: + await this.exit() + break + case PromptOptions.Restart: + await this.restart() + return + } + await this.processAnswer() + } + + public async createCredentialOffer() { + const choice = await prompt([this.inquireOptions(credentialsSupported.map((credential) => credential.id))]) + const offeredCredential = credentialsSupported.find((credential) => credential.id === choice.options) + if (!offeredCredential) throw new Error(`No credential of type ${choice.options} found, that can be offered.`) + const offerRequest = await this.issuer.createCredentialOffer([offeredCredential.id]) + + console.log(purpleText(`credential offer: '${offerRequest}'`)) + } + + public async exit() { + const confirm = await prompt([this.inquireConfirmation(Title.ConfirmTitle)]) + if (confirm.options === ConfirmOptions.No) { + return + } else if (confirm.options === ConfirmOptions.Yes) { + await this.issuer.exit() + } + } + + public async restart() { + const confirm = await prompt([this.inquireConfirmation(Title.ConfirmTitle)]) + if (confirm.options === ConfirmOptions.No) { + await this.processAnswer() + return + } else if (confirm.options === ConfirmOptions.Yes) { + await this.issuer.restart() + await runIssuer() + } + } +} + +void runIssuer() diff --git a/demo-openid/src/OutputClass.ts b/demo-openid/src/OutputClass.ts new file mode 100644 index 0000000000..b9e69c72f0 --- /dev/null +++ b/demo-openid/src/OutputClass.ts @@ -0,0 +1,40 @@ +export enum Color { + Green = `\x1b[32m`, + Red = `\x1b[31m`, + Purple = `\x1b[35m`, + Reset = `\x1b[0m`, +} + +export enum Output { + NoConnectionRecordFromOutOfBand = `\nNo connectionRecord has been created from invitation\n`, + ConnectionEstablished = `\nConnection established!`, + MissingConnectionRecord = `\nNo connectionRecord ID has been set yet\n`, + ConnectionLink = `\nRun 'Receive connection invitation' in Alice and paste this invitation link:\n\n`, + Exit = 'Shutting down agent...\nExiting...', +} + +export enum Title { + OptionsTitle = '\nOptions:', + InvitationTitle = '\n\nPaste the invitation url here:', + MessageTitle = '\n\nWrite your message here:\n(Press enter to send or press q to exit)\n', + ConfirmTitle = '\n\nAre you sure?', + CredentialOfferTitle = '\n\nCredential offer received, do you want to accept it?', + ProofRequestTitle = '\n\nProof request received, do you want to accept it?', +} + +export const greenText = (text: string, reset?: boolean) => { + if (reset) return Color.Green + text + Color.Reset + + return Color.Green + text +} + +export const purpleText = (text: string, reset?: boolean) => { + if (reset) return Color.Purple + text + Color.Reset + return Color.Purple + text +} + +export const redText = (text: string, reset?: boolean) => { + if (reset) return Color.Red + text + Color.Reset + + return Color.Red + text +} diff --git a/demo-openid/src/Verifier.ts b/demo-openid/src/Verifier.ts new file mode 100644 index 0000000000..6a89b71cbc --- /dev/null +++ b/demo-openid/src/Verifier.ts @@ -0,0 +1,114 @@ +import type { DifPresentationExchangeDefinitionV2 } from '@credo-ts/core/src' +import type { OpenId4VcVerifierRecord } from '@credo-ts/openid4vc' + +import { AskarModule } from '@credo-ts/askar' +import { OpenId4VcVerifierModule } from '@credo-ts/openid4vc' +import { ariesAskar } from '@hyperledger/aries-askar-nodejs' +import { Router } from 'express' + +import { BaseAgent } from './BaseAgent' +import { Output } from './OutputClass' + +const universityDegreePresentationDefinition = { + id: 'UniversityDegreeCredential', + purpose: 'Present your UniversityDegreeCredential to verify your education level.', + input_descriptors: [ + { + id: 'UniversityDegreeCredentialDescriptor', + constraints: { + fields: [ + { + // Works for JSON-LD, SD-JWT and JWT + path: ['$.vc.type.*', '$.vct', '$.type'], + filter: { + type: 'string', + pattern: 'UniversityDegree', + }, + }, + ], + }, + }, + ], +} + +const openBadgeCredentialPresentationDefinition = { + id: 'OpenBadgeCredential', + purpose: 'Provide proof of employment to confirm your employment status.', + input_descriptors: [ + { + id: 'OpenBadgeCredentialDescriptor', + constraints: { + fields: [ + { + // Works for JSON-LD, SD-JWT and JWT + path: ['$.vc.type.*', '$.vct', '$.type'], + filter: { + type: 'string', + pattern: 'OpenBadgeCredential', + }, + }, + ], + }, + }, + ], +} + +export const presentationDefinitions = [ + universityDegreePresentationDefinition, + openBadgeCredentialPresentationDefinition, +] + +export class Verifier extends BaseAgent<{ askar: AskarModule; openId4VcVerifier: OpenId4VcVerifierModule }> { + public verifierRecord!: OpenId4VcVerifierRecord + + public constructor(port: number, name: string) { + const openId4VcSiopRouter = Router() + + super({ + port, + name, + modules: { + askar: new AskarModule({ ariesAskar }), + openId4VcVerifier: new OpenId4VcVerifierModule({ + baseUrl: 'http://localhost:4000/siop', + }), + }, + }) + + this.app.use('/siop', openId4VcSiopRouter) + } + + public static async build(): Promise { + const verifier = new Verifier(4000, 'OpenId4VcVerifier ' + Math.random().toString()) + await verifier.initializeAgent('96213c3d7fc8d4d6754c7a0fd969598g') + verifier.verifierRecord = await verifier.agent.modules.openId4VcVerifier.createVerifier() + + return verifier + } + + // TODO: add method to show the received presentation submission + public async createProofRequest(presentationDefinition: DifPresentationExchangeDefinitionV2) { + const { authorizationRequestUri } = await this.agent.modules.openId4VcVerifier.createAuthorizationRequest({ + requestSigner: { + method: 'did', + didUrl: this.verificationMethod.id, + }, + verifierId: this.verifierRecord.verifierId, + presentationExchange: { + definition: presentationDefinition, + }, + }) + + return authorizationRequestUri + } + + public async exit() { + console.log(Output.Exit) + await this.agent.shutdown() + process.exit(0) + } + + public async restart() { + await this.agent.shutdown() + } +} diff --git a/demo-openid/src/VerifierInquirer.ts b/demo-openid/src/VerifierInquirer.ts new file mode 100644 index 0000000000..8877242fb6 --- /dev/null +++ b/demo-openid/src/VerifierInquirer.ts @@ -0,0 +1,89 @@ +import { clear } from 'console' +import { textSync } from 'figlet' +import { prompt } from 'inquirer' + +import { BaseInquirer, ConfirmOptions } from './BaseInquirer' +import { Title, purpleText } from './OutputClass' +import { Verifier, presentationDefinitions } from './Verifier' + +export const runVerifier = async () => { + clear() + console.log(textSync('Verifier', { horizontalLayout: 'full' })) + const verifier = await VerifierInquirer.build() + await verifier.processAnswer() +} + +enum PromptOptions { + CreateProofOffer = 'Request the presentation of a credential.', + Exit = 'Exit', + Restart = 'Restart', +} + +export class VerifierInquirer extends BaseInquirer { + public verifier: Verifier + public promptOptionsString: string[] + + public constructor(verifier: Verifier) { + super() + this.verifier = verifier + this.promptOptionsString = Object.values(PromptOptions) + } + + public static async build(): Promise { + const verifier = await Verifier.build() + return new VerifierInquirer(verifier) + } + + private async getPromptChoice() { + return prompt([this.inquireOptions(this.promptOptionsString)]) + } + + public async processAnswer() { + const choice = await this.getPromptChoice() + + switch (choice.options) { + case PromptOptions.CreateProofOffer: + await this.createProofRequest() + break + case PromptOptions.Exit: + await this.exit() + break + case PromptOptions.Restart: + await this.restart() + return + } + await this.processAnswer() + } + + public async createProofRequest() { + const choice = await prompt([this.inquireOptions(presentationDefinitions.map((p) => p.id))]) + const presentationDefinition = presentationDefinitions.find((p) => p.id === choice.options) + if (!presentationDefinition) throw new Error('No presentation definition found') + + const proofRequest = await this.verifier.createProofRequest(presentationDefinition) + + console.log(purpleText(`Proof request for the presentation of an ${choice.options}.\n'${proofRequest}'`)) + } + + public async exit() { + const confirm = await prompt([this.inquireConfirmation(Title.ConfirmTitle)]) + if (confirm.options === ConfirmOptions.No) { + return + } else if (confirm.options === ConfirmOptions.Yes) { + await this.verifier.exit() + } + } + + public async restart() { + const confirm = await prompt([this.inquireConfirmation(Title.ConfirmTitle)]) + if (confirm.options === ConfirmOptions.No) { + await this.processAnswer() + return + } else if (confirm.options === ConfirmOptions.Yes) { + await this.verifier.restart() + await runVerifier() + } + } +} + +void runVerifier() diff --git a/demo-openid/tsconfig.json b/demo-openid/tsconfig.json new file mode 100644 index 0000000000..b7d9de6c8e --- /dev/null +++ b/demo-openid/tsconfig.json @@ -0,0 +1,6 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "skipLibCheck": true + } +} diff --git a/package.json b/package.json index a5d71237cc..a0a69bcee4 100644 --- a/package.json +++ b/package.json @@ -5,6 +5,7 @@ "workspaces": [ "packages/*", "demo", + "demo-openid", "samples/*" ], "repository": { diff --git a/packages/action-menu/package.json b/packages/action-menu/package.json index 132d10a234..dcdcf82172 100644 --- a/packages/action-menu/package.json +++ b/packages/action-menu/package.json @@ -26,7 +26,7 @@ "dependencies": { "@credo-ts/core": "0.4.2", "class-transformer": "0.5.1", - "class-validator": "0.14.0", + "class-validator": "0.14.1", "rxjs": "^7.2.0" }, "devDependencies": { diff --git a/packages/action-menu/src/ActionMenuModule.ts b/packages/action-menu/src/ActionMenuModule.ts index ba68ee3482..21beecf751 100644 --- a/packages/action-menu/src/ActionMenuModule.ts +++ b/packages/action-menu/src/ActionMenuModule.ts @@ -17,9 +17,6 @@ export class ActionMenuModule implements Module { * Registers the dependencies of the question answer module on the dependency manager. */ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(ActionMenuApi) - // Services dependencyManager.registerSingleton(ActionMenuService) diff --git a/packages/action-menu/src/__tests__/ActionMenuModule.test.ts b/packages/action-menu/src/__tests__/ActionMenuModule.test.ts index bd844cc596..c37554a827 100644 --- a/packages/action-menu/src/__tests__/ActionMenuModule.test.ts +++ b/packages/action-menu/src/__tests__/ActionMenuModule.test.ts @@ -2,7 +2,6 @@ import type { DependencyManager, FeatureRegistry } from '@credo-ts/core' import { Protocol } from '@credo-ts/core' -import { ActionMenuApi } from '../ActionMenuApi' import { ActionMenuModule } from '../ActionMenuModule' import { ActionMenuRole } from '../ActionMenuRole' import { ActionMenuRepository } from '../repository' @@ -23,9 +22,6 @@ describe('ActionMenuModule', () => { const actionMenuModule = new ActionMenuModule() actionMenuModule.register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(ActionMenuApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(ActionMenuService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(ActionMenuRepository) diff --git a/packages/anoncreds/package.json b/packages/anoncreds/package.json index f130f5d724..2fc9633c2b 100644 --- a/packages/anoncreds/package.json +++ b/packages/anoncreds/package.json @@ -27,7 +27,7 @@ "@credo-ts/core": "0.4.2", "bn.js": "^5.2.1", "class-transformer": "0.5.1", - "class-validator": "0.14.0", + "class-validator": "0.14.1", "reflect-metadata": "^0.1.13" }, "devDependencies": { diff --git a/packages/anoncreds/src/updates/__tests__/0.3.test.ts b/packages/anoncreds/src/updates/__tests__/0.3.test.ts index 9d0280c1ac..602c3d37b0 100644 --- a/packages/anoncreds/src/updates/__tests__/0.3.test.ts +++ b/packages/anoncreds/src/updates/__tests__/0.3.test.ts @@ -73,7 +73,7 @@ describe('UpdateAssistant | AnonCreds | v0.3.1 - v0.4', () => { }, } - expect(await updateAssistant.isUpToDate()).toBe(false) + expect(await updateAssistant.isUpToDate('0.4')).toBe(false) expect(await updateAssistant.getNeededUpdates('0.4')).toEqual([ { fromVersion: '0.3.1', @@ -82,10 +82,10 @@ describe('UpdateAssistant | AnonCreds | v0.3.1 - v0.4', () => { }, ]) - await updateAssistant.update() + await updateAssistant.update('0.4') - expect(await updateAssistant.isUpToDate()).toBe(true) - expect(await updateAssistant.getNeededUpdates()).toEqual([]) + expect(await updateAssistant.isUpToDate('0.4')).toBe(true) + expect(await updateAssistant.getNeededUpdates('0.4')).toEqual([]) expect(storageService.contextCorrelationIdToRecords[agent.context.contextCorrelationId].records).toMatchSnapshot() @@ -215,8 +215,8 @@ describe('UpdateAssistant | AnonCreds | v0.3.1 - v0.4', () => { }, } - expect(await updateAssistant.isUpToDate()).toBe(false) - expect(await updateAssistant.getNeededUpdates()).toEqual([ + expect(await updateAssistant.isUpToDate('0.4')).toBe(false) + expect(await updateAssistant.getNeededUpdates('0.4')).toEqual([ { fromVersion: '0.3.1', toVersion: '0.4', @@ -224,10 +224,10 @@ describe('UpdateAssistant | AnonCreds | v0.3.1 - v0.4', () => { }, ]) - await updateAssistant.update() + await updateAssistant.update('0.4') - expect(await updateAssistant.isUpToDate()).toBe(true) - expect(await updateAssistant.getNeededUpdates()).toEqual([]) + expect(await updateAssistant.isUpToDate('0.4')).toBe(true) + expect(await updateAssistant.getNeededUpdates('0.4')).toEqual([]) expect(storageService.contextCorrelationIdToRecords[agent.context.contextCorrelationId].records).toMatchSnapshot() diff --git a/packages/anoncreds/src/utils/credential.ts b/packages/anoncreds/src/utils/credential.ts index b210997fe0..9eae6b387b 100644 --- a/packages/anoncreds/src/utils/credential.ts +++ b/packages/anoncreds/src/utils/credential.ts @@ -1,7 +1,7 @@ import type { AnonCredsSchema, AnonCredsCredentialValues } from '../models' import type { CredentialPreviewAttributeOptions, LinkedAttachment } from '@credo-ts/core' -import { CredoError, Hasher, encodeAttachment, Buffer } from '@credo-ts/core' +import { CredoError, Hasher, encodeAttachment } from '@credo-ts/core' import BigNumber from 'bn.js' const isString = (value: unknown): value is string => typeof value === 'string' @@ -150,7 +150,7 @@ export function encodeCredentialValue(value: unknown) { value = 'None' } - return new BigNumber(Hasher.hash(Buffer.from(value as string), 'sha2-256')).toString() + return new BigNumber(Hasher.hash(String(value).toString(), 'sha-256')).toString() } export function assertAttributesMatch(schema: AnonCredsSchema, attributes: CredentialPreviewAttributeOptions[]) { diff --git a/packages/anoncreds/tests/InMemoryAnonCredsRegistry.ts b/packages/anoncreds/tests/InMemoryAnonCredsRegistry.ts index 382b1f68b0..2bf5ce88ed 100644 --- a/packages/anoncreds/tests/InMemoryAnonCredsRegistry.ts +++ b/packages/anoncreds/tests/InMemoryAnonCredsRegistry.ts @@ -19,7 +19,7 @@ import type { } from '../src' import type { AgentContext } from '@credo-ts/core' -import { Hasher, TypedArrayEncoder } from '@credo-ts/core' +import { Hasher } from '@credo-ts/core' import BigNumber from 'bn.js' import { @@ -348,9 +348,7 @@ export class InMemoryAnonCredsRegistry implements AnonCredsRegistry { * Does this by hashing the schema id, transforming the hash to a number and taking the first 6 digits. */ function getSeqNoFromSchemaId(schemaId: string) { - const seqNo = Number( - new BigNumber(Hasher.hash(TypedArrayEncoder.fromString(schemaId), 'sha2-256')).toString().slice(0, 5) - ) + const seqNo = Number(new BigNumber(Hasher.hash(schemaId, 'sha-256')).toString().slice(0, 5)) return seqNo } diff --git a/packages/askar/package.json b/packages/askar/package.json index ab450d27bf..ff35993cde 100644 --- a/packages/askar/package.json +++ b/packages/askar/package.json @@ -27,7 +27,7 @@ "@credo-ts/core": "0.4.2", "bn.js": "^5.2.1", "class-transformer": "0.5.1", - "class-validator": "0.14.0", + "class-validator": "0.14.1", "rxjs": "^7.2.0", "tsyringe": "^4.8.0" }, diff --git a/packages/askar/src/AskarModule.ts b/packages/askar/src/AskarModule.ts index c59450e122..a1e1762f40 100644 --- a/packages/askar/src/AskarModule.ts +++ b/packages/askar/src/AskarModule.ts @@ -1,7 +1,7 @@ import type { AskarModuleConfigOptions } from './AskarModuleConfig' import type { AgentContext, DependencyManager, Module } from '@credo-ts/core' -import { AgentConfig, CredoError, InjectionSymbols } from '@credo-ts/core' +import { CredoError, InjectionSymbols } from '@credo-ts/core' import { Store } from '@hyperledger/aries-askar-shared' import { AskarMultiWalletDatabaseScheme, AskarModuleConfig } from './AskarModuleConfig' @@ -17,13 +17,6 @@ export class AskarModule implements Module { } public register(dependencyManager: DependencyManager) { - // Warn about experimental module - dependencyManager - .resolve(AgentConfig) - .logger.warn( - "The '@credo-ts/askar' module is experimental and could have unexpected breaking changes. When using this module, make sure to use strict versions for all @credo-ts packages." - ) - dependencyManager.registerInstance(AskarModuleConfig, this.config) if (dependencyManager.isRegistered(InjectionSymbols.Wallet)) { diff --git a/packages/askar/src/wallet/AskarWallet.ts b/packages/askar/src/wallet/AskarWallet.ts index 917eddd27e..f404edb989 100644 --- a/packages/askar/src/wallet/AskarWallet.ts +++ b/packages/askar/src/wallet/AskarWallet.ts @@ -22,7 +22,6 @@ import { inject, injectable } from 'tsyringe' import { AskarErrorCode, isAskarError, keyDerivationMethodToStoreKeyMethod, uriFromWalletConfig } from '../utils' import { AskarBaseWallet } from './AskarBaseWallet' -import { AskarProfileWallet } from './AskarProfileWallet' import { isAskarWalletSqliteStorageConfig } from './AskarWalletStorageConfig' /** @@ -88,14 +87,6 @@ export class AskarWallet extends AskarBaseWallet { await this.close() } - /** - * TODO: we can add this method, and add custom logic in the tenants module - * or we can try to register the store on the agent context - */ - public async getProfileWallet() { - return new AskarProfileWallet(this.store, this.logger, this.signingKeyProviderRegistry) - } - /** * @throws {WalletDuplicateError} if the wallet already exists * @throws {WalletError} if another error occurs diff --git a/packages/cheqd/package.json b/packages/cheqd/package.json index f13502ab40..c3891db2b9 100644 --- a/packages/cheqd/package.json +++ b/packages/cheqd/package.json @@ -32,7 +32,7 @@ "@cosmjs/proto-signing": "^0.31.0", "@stablelib/ed25519": "^1.0.3", "class-transformer": "^0.5.1", - "class-validator": "^0.14.0", + "class-validator": "0.14.1", "rxjs": "^7.2.0", "tsyringe": "^4.8.0" }, diff --git a/packages/cheqd/src/anoncreds/services/CheqdAnonCredsRegistry.ts b/packages/cheqd/src/anoncreds/services/CheqdAnonCredsRegistry.ts index 0fbd45de8e..0d2c41bb73 100644 --- a/packages/cheqd/src/anoncreds/services/CheqdAnonCredsRegistry.ts +++ b/packages/cheqd/src/anoncreds/services/CheqdAnonCredsRegistry.ts @@ -14,7 +14,7 @@ import type { } from '@credo-ts/anoncreds' import type { AgentContext } from '@credo-ts/core' -import { CredoError, Buffer, Hasher, JsonTransformer, TypedArrayEncoder, utils } from '@credo-ts/core' +import { CredoError, Hasher, JsonTransformer, TypedArrayEncoder, utils } from '@credo-ts/core' import { CheqdDidResolver, CheqdDidRegistrar } from '../../dids' import { cheqdSdkAnonCredsRegistryIdentifierRegex, parseCheqdDid } from '../utils/identifiers' @@ -142,7 +142,7 @@ export class CheqdAnonCredsRegistry implements AnonCredsRegistry { } const credDefName = `${schema.schema.name}-${credentialDefinition.tag}` - const credDefNameHashBuffer = Hasher.hash(Buffer.from(credDefName), 'sha2-256') + const credDefNameHashBuffer = Hasher.hash(credDefName, 'sha-256') const credDefResource = { id: utils.uuid(), diff --git a/packages/cheqd/src/anoncreds/utils/identifiers.ts b/packages/cheqd/src/anoncreds/utils/identifiers.ts index f0c2ccc49a..5368e6b9ee 100644 --- a/packages/cheqd/src/anoncreds/utils/identifiers.ts +++ b/packages/cheqd/src/anoncreds/utils/identifiers.ts @@ -9,18 +9,23 @@ const IDENTIFIER = `((?:${ID_CHAR}*:)*(${ID_CHAR}+))` const PATH = `(/[^#?]*)?` const QUERY = `([?][^#]*)?` const VERSION_ID = `(.*?)` +const FRAGMENT = `([#].*)?` export const cheqdSdkAnonCredsRegistryIdentifierRegex = new RegExp( - `^did:cheqd:${NETWORK}:${IDENTIFIER}${PATH}${QUERY}$` + `^did:cheqd:${NETWORK}:${IDENTIFIER}${PATH}${QUERY}${FRAGMENT}$` ) -export const cheqdDidRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}${QUERY}$`) -export const cheqdDidVersionRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/version/${VERSION_ID}${QUERY}$`) -export const cheqdDidVersionsRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/versions${QUERY}$`) -export const cheqdDidMetadataRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/metadata${QUERY}$`) -export const cheqdResourceRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/resources/${IDENTIFIER}${QUERY}$`) +export const cheqdDidRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}${QUERY}${FRAGMENT}$`) +export const cheqdDidVersionRegex = new RegExp( + `^did:cheqd:${NETWORK}:${IDENTIFIER}/version/${VERSION_ID}${QUERY}${FRAGMENT}$` +) +export const cheqdDidVersionsRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/versions${QUERY}${FRAGMENT}$`) +export const cheqdDidMetadataRegex = new RegExp(`^did:cheqd:${NETWORK}:${IDENTIFIER}/metadata${QUERY}${FRAGMENT}$`) +export const cheqdResourceRegex = new RegExp( + `^did:cheqd:${NETWORK}:${IDENTIFIER}/resources/${IDENTIFIER}${QUERY}${FRAGMENT}$` +) export const cheqdResourceMetadataRegex = new RegExp( - `^did:cheqd:${NETWORK}:${IDENTIFIER}/resources/${IDENTIFIER}/metadata${QUERY}` + `^did:cheqd:${NETWORK}:${IDENTIFIER}/resources/${IDENTIFIER}/metadata${QUERY}${FRAGMENT}` ) export type ParsedCheqdDid = ParsedDid & { network: string } diff --git a/packages/core/package.json b/packages/core/package.json index 8fad6160a3..14ac3d2cbe 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -27,19 +27,20 @@ "@digitalcredentials/jsonld-signatures": "^9.4.0", "@digitalcredentials/vc": "^6.0.1", "@multiformats/base-x": "^4.0.1", + "@sd-jwt/core": "^0.2.0", + "@sd-jwt/decode": "^0.2.0", + "@sphereon/pex": "^3.0.1", + "@sphereon/pex-models": "^2.1.5", + "@sphereon/ssi-types": "^0.18.1", "@stablelib/ed25519": "^1.0.2", - "@stablelib/random": "^1.0.1", "@stablelib/sha256": "^1.0.1", - "@sphereon/pex": "^2.2.2", - "@sphereon/pex-models": "^2.1.2", - "@sphereon/ssi-types": "^0.17.5", "@types/ws": "^8.5.4", "abort-controller": "^3.0.0", "big-integer": "^1.6.51", "borc": "^3.0.0", "buffer": "^6.0.3", "class-transformer": "0.5.1", - "class-validator": "0.14.0", + "class-validator": "0.14.1", "did-resolver": "^4.1.0", "jsonpath": "^1.1.1", "lru_map": "^0.4.1", diff --git a/packages/core/src/agent/AgentModules.ts b/packages/core/src/agent/AgentModules.ts index faf87ecec7..efe603a40f 100644 --- a/packages/core/src/agent/AgentModules.ts +++ b/packages/core/src/agent/AgentModules.ts @@ -14,6 +14,7 @@ import { MessagePickupModule } from '../modules/message-pickup' import { OutOfBandModule } from '../modules/oob' import { ProofsModule } from '../modules/proofs' import { MediationRecipientModule, MediatorModule } from '../modules/routing' +import { SdJwtVcModule } from '../modules/sd-jwt-vc' import { W3cCredentialsModule } from '../modules/vc' import { WalletModule } from '../wallet' @@ -133,6 +134,7 @@ function getDefaultAgentModules() { w3cCredentials: () => new W3cCredentialsModule(), cache: () => new CacheModule(), pex: () => new DifPresentationExchangeModule(), + sdJwtVc: () => new SdJwtVcModule(), } as const } diff --git a/packages/core/src/agent/BaseAgent.ts b/packages/core/src/agent/BaseAgent.ts index a1ed4131c7..de051d7f50 100644 --- a/packages/core/src/agent/BaseAgent.ts +++ b/packages/core/src/agent/BaseAgent.ts @@ -18,6 +18,7 @@ import { MessagePickupApi } from '../modules/message-pickup/MessagePickupApi' import { OutOfBandApi } from '../modules/oob' import { ProofsApi } from '../modules/proofs' import { MediatorApi, MediationRecipientApi } from '../modules/routing' +import { SdJwtVcApi } from '../modules/sd-jwt-vc' import { W3cCredentialsApi } from '../modules/vc/W3cCredentialsApi' import { StorageUpdateService } from '../storage' import { UpdateAssistant } from '../storage/migration/UpdateAssistant' @@ -58,6 +59,7 @@ export abstract class BaseAgent> @@ -106,6 +108,7 @@ export abstract class BaseAgent { wallet: expect.any(WalletModule), oob: expect.any(OutOfBandModule), w3cCredentials: expect.any(W3cCredentialsModule), + sdJwtVc: expect.any(SdJwtVcModule), cache: expect.any(CacheModule), }) }) @@ -96,6 +98,7 @@ describe('AgentModules', () => { oob: expect.any(OutOfBandModule), w3cCredentials: expect.any(W3cCredentialsModule), cache: expect.any(CacheModule), + sdJwtVc: expect.any(SdJwtVcModule), myModule, }) }) @@ -124,6 +127,7 @@ describe('AgentModules', () => { oob: expect.any(OutOfBandModule), w3cCredentials: expect.any(W3cCredentialsModule), cache: expect.any(CacheModule), + sdJwtVc: expect.any(SdJwtVcModule), myModule, }) }) diff --git a/packages/core/src/crypto/JwsService.ts b/packages/core/src/crypto/JwsService.ts index 53a0300660..52afc38e61 100644 --- a/packages/core/src/crypto/JwsService.ts +++ b/packages/core/src/crypto/JwsService.ts @@ -1,4 +1,10 @@ -import type { Jws, JwsDetachedFormat, JwsGeneralFormat, JwsProtectedHeaderOptions } from './JwsTypes' +import type { + Jws, + JwsDetachedFormat, + JwsFlattenedFormat, + JwsGeneralFormat, + JwsProtectedHeaderOptions, +} from './JwsTypes' import type { Key } from './Key' import type { Jwk } from './jose/jwk' import type { JwkJson } from './jose/jwk/Jwk' @@ -118,6 +124,11 @@ export class JwsService { throw new CredoError('Unable to verify JWS, no signatures present in JWS.') } + const jwsFlattened = { + signatures, + payload, + } satisfies JwsFlattenedFormat + const signerKeys: Key[] = [] for (const jws of signatures) { const protectedJson = JsonEncoder.fromBase64(jws.protected) @@ -158,6 +169,7 @@ export class JwsService { return { isValid: false, signerKeys: [], + jws: jwsFlattened, } } } catch (error) { @@ -167,6 +179,7 @@ export class JwsService { return { isValid: false, signerKeys: [], + jws: jwsFlattened, } } @@ -174,7 +187,7 @@ export class JwsService { } } - return { isValid: true, signerKeys } + return { isValid: true, signerKeys, jws: jwsFlattened } } private buildProtected(options: JwsProtectedHeaderOptions) { @@ -263,10 +276,12 @@ export interface VerifyJwsOptions { export type JwsJwkResolver = (options: { jws: JwsDetachedFormat payload: string - protectedHeader: { alg: string; [key: string]: unknown } + protectedHeader: { alg: string; jwk?: string; kid?: string; [key: string]: unknown } }) => Promise | Jwk export interface VerifyJwsResult { isValid: boolean signerKeys: Key[] + + jws: JwsFlattenedFormat } diff --git a/packages/core/src/crypto/jose/jwt/Jwt.ts b/packages/core/src/crypto/jose/jwt/Jwt.ts index 71e90252ce..90302f72e8 100644 --- a/packages/core/src/crypto/jose/jwt/Jwt.ts +++ b/packages/core/src/crypto/jose/jwt/Jwt.ts @@ -1,4 +1,5 @@ import type { Buffer } from '../../../utils' +import type { JwkJson } from '../jwk' import { CredoError } from '../../../error' import { JsonEncoder, TypedArrayEncoder } from '../../../utils' @@ -9,6 +10,7 @@ import { JwtPayload } from './JwtPayload' interface JwtHeader { alg: string kid?: string + jwk?: JwkJson [key: string]: unknown } diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 4b86373206..1a8988e924 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -37,7 +37,7 @@ export { Repository } from './storage/Repository' export * from './storage/RepositoryEvents' export { StorageService, Query, SimpleQuery, BaseRecordConstructor } from './storage/StorageService' export * from './storage/migration' -export { getDirFromFilePath } from './utils/path' +export { getDirFromFilePath, joinUriParts } from './utils/path' export { InjectionSymbols } from './constants' export * from './wallet' export type { TransportSession } from './agent/TransportService' @@ -61,6 +61,8 @@ export * from './modules/oob' export * from './modules/dids' export * from './modules/vc' export * from './modules/cache' +export * from './modules/dif-presentation-exchange' +export * from './modules/sd-jwt-vc' export { JsonEncoder, JsonTransformer, @@ -69,6 +71,8 @@ export { TypedArrayEncoder, Buffer, deepEquality, + asArray, + equalsIgnoreOrder, } from './utils' export * from './logger' export * from './error' @@ -76,7 +80,7 @@ export * from './wallet/error' export { parseMessageType, IsValidMessageType, replaceLegacyDidSovPrefix } from './utils/messageType' export type { Constructor, Constructable } from './utils/mixins' export * from './agent/Events' -export * from './crypto/' +export * from './crypto' // TODO: clean up util exports export { encodeAttachment, isLinkedAttachment } from './utils/attachment' diff --git a/packages/core/src/modules/basic-messages/BasicMessagesModule.ts b/packages/core/src/modules/basic-messages/BasicMessagesModule.ts index fd1fd77f6c..346b3bd1c4 100644 --- a/packages/core/src/modules/basic-messages/BasicMessagesModule.ts +++ b/packages/core/src/modules/basic-messages/BasicMessagesModule.ts @@ -15,9 +15,6 @@ export class BasicMessagesModule implements Module { * Registers the dependencies of the basic message module on the dependency manager. */ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(BasicMessagesApi) - // Services dependencyManager.registerSingleton(BasicMessageService) diff --git a/packages/core/src/modules/basic-messages/__tests__/BasicMessagesModule.test.ts b/packages/core/src/modules/basic-messages/__tests__/BasicMessagesModule.test.ts index 4a9f106810..7354486db1 100644 --- a/packages/core/src/modules/basic-messages/__tests__/BasicMessagesModule.test.ts +++ b/packages/core/src/modules/basic-messages/__tests__/BasicMessagesModule.test.ts @@ -1,6 +1,5 @@ import { FeatureRegistry } from '../../../agent/FeatureRegistry' import { DependencyManager } from '../../../plugins/DependencyManager' -import { BasicMessagesApi } from '../BasicMessagesApi' import { BasicMessagesModule } from '../BasicMessagesModule' import { BasicMessageRepository } from '../repository' import { BasicMessageService } from '../services' @@ -19,9 +18,6 @@ describe('BasicMessagesModule', () => { test('registers dependencies on the dependency manager', () => { new BasicMessagesModule().register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(BasicMessagesApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(BasicMessageService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(BasicMessageRepository) diff --git a/packages/core/src/modules/connections/ConnectionsModule.ts b/packages/core/src/modules/connections/ConnectionsModule.ts index dcddf81da3..b6cef0b7f6 100644 --- a/packages/core/src/modules/connections/ConnectionsModule.ts +++ b/packages/core/src/modules/connections/ConnectionsModule.ts @@ -23,9 +23,6 @@ export class ConnectionsModule implements Module { * Registers the dependencies of the connections module on the dependency manager. */ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(ConnectionsApi) - // Config dependencyManager.registerInstance(ConnectionsModuleConfig, this.config) diff --git a/packages/core/src/modules/connections/__tests__/ConnectionsModule.test.ts b/packages/core/src/modules/connections/__tests__/ConnectionsModule.test.ts index 8fe0127226..5d026182dc 100644 --- a/packages/core/src/modules/connections/__tests__/ConnectionsModule.test.ts +++ b/packages/core/src/modules/connections/__tests__/ConnectionsModule.test.ts @@ -1,6 +1,5 @@ import { FeatureRegistry } from '../../../agent/FeatureRegistry' import { DependencyManager } from '../../../plugins/DependencyManager' -import { ConnectionsApi } from '../ConnectionsApi' import { ConnectionsModule } from '../ConnectionsModule' import { ConnectionsModuleConfig } from '../ConnectionsModuleConfig' import { DidExchangeProtocol } from '../DidExchangeProtocol' @@ -23,9 +22,6 @@ describe('ConnectionsModule', () => { const connectionsModule = new ConnectionsModule() connectionsModule.register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(ConnectionsApi) - expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(1) expect(dependencyManager.registerInstance).toHaveBeenCalledWith(ConnectionsModuleConfig, connectionsModule.config) diff --git a/packages/core/src/modules/credentials/CredentialsModule.ts b/packages/core/src/modules/credentials/CredentialsModule.ts index 9cae75eb28..043a5bde5a 100644 --- a/packages/core/src/modules/credentials/CredentialsModule.ts +++ b/packages/core/src/modules/credentials/CredentialsModule.ts @@ -45,9 +45,6 @@ export class CredentialsModule { }) credentialsModule.register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(CredentialsApi) - expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(1) expect(dependencyManager.registerInstance).toHaveBeenCalledWith(CredentialsModuleConfig, credentialsModule.config) diff --git a/packages/core/src/modules/dids/DidsApi.ts b/packages/core/src/modules/dids/DidsApi.ts index 22f6d695db..bd4f0036ec 100644 --- a/packages/core/src/modules/dids/DidsApi.ts +++ b/packages/core/src/modules/dids/DidsApi.ts @@ -175,4 +175,12 @@ export class DidsApi { }, }) } + + public get supportedResolverMethods() { + return this.didResolverService.supportedMethods + } + + public get supportedRegistrarMethods() { + return this.didRegistrarService.supportedMethods + } } diff --git a/packages/core/src/modules/dids/DidsModule.ts b/packages/core/src/modules/dids/DidsModule.ts index a82dabeb8f..72a6ae96f1 100644 --- a/packages/core/src/modules/dids/DidsModule.ts +++ b/packages/core/src/modules/dids/DidsModule.ts @@ -19,9 +19,6 @@ export class DidsModule implements Module { * Registers the dependencies of the dids module module on the dependency manager. */ public register(dependencyManager: DependencyManager) { - // Api - dependencyManager.registerContextScoped(DidsApi) - // Config dependencyManager.registerInstance(DidsModuleConfig, this.config) diff --git a/packages/core/src/modules/dids/__tests__/DidsModule.test.ts b/packages/core/src/modules/dids/__tests__/DidsModule.test.ts index bddd4a3d53..e09efd52fd 100644 --- a/packages/core/src/modules/dids/__tests__/DidsModule.test.ts +++ b/packages/core/src/modules/dids/__tests__/DidsModule.test.ts @@ -1,5 +1,4 @@ import { DependencyManager } from '../../../plugins/DependencyManager' -import { DidsApi } from '../DidsApi' import { DidsModule } from '../DidsModule' import { DidsModuleConfig } from '../DidsModuleConfig' import { DidRepository } from '../repository' @@ -15,9 +14,6 @@ describe('DidsModule', () => { const didsModule = new DidsModule() didsModule.register(dependencyManager) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(DidsApi) - expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(1) expect(dependencyManager.registerInstance).toHaveBeenCalledWith(DidsModuleConfig, didsModule.config) diff --git a/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo1.ts b/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo1.ts index bcbb5db2bc..f9322412bb 100644 --- a/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo1.ts +++ b/packages/core/src/modules/dids/methods/peer/peerDidNumAlgo1.ts @@ -4,7 +4,7 @@ export function didDocumentJsonToNumAlgo1Did(didDocumentJson: Record LONG_RE.test(did) const hashEncodedDocument = (encodedDocument: string) => MultiBaseEncoder.encode( - MultiHashEncoder.encode(TypedArrayEncoder.fromString(encodedDocument), 'sha2-256'), + MultiHashEncoder.encode(TypedArrayEncoder.fromString(encodedDocument), 'sha-256'), 'base58btc' ) diff --git a/packages/core/src/modules/dids/methods/web/WebDidResolver.ts b/packages/core/src/modules/dids/methods/web/WebDidResolver.ts index f56dbebbfd..4af3511282 100644 --- a/packages/core/src/modules/dids/methods/web/WebDidResolver.ts +++ b/packages/core/src/modules/dids/methods/web/WebDidResolver.ts @@ -30,6 +30,13 @@ export class WebDidResolver implements DidResolver { const result = await this.resolver[parsed.method](did, parsed, this._resolverInstance, didResolutionOptions) let didDocument = null + + // If the did document uses the deprecated publicKey property + // we map it to the newer verificationMethod property + if (!result.didDocument?.verificationMethod && result.didDocument?.publicKey) { + result.didDocument.verificationMethod = result.didDocument.publicKey + } + if (result.didDocument) { didDocument = JsonTransformer.fromJSON(result.didDocument, DidDocument) } diff --git a/packages/core/src/modules/dids/services/DidRegistrarService.ts b/packages/core/src/modules/dids/services/DidRegistrarService.ts index cb59457aa0..861110f7a6 100644 --- a/packages/core/src/modules/dids/services/DidRegistrarService.ts +++ b/packages/core/src/modules/dids/services/DidRegistrarService.ts @@ -153,4 +153,11 @@ export class DidRegistrarService { private findRegistrarForMethod(method: string): DidRegistrar | null { return this.didsModuleConfig.registrars.find((r) => r.supportedMethods.includes(method)) ?? null } + + /** + * Get all supported did methods for the did registrar. + */ + public get supportedMethods() { + return Array.from(new Set(this.didsModuleConfig.registrars.flatMap((r) => r.supportedMethods))) + } } diff --git a/packages/core/src/modules/dids/services/DidResolverService.ts b/packages/core/src/modules/dids/services/DidResolverService.ts index f73fc0aecb..916ef91c4a 100644 --- a/packages/core/src/modules/dids/services/DidResolverService.ts +++ b/packages/core/src/modules/dids/services/DidResolverService.ts @@ -134,4 +134,11 @@ export class DidResolverService { private findResolver(parsed: ParsedDid): DidResolver | null { return this.didsModuleConfig.resolvers.find((r) => r.supportedMethods.includes(parsed.method)) ?? null } + + /** + * Get all supported did methods for the did resolver. + */ + public get supportedMethods() { + return Array.from(new Set(this.didsModuleConfig.resolvers.flatMap((r) => r.supportedMethods))) + } } diff --git a/packages/core/src/modules/dif-presentation-exchange/DifPresentationExchangeService.ts b/packages/core/src/modules/dif-presentation-exchange/DifPresentationExchangeService.ts index 301acc597b..9aa6cb6b27 100644 --- a/packages/core/src/modules/dif-presentation-exchange/DifPresentationExchangeService.ts +++ b/packages/core/src/modules/dif-presentation-exchange/DifPresentationExchangeService.ts @@ -5,22 +5,31 @@ import type { DifPresentationExchangeDefinitionV1, DifPresentationExchangeSubmission, DifPresentationExchangeDefinitionV2, + VerifiablePresentation, } from './models' +import type { PresentationToCreate } from './utils' import type { AgentContext } from '../../agent' import type { Query } from '../../storage/StorageService' import type { VerificationMethod } from '../dids' -import type { W3cCredentialRecord, W3cVerifiableCredential, W3cVerifiablePresentation } from '../vc' -import type { PresentationSignCallBackParams, Validated, VerifiablePresentationResult } from '@sphereon/pex' +import type { SdJwtVcRecord } from '../sd-jwt-vc' +import type { W3cCredentialRecord } from '../vc' +import type { + PresentationSignCallBackParams, + SdJwtDecodedVerifiableCredentialWithKbJwtInput, + Validated, + VerifiablePresentationResult, +} from '@sphereon/pex' import type { InputDescriptorV2, PresentationDefinitionV1 } from '@sphereon/pex-models' -import type { OriginalVerifiableCredential, OriginalVerifiablePresentation } from '@sphereon/ssi-types' +import type { W3CVerifiablePresentation } from '@sphereon/ssi-types' import { Status, PEVersion, PEX } from '@sphereon/pex' import { injectable } from 'tsyringe' import { getJwkFromKey } from '../../crypto' import { CredoError } from '../../error' -import { JsonTransformer } from '../../utils' +import { Hasher, JsonTransformer } from '../../utils' import { DidsApi, getKeyFromVerificationMethod } from '../dids' +import { SdJwtVcApi } from '../sd-jwt-vc' import { ClaimFormat, SignatureSuiteRegistry, @@ -32,32 +41,28 @@ import { import { DifPresentationExchangeError } from './DifPresentationExchangeError' import { DifPresentationExchangeSubmissionLocation } from './models' import { + getVerifiablePresentationFromEncoded, + getSphereonOriginalVerifiablePresentation, getCredentialsForRequest, + getPresentationsToCreate, getSphereonOriginalVerifiableCredential, - getSphereonW3cVerifiablePresentation, - getW3cVerifiablePresentationInstance, } from './utils' -export type ProofStructure = Record>> - +/** + * @todo create a public api for using dif presentation exchange + */ @injectable() export class DifPresentationExchangeService { - private pex = new PEX() + private pex = new PEX({ hasher: Hasher.hash }) + + public constructor(private w3cCredentialService: W3cCredentialService) {} public async getCredentialsForRequest( agentContext: AgentContext, presentationDefinition: DifPresentationExchangeDefinition ): Promise { const credentialRecords = await this.queryCredentialForPresentationDefinition(agentContext, presentationDefinition) - - // FIXME: why are we resolving all created dids here? - // If we want to do this we should extract all dids from the credential records and only - // fetch the dids for the queried credential records - const didsApi = agentContext.dependencyManager.resolve(DidsApi) - const didRecords = await didsApi.getCreatedDids() - const holderDids = didRecords.map((didRecord) => didRecord.did) - - return getCredentialsForRequest(presentationDefinition, credentialRecords, holderDids) + return getCredentialsForRequest(this.pex, presentationDefinition, credentialRecords) } /** @@ -80,7 +85,7 @@ export class DifPresentationExchangeService { } // We pick the first matching VC if we are auto-selecting - credentials[submission.inputDescriptorId].push(submission.verifiableCredentials[0].credential) + credentials[submission.inputDescriptorId].push(submission.verifiableCredentials[0]) } } @@ -105,11 +110,11 @@ export class DifPresentationExchangeService { public validatePresentation( presentationDefinition: DifPresentationExchangeDefinition, - presentation: W3cVerifiablePresentation + presentation: VerifiablePresentation ) { const { errors } = this.pex.evaluatePresentation( presentationDefinition, - presentation.encoded as OriginalVerifiablePresentation + getSphereonOriginalVerifiablePresentation(presentation) ) if (errors) { @@ -128,107 +133,6 @@ export class DifPresentationExchangeService { .filter((r): r is string => Boolean(r)) } - /** - * Queries the wallet for credentials that match the given presentation definition. This only does an initial query based on the - * schema of the input descriptors. It does not do any further filtering based on the constraints in the input descriptors. - */ - private async queryCredentialForPresentationDefinition( - agentContext: AgentContext, - presentationDefinition: DifPresentationExchangeDefinition - ): Promise> { - const w3cCredentialRepository = agentContext.dependencyManager.resolve(W3cCredentialRepository) - const query: Array> = [] - const presentationDefinitionVersion = PEX.definitionVersionDiscovery(presentationDefinition) - - if (!presentationDefinitionVersion.version) { - throw new DifPresentationExchangeError( - `Unable to determine the Presentation Exchange version from the presentation definition - `, - presentationDefinitionVersion.error ? { additionalMessages: [presentationDefinitionVersion.error] } : {} - ) - } - - if (presentationDefinitionVersion.version === PEVersion.v1) { - const pd = presentationDefinition as PresentationDefinitionV1 - - // The schema.uri can contain either an expanded type, or a context uri - for (const inputDescriptor of pd.input_descriptors) { - for (const schema of inputDescriptor.schema) { - query.push({ - $or: [{ expandedType: [schema.uri] }, { contexts: [schema.uri] }, { type: [schema.uri] }], - }) - } - } - } else if (presentationDefinitionVersion.version === PEVersion.v2) { - // FIXME: As PE version 2 does not have the `schema` anymore, we can't query by schema anymore. - // For now we retrieve ALL credentials, as we did the same for V1 with JWT credentials. We probably need - // to find some way to do initial filtering, hopefully if there's a filter on the `type` field or something. - } else { - throw new DifPresentationExchangeError( - `Unsupported presentation definition version ${presentationDefinitionVersion.version as unknown as string}` - ) - } - - // query the wallet ourselves first to avoid the need to query the pex library for all - // credentials for every proof request - const credentialRecords = - query.length > 0 - ? await w3cCredentialRepository.findByQuery(agentContext, { - $or: query, - }) - : await w3cCredentialRepository.getAll(agentContext) - - return credentialRecords - } - - private addCredentialToSubjectInputDescriptor( - subjectsToInputDescriptors: ProofStructure, - subjectId: string, - inputDescriptorId: string, - credential: W3cVerifiableCredential - ) { - const inputDescriptorsToCredentials = subjectsToInputDescriptors[subjectId] ?? {} - const credentials = inputDescriptorsToCredentials[inputDescriptorId] ?? [] - - credentials.push(credential) - inputDescriptorsToCredentials[inputDescriptorId] = credentials - subjectsToInputDescriptors[subjectId] = inputDescriptorsToCredentials - } - - private getPresentationFormat( - presentationDefinition: DifPresentationExchangeDefinition, - credentials: Array - ): ClaimFormat.JwtVp | ClaimFormat.LdpVp { - const allCredentialsAreJwtVc = credentials?.every((c) => typeof c === 'string') - const allCredentialsAreLdpVc = credentials?.every((c) => typeof c !== 'string') - - const inputDescriptorsNotSupportingJwtVc = ( - presentationDefinition.input_descriptors as Array - ).filter((d) => d.format && d.format.jwt_vc === undefined) - - const inputDescriptorsNotSupportingLdpVc = ( - presentationDefinition.input_descriptors as Array - ).filter((d) => d.format && d.format.ldp_vc === undefined) - - if ( - allCredentialsAreJwtVc && - (presentationDefinition.format === undefined || presentationDefinition.format.jwt_vc) && - inputDescriptorsNotSupportingJwtVc.length === 0 - ) { - return ClaimFormat.JwtVp - } else if ( - allCredentialsAreLdpVc && - (presentationDefinition.format === undefined || presentationDefinition.format.ldp_vc) && - inputDescriptorsNotSupportingLdpVc.length === 0 - ) { - return ClaimFormat.LdpVp - } else { - throw new DifPresentationExchangeError( - 'No suitable presentation format found for the given presentation definition, and credentials' - ) - } - } - public async createPresentation( agentContext: AgentContext, options: { @@ -238,85 +142,65 @@ export class DifPresentationExchangeService { * Defaults to {@link DifPresentationExchangeSubmissionLocation.PRESENTATION} */ presentationSubmissionLocation?: DifPresentationExchangeSubmissionLocation - challenge?: string + challenge: string domain?: string - nonce?: string } ) { - const { presentationDefinition, challenge, nonce, domain, presentationSubmissionLocation } = options - - const proofStructure: ProofStructure = {} - - Object.entries(options.credentialsForInputDescriptor).forEach(([inputDescriptorId, credentials]) => { - credentials.forEach((credential) => { - const subjectId = credential.credentialSubjectIds[0] - if (!subjectId) { - throw new DifPresentationExchangeError('Missing required credential subject for creating the presentation.') - } - - this.addCredentialToSubjectInputDescriptor(proofStructure, subjectId, inputDescriptorId, credential) - }) - }) + const { presentationDefinition, domain, challenge } = options + const presentationSubmissionLocation = + options.presentationSubmissionLocation ?? DifPresentationExchangeSubmissionLocation.PRESENTATION const verifiablePresentationResultsWithFormat: Array<{ verifiablePresentationResult: VerifiablePresentationResult - format: ClaimFormat.LdpVp | ClaimFormat.JwtVp + claimFormat: PresentationToCreate['claimFormat'] }> = [] - const subjectToInputDescriptors = Object.entries(proofStructure) - for (const [subjectId, subjectInputDescriptorsToCredentials] of subjectToInputDescriptors) { - // Determine a suitable verification method for the presentation - const verificationMethod = await this.getVerificationMethodForSubjectId(agentContext, subjectId) - - if (!verificationMethod) { - throw new DifPresentationExchangeError(`No verification method found for subject id '${subjectId}'.`) - } - + const presentationsToCreate = getPresentationsToCreate(options.credentialsForInputDescriptor) + for (const presentationToCreate of presentationsToCreate) { // We create a presentation for each subject // Thus for each subject we need to filter all the related input descriptors and credentials // FIXME: cast to V1, as tsc errors for strange reasons if not - const inputDescriptorsForSubject = (presentationDefinition as PresentationDefinitionV1).input_descriptors.filter( - (inputDescriptor) => inputDescriptor.id in subjectInputDescriptorsToCredentials + const inputDescriptorIds = presentationToCreate.verifiableCredentials.map((c) => c.inputDescriptorId) + const inputDescriptorsForPresentation = ( + presentationDefinition as PresentationDefinitionV1 + ).input_descriptors.filter((inputDescriptor) => inputDescriptorIds.includes(inputDescriptor.id)) + + // Get all the credentials for the presentation + const credentialsForPresentation = presentationToCreate.verifiableCredentials.map((c) => + getSphereonOriginalVerifiableCredential(c.credential) ) - // Get all the credentials associated with the input descriptors - const credentialsForSubject = Object.values(subjectInputDescriptorsToCredentials) - .flat() - .map(getSphereonOriginalVerifiableCredential) - const presentationDefinitionForSubject: DifPresentationExchangeDefinition = { ...presentationDefinition, - input_descriptors: inputDescriptorsForSubject, + input_descriptors: inputDescriptorsForPresentation, // We remove the submission requirements, as it will otherwise fail to create the VP submission_requirements: undefined, } - const format = this.getPresentationFormat(presentationDefinitionForSubject, credentialsForSubject) - - // FIXME: Q1: is holder always subject id, what if there are multiple subjects??? - // FIXME: Q2: What about proofType, proofPurpose verification method for multiple subjects? const verifiablePresentationResult = await this.pex.verifiablePresentationFrom( presentationDefinitionForSubject, - credentialsForSubject, - this.getPresentationSignCallback(agentContext, verificationMethod, format), + credentialsForPresentation, + this.getPresentationSignCallback(agentContext, presentationToCreate), { - holderDID: subjectId, - proofOptions: { challenge, domain, nonce }, - signatureOptions: { verificationMethod: verificationMethod?.id }, + proofOptions: { domain, challenge }, + signatureOptions: {}, presentationSubmissionLocation: presentationSubmissionLocation ?? DifPresentationExchangeSubmissionLocation.PRESENTATION, } ) - verifiablePresentationResultsWithFormat.push({ verifiablePresentationResult, format }) + verifiablePresentationResultsWithFormat.push({ + verifiablePresentationResult, + claimFormat: presentationToCreate.claimFormat, + }) } - if (!verifiablePresentationResultsWithFormat[0]) { + if (verifiablePresentationResultsWithFormat.length === 0) { throw new DifPresentationExchangeError('No verifiable presentations created') } - if (subjectToInputDescriptors.length !== verifiablePresentationResultsWithFormat.length) { + if (presentationsToCreate.length !== verifiablePresentationResultsWithFormat.length) { throw new DifPresentationExchangeError('Invalid amount of verifiable presentations created') } @@ -327,14 +211,38 @@ export class DifPresentationExchangeService { descriptor_map: [], } - for (const vpf of verifiablePresentationResultsWithFormat) { - const { verifiablePresentationResult } = vpf - presentationSubmission.descriptor_map.push(...verifiablePresentationResult.presentationSubmission.descriptor_map) - } + verifiablePresentationResultsWithFormat.forEach(({ verifiablePresentationResult }, index) => { + // FIXME: path_nested should not be used for sd-jwt. + // Can be removed once https://github.com/Sphereon-Opensource/PEX/pull/140 is released + const descriptorMap = verifiablePresentationResult.presentationSubmission.descriptor_map.map((d) => { + const descriptor = { ...d } + + // when multiple presentations are submitted, path should be $[0], $[1] + // FIXME: this should be addressed in the PEX/OID4VP lib. + // See https://github.com/Sphereon-Opensource/SIOP-OID4VP/issues/62 + if ( + presentationSubmissionLocation === DifPresentationExchangeSubmissionLocation.EXTERNAL && + verifiablePresentationResultsWithFormat.length > 1 + ) { + descriptor.path = `$[${index}]` + } + + if (descriptor.format === 'vc+sd-jwt' && descriptor.path_nested) { + delete descriptor.path_nested + } + + return descriptor + }) + + presentationSubmission.descriptor_map.push(...descriptorMap) + }) return { - verifiablePresentations: verifiablePresentationResultsWithFormat.map((r) => - getW3cVerifiablePresentationInstance(r.verifiablePresentationResult.verifiablePresentation) + verifiablePresentations: verifiablePresentationResultsWithFormat.map((resultWithFormat) => + getVerifiablePresentationFromEncoded( + agentContext, + resultWithFormat.verifiablePresentationResult.verifiablePresentation + ) ), presentationSubmission, presentationSubmissionLocation: @@ -445,77 +353,117 @@ export class DifPresentationExchangeService { // For each of the supported algs, find the key types, then find the proof types const signatureSuiteRegistry = agentContext.dependencyManager.resolve(SignatureSuiteRegistry) - const supportedSignatureSuite = signatureSuiteRegistry.getByVerificationMethodType(verificationMethod.type) - if (!supportedSignatureSuite) { + const key = getKeyFromVerificationMethod(verificationMethod) + const supportedSignatureSuites = signatureSuiteRegistry.getAllByKeyType(key.keyType) + if (supportedSignatureSuites.length === 0) { throw new DifPresentationExchangeError( - `Couldn't find a supported signature suite for the given verification method type '${verificationMethod.type}'` + `Couldn't find a supported signature suite for the given key type '${key.keyType}'` ) } if (suitableSignatureSuites) { - if (suitableSignatureSuites.includes(supportedSignatureSuite.proofType) === false) { + const foundSignatureSuite = supportedSignatureSuites.find((suite) => + suitableSignatureSuites.includes(suite.proofType) + ) + + if (!foundSignatureSuite) { throw new DifPresentationExchangeError( [ 'No possible signature suite found for the given verification method.', `Verification method type: ${verificationMethod.type}`, - `SupportedSignatureSuite '${supportedSignatureSuite.proofType}'`, + `Key type: ${key.keyType}`, + `SupportedSignatureSuites: '${supportedSignatureSuites.map((s) => s.proofType).join(', ')}'`, `SuitableSignatureSuites: ${suitableSignatureSuites.join(', ')}`, ].join('\n') ) } - return supportedSignatureSuite.proofType + return supportedSignatureSuites[0].proofType } - return supportedSignatureSuite.proofType + return supportedSignatureSuites[0].proofType } - public getPresentationSignCallback( - agentContext: AgentContext, - verificationMethod: VerificationMethod, - vpFormat: ClaimFormat.LdpVp | ClaimFormat.JwtVp - ) { - const w3cCredentialService = agentContext.dependencyManager.resolve(W3cCredentialService) - + private getPresentationSignCallback(agentContext: AgentContext, presentationToCreate: PresentationToCreate) { return async (callBackParams: PresentationSignCallBackParams) => { // The created partial proof and presentation, as well as original supplied options - const { presentation: presentationJson, options, presentationDefinition } = callBackParams - const { challenge, domain, nonce } = options.proofOptions ?? {} - const { verificationMethod: verificationMethodId } = options.signatureOptions ?? {} + const { presentation: presentationInput, options, presentationDefinition } = callBackParams + const { challenge, domain } = options.proofOptions ?? {} - if (verificationMethodId && verificationMethodId !== verificationMethod.id) { - throw new DifPresentationExchangeError( - `Verification method from signing options ${verificationMethodId} does not match verification method ${verificationMethod.id}` - ) + if (!challenge) { + throw new CredoError('challenge MUST be provided when signing a Verifiable Presentation') } - let signedPresentation: W3cVerifiablePresentation - if (vpFormat === 'jwt_vp') { - signedPresentation = await w3cCredentialService.signPresentation(agentContext, { + if (presentationToCreate.claimFormat === ClaimFormat.JwtVp) { + // Determine a suitable verification method for the presentation + const verificationMethod = await this.getVerificationMethodForSubjectId( + agentContext, + presentationToCreate.subjectIds[0] + ) + + const w3cPresentation = JsonTransformer.fromJSON(presentationInput, W3cPresentation) + w3cPresentation.holder = verificationMethod.controller + + const signedPresentation = await this.w3cCredentialService.signPresentation(agentContext, { format: ClaimFormat.JwtVp, alg: this.getSigningAlgorithmForJwtVc(presentationDefinition, verificationMethod), verificationMethod: verificationMethod.id, - presentation: JsonTransformer.fromJSON(presentationJson, W3cPresentation), - challenge: challenge ?? nonce ?? (await agentContext.wallet.generateNonce()), + presentation: w3cPresentation, + challenge, domain, }) - } else if (vpFormat === 'ldp_vp') { - signedPresentation = await w3cCredentialService.signPresentation(agentContext, { + + return signedPresentation.encoded as W3CVerifiablePresentation + } else if (presentationToCreate.claimFormat === ClaimFormat.LdpVp) { + // Determine a suitable verification method for the presentation + const verificationMethod = await this.getVerificationMethodForSubjectId( + agentContext, + presentationToCreate.subjectIds[0] + ) + + const w3cPresentation = JsonTransformer.fromJSON(presentationInput, W3cPresentation) + w3cPresentation.holder = verificationMethod.controller + + const signedPresentation = await this.w3cCredentialService.signPresentation(agentContext, { format: ClaimFormat.LdpVp, + // TODO: we should move the check for which proof to use for a presentation to earlier + // as then we know when determining which VPs to submit already if the proof types are supported + // by the verifier, and we can then just add this to the vpToCreate interface proofType: this.getProofTypeForLdpVc(agentContext, presentationDefinition, verificationMethod), proofPurpose: 'authentication', verificationMethod: verificationMethod.id, - presentation: JsonTransformer.fromJSON(presentationJson, W3cPresentation), - challenge: challenge ?? nonce ?? (await agentContext.wallet.generateNonce()), + presentation: w3cPresentation, + challenge, domain, }) + + return signedPresentation.encoded as W3CVerifiablePresentation + } else if (presentationToCreate.claimFormat === ClaimFormat.SdJwtVc) { + const sdJwtInput = presentationInput as SdJwtDecodedVerifiableCredentialWithKbJwtInput + + if (!domain) { + throw new CredoError("Missing 'domain' property, unable to set required 'aud' property in SD-JWT KB-JWT") + } + + const sdJwtVcApi = this.getSdJwtVcApi(agentContext) + const sdJwtVc = await sdJwtVcApi.present({ + compactSdJwtVc: sdJwtInput.compactSdJwtVc, + // SD is already handled by PEX + presentationFrame: true, + verifierMetadata: { + audience: domain, + nonce: challenge, + // TODO: we should make this optional + issuedAt: Math.floor(Date.now() / 1000), + }, + }) + + return sdJwtVc } else { throw new DifPresentationExchangeError( - `Only JWT credentials or JSONLD credentials are supported for a single presentation` + `Only JWT, SD-JWT-VC, JSONLD credentials are supported for a single presentation` ) } - - return getSphereonW3cVerifiablePresentation(signedPresentation) } } @@ -545,4 +493,78 @@ export class DifPresentationExchangeService { return verificationMethod } + + /** + * Queries the wallet for credentials that match the given presentation definition. This only does an initial query based on the + * schema of the input descriptors. It does not do any further filtering based on the constraints in the input descriptors. + */ + private async queryCredentialForPresentationDefinition( + agentContext: AgentContext, + presentationDefinition: DifPresentationExchangeDefinition + ): Promise> { + const w3cCredentialRepository = agentContext.dependencyManager.resolve(W3cCredentialRepository) + const w3cQuery: Array> = [] + const sdJwtVcQuery: Array> = [] + const presentationDefinitionVersion = PEX.definitionVersionDiscovery(presentationDefinition) + + if (!presentationDefinitionVersion.version) { + throw new DifPresentationExchangeError( + `Unable to determine the Presentation Exchange version from the presentation definition`, + presentationDefinitionVersion.error ? { additionalMessages: [presentationDefinitionVersion.error] } : {} + ) + } + + // FIXME: in the query we should take into account the supported proof types of the verifier + // this could help enormously in the amount of credentials we have to retrieve from storage. + // NOTE: for now we don't support SD-JWT for v1, as I don't know what the schema.uri should be? + if (presentationDefinitionVersion.version === PEVersion.v1) { + const pd = presentationDefinition as PresentationDefinitionV1 + + // The schema.uri can contain either an expanded type, or a context uri + for (const inputDescriptor of pd.input_descriptors) { + for (const schema of inputDescriptor.schema) { + w3cQuery.push({ + $or: [{ expandedType: [schema.uri] }, { contexts: [schema.uri] }, { type: [schema.uri] }], + }) + } + } + } else if (presentationDefinitionVersion.version === PEVersion.v2) { + // FIXME: As PE version 2 does not have the `schema` anymore, we can't query by schema anymore. + // For now we retrieve ALL credentials, as we did the same for V1 with JWT credentials. We probably need + // to find some way to do initial filtering, hopefully if there's a filter on the `type` field or something. + } else { + throw new DifPresentationExchangeError( + `Unsupported presentation definition version ${presentationDefinitionVersion.version as unknown as string}` + ) + } + + const allRecords: Array = [] + + // query the wallet ourselves first to avoid the need to query the pex library for all + // credentials for every proof request + const w3cCredentialRecords = + w3cQuery.length > 0 + ? await w3cCredentialRepository.findByQuery(agentContext, { + $or: w3cQuery, + }) + : await w3cCredentialRepository.getAll(agentContext) + + allRecords.push(...w3cCredentialRecords) + + const sdJwtVcApi = this.getSdJwtVcApi(agentContext) + const sdJwtVcRecords = + sdJwtVcQuery.length > 0 + ? await sdJwtVcApi.findAllByQuery({ + $or: sdJwtVcQuery, + }) + : await sdJwtVcApi.getAll() + + allRecords.push(...sdJwtVcRecords) + + return allRecords + } + + private getSdJwtVcApi(agentContext: AgentContext) { + return agentContext.dependencyManager.resolve(SdJwtVcApi) + } } diff --git a/packages/core/src/modules/dif-presentation-exchange/models/DifPexCredentialsForRequest.ts b/packages/core/src/modules/dif-presentation-exchange/models/DifPexCredentialsForRequest.ts index ec2e83d17e..9ded2b1688 100644 --- a/packages/core/src/modules/dif-presentation-exchange/models/DifPexCredentialsForRequest.ts +++ b/packages/core/src/modules/dif-presentation-exchange/models/DifPexCredentialsForRequest.ts @@ -1,4 +1,5 @@ -import type { W3cCredentialRecord, W3cVerifiableCredential } from '../../vc' +import type { SdJwtVcRecord } from '../../sd-jwt-vc' +import type { W3cCredentialRecord } from '../../vc' export interface DifPexCredentialsForRequest { /** @@ -110,10 +111,10 @@ export interface DifPexCredentialsForRequestSubmissionEntry { * If the value is an empty list, it means the input descriptor could * not be satisfied. */ - verifiableCredentials: W3cCredentialRecord[] + verifiableCredentials: Array } /** * Mapping of selected credentials for an input descriptor */ -export type DifPexInputDescriptorToCredentials = Record> +export type DifPexInputDescriptorToCredentials = Record> diff --git a/packages/core/src/modules/dif-presentation-exchange/models/index.ts b/packages/core/src/modules/dif-presentation-exchange/models/index.ts index 01ce9d6767..a94c88e6c9 100644 --- a/packages/core/src/modules/dif-presentation-exchange/models/index.ts +++ b/packages/core/src/modules/dif-presentation-exchange/models/index.ts @@ -1,4 +1,6 @@ export * from './DifPexCredentialsForRequest' +import type { SdJwtVc } from '../../sd-jwt-vc' +import type { W3cVerifiableCredential, W3cVerifiablePresentation } from '../../vc' import type { PresentationDefinitionV1, PresentationDefinitionV2, PresentationSubmission } from '@sphereon/pex-models' import { PresentationSubmissionLocation } from '@sphereon/pex' @@ -9,3 +11,7 @@ export type DifPresentationExchangeDefinitionV1 = PresentationDefinitionV1 export type DifPresentationExchangeDefinitionV2 = PresentationDefinitionV2 export type DifPresentationExchangeSubmission = PresentationSubmission export { PresentationSubmissionLocation as DifPresentationExchangeSubmissionLocation } + +// TODO: we might want to move this to another place at some point +export type VerifiablePresentation = W3cVerifiablePresentation | SdJwtVc +export type VerifiableCredential = W3cVerifiableCredential | SdJwtVc diff --git a/packages/core/src/modules/dif-presentation-exchange/utils/credentialSelection.ts b/packages/core/src/modules/dif-presentation-exchange/utils/credentialSelection.ts index 1fca34b943..c1ef770b36 100644 --- a/packages/core/src/modules/dif-presentation-exchange/utils/credentialSelection.ts +++ b/packages/core/src/modules/dif-presentation-exchange/utils/credentialSelection.ts @@ -1,13 +1,13 @@ +import type { SdJwtVcRecord } from '../../sd-jwt-vc' import type { W3cCredentialRecord } from '../../vc' import type { DifPexCredentialsForRequest, DifPexCredentialsForRequestRequirement, DifPexCredentialsForRequestSubmissionEntry, } from '../models' -import type { IPresentationDefinition, SelectResults, SubmissionRequirementMatch } from '@sphereon/pex' +import type { IPresentationDefinition, SelectResults, SubmissionRequirementMatch, PEX } from '@sphereon/pex' import type { InputDescriptorV1, InputDescriptorV2, SubmissionRequirement } from '@sphereon/pex-models' -import { PEX } from '@sphereon/pex' import { Rules } from '@sphereon/pex-models' import { default as jp } from 'jsonpath' @@ -17,40 +17,42 @@ import { DifPresentationExchangeError } from '../DifPresentationExchangeError' import { getSphereonOriginalVerifiableCredential } from './transform' export async function getCredentialsForRequest( + // PEX instance with hasher defined + pex: PEX, presentationDefinition: IPresentationDefinition, - credentialRecords: Array, - holderDIDs: Array + credentialRecords: Array ): Promise { - if (!presentationDefinition) { - throw new DifPresentationExchangeError('Presentation Definition is required to select credentials for submission.') - } - - const pex = new PEX() - - const encodedCredentials = credentialRecords.map((c) => getSphereonOriginalVerifiableCredential(c.credential)) - - // FIXME: there is a function for this in the VP library, but it is not usable atm - const selectResultsRaw = pex.selectFrom(presentationDefinition, encodedCredentials, { - holderDIDs, - // limitDisclosureSignatureSuites: [], - // restrictToDIDMethods, - // restrictToFormats - }) + const encodedCredentials = credentialRecords.map((c) => getSphereonOriginalVerifiableCredential(c)) + const selectResultsRaw = pex.selectFrom(presentationDefinition, encodedCredentials) const selectResults = { ...selectResultsRaw, // Map the encoded credential to their respective w3c credential record - verifiableCredential: selectResultsRaw.verifiableCredential?.map((encoded) => { - const credentialRecord = credentialRecords.find((record) => { - const originalVc = getSphereonOriginalVerifiableCredential(record.credential) - return deepEquality(originalVc, encoded) + verifiableCredential: selectResultsRaw.verifiableCredential?.map((selectedEncoded) => { + const credentialRecordIndex = encodedCredentials.findIndex((encoded) => { + if ( + typeof selectedEncoded === 'string' && + selectedEncoded.includes('~') && + typeof encoded === 'string' && + encoded.includes('~') + ) { + // FIXME: pex applies SD-JWT, so we actually can't match the record anymore :( + // We take the first part of the sd-jwt, as that will never change, and should + // be unique on it's own + const [encodedJwt] = encoded.split('~') + const [selectedEncodedJwt] = selectedEncoded.split('~') + + return encodedJwt === selectedEncodedJwt + } else { + return deepEquality(selectedEncoded, encoded) + } }) - if (!credentialRecord) { + if (credentialRecordIndex === -1) { throw new DifPresentationExchangeError('Unable to find credential in credential records.') } - return credentialRecord + return credentialRecords[credentialRecordIndex] }), } @@ -95,7 +97,7 @@ export async function getCredentialsForRequest( function getSubmissionRequirements( presentationDefinition: IPresentationDefinition, - selectResults: W3cCredentialRecordSelectResults + selectResults: CredentialRecordSelectResults ): Array { const submissionRequirements: Array = [] @@ -141,7 +143,7 @@ function getSubmissionRequirements( function getSubmissionRequirementsForAllInputDescriptors( inputDescriptors: Array | Array, - selectResults: W3cCredentialRecordSelectResults + selectResults: CredentialRecordSelectResults ): Array { const submissionRequirements: Array = [] @@ -162,7 +164,7 @@ function getSubmissionRequirementsForAllInputDescriptors( function getSubmissionRequirementRuleAll( submissionRequirement: SubmissionRequirement, presentationDefinition: IPresentationDefinition, - selectResults: W3cCredentialRecordSelectResults + selectResults: CredentialRecordSelectResults ) { // Check if there's a 'from'. If not the structure is not as we expect it if (!submissionRequirement.from) @@ -201,7 +203,7 @@ function getSubmissionRequirementRuleAll( function getSubmissionRequirementRulePick( submissionRequirement: SubmissionRequirement, presentationDefinition: IPresentationDefinition, - selectResults: W3cCredentialRecordSelectResults + selectResults: CredentialRecordSelectResults ) { // Check if there's a 'from'. If not the structure is not as we expect it if (!submissionRequirement.from) { @@ -257,7 +259,7 @@ function getSubmissionRequirementRulePick( function getSubmissionForInputDescriptor( inputDescriptor: InputDescriptorV1 | InputDescriptorV2, - selectResults: W3cCredentialRecordSelectResults + selectResults: CredentialRecordSelectResults ): DifPexCredentialsForRequestSubmissionEntry { // https://github.com/Sphereon-Opensource/PEX/issues/116 // If the input descriptor doesn't contain a name, the name of the match will be the id of the input descriptor that satisfied it @@ -292,9 +294,9 @@ function getSubmissionForInputDescriptor( function extractCredentialsFromMatch( match: SubmissionRequirementMatch, - availableCredentials?: Array + availableCredentials?: Array ) { - const verifiableCredentials: Array = [] + const verifiableCredentials: Array = [] for (const vcPath of match.vc_path) { const [verifiableCredential] = jp.query({ verifiableCredential: availableCredentials }, vcPath) as [ @@ -307,8 +309,8 @@ function extractCredentialsFromMatch( } /** - * Custom SelectResults that include the W3cCredentialRecord instead of the encoded verifiable credential + * Custom SelectResults that includes the AFJ records instead of the encoded verifiable credential */ -export type W3cCredentialRecordSelectResults = Omit & { - verifiableCredential?: Array +type CredentialRecordSelectResults = Omit & { + verifiableCredential?: Array } diff --git a/packages/core/src/modules/dif-presentation-exchange/utils/index.ts b/packages/core/src/modules/dif-presentation-exchange/utils/index.ts index aaf44fa1b6..18fe3ad53c 100644 --- a/packages/core/src/modules/dif-presentation-exchange/utils/index.ts +++ b/packages/core/src/modules/dif-presentation-exchange/utils/index.ts @@ -1,2 +1,3 @@ export * from './transform' export * from './credentialSelection' +export * from './presentationsToCreate' diff --git a/packages/core/src/modules/dif-presentation-exchange/utils/presentationsToCreate.ts b/packages/core/src/modules/dif-presentation-exchange/utils/presentationsToCreate.ts new file mode 100644 index 0000000000..47cb5202ca --- /dev/null +++ b/packages/core/src/modules/dif-presentation-exchange/utils/presentationsToCreate.ts @@ -0,0 +1,89 @@ +import type { SdJwtVcRecord } from '../../sd-jwt-vc' +import type { DifPexInputDescriptorToCredentials } from '../models' + +import { W3cCredentialRecord, ClaimFormat } from '../../vc' +import { DifPresentationExchangeError } from '../DifPresentationExchangeError' + +// - the credentials included in the presentation +export interface SdJwtVcPresentationToCreate { + claimFormat: ClaimFormat.SdJwtVc + subjectIds: [] // subject is included in the cnf of the sd-jwt and automatically extracted by PEX + verifiableCredentials: [ + { + credential: SdJwtVcRecord + inputDescriptorId: string + } + ] // only one credential supported for SD-JWT-VC +} + +export interface JwtVpPresentationToCreate { + claimFormat: ClaimFormat.JwtVp + subjectIds: [string] // only one subject id supported for JWT VP + verifiableCredentials: Array<{ + credential: W3cCredentialRecord + inputDescriptorId: string + }> // multiple credentials supported for JWT VP +} + +export interface LdpVpPresentationToCreate { + claimFormat: ClaimFormat.LdpVp + // NOTE: we only support one subject id at the moment as we don't have proper + // support yet for adding multiple proofs to an LDP-VP + subjectIds: [string] + verifiableCredentials: Array<{ + credential: W3cCredentialRecord + inputDescriptorId: string + }> // multiple credentials supported for LDP VP +} + +export type PresentationToCreate = SdJwtVcPresentationToCreate | JwtVpPresentationToCreate | LdpVpPresentationToCreate + +// FIXME: we should extract supported format form top-level presentation definition, and input_descriptor as well +// to make sure the presentation we are going to create is a presentation format supported by the verifier. +// In addition we should allow to pass an override 'format' object, as specification like OID4VP do not use the +// PD formats, but define their own. +export function getPresentationsToCreate(credentialsForInputDescriptor: DifPexInputDescriptorToCredentials) { + const presentationsToCreate: Array = [] + + // We map all credentials for a input descriptor to the different subject ids. Each subjectId will need + // to create a separate proof (either on the same presentation or if not allowed by proof format on separate) + // presentations + for (const [inputDescriptorId, credentials] of Object.entries(credentialsForInputDescriptor)) { + for (const credential of credentials) { + if (credential instanceof W3cCredentialRecord) { + const subjectId = credential.credential.credentialSubjectIds[0] + if (!subjectId) { + throw new DifPresentationExchangeError('Missing required credential subject for creating the presentation.') + } + + // NOTE: we only support one subjectId per VP -- once we have proper support + // for multiple proofs on an LDP-VP we can add multiple subjectIds to a single VP for LDP-vp only + const expectedClaimFormat = + credential.credential.claimFormat === ClaimFormat.LdpVc ? ClaimFormat.LdpVp : ClaimFormat.JwtVp + const matchingClaimFormatAndSubject = presentationsToCreate.find( + (p): p is JwtVpPresentationToCreate => + p.claimFormat === expectedClaimFormat && p.subjectIds.includes(subjectId) + ) + + if (matchingClaimFormatAndSubject) { + matchingClaimFormatAndSubject.verifiableCredentials.push({ inputDescriptorId, credential }) + } else { + presentationsToCreate.push({ + claimFormat: expectedClaimFormat, + subjectIds: [subjectId], + verifiableCredentials: [{ credential, inputDescriptorId }], + }) + } + } else { + // SD-JWT-VC always needs it's own presentation + presentationsToCreate.push({ + claimFormat: ClaimFormat.SdJwtVc, + subjectIds: [], + verifiableCredentials: [{ inputDescriptorId, credential }], + }) + } + } + } + + return presentationsToCreate +} diff --git a/packages/core/src/modules/dif-presentation-exchange/utils/transform.ts b/packages/core/src/modules/dif-presentation-exchange/utils/transform.ts index e4d5f694c9..7748ec7d65 100644 --- a/packages/core/src/modules/dif-presentation-exchange/utils/transform.ts +++ b/packages/core/src/modules/dif-presentation-exchange/utils/transform.ts @@ -1,78 +1,54 @@ -import type { W3cVerifiableCredential, W3cVerifiablePresentation } from '../../vc' +import type { AgentContext } from '../../../agent' +import type { SdJwtVcRecord } from '../../sd-jwt-vc' +import type { W3cJsonPresentation } from '../../vc/models/presentation/W3cJsonPresentation' +import type { VerifiablePresentation } from '../models' import type { OriginalVerifiableCredential as SphereonOriginalVerifiableCredential, - W3CVerifiableCredential as SphereonW3cVerifiableCredential, - W3CVerifiablePresentation as SphereonW3cVerifiablePresentation, + OriginalVerifiablePresentation as SphereonOriginalVerifiablePresentation, + W3CVerifiablePresentation as SphereonW3CVerifiablePresentation, } from '@sphereon/ssi-types' +import { CredoError } from '../../../error' import { JsonTransformer } from '../../../utils' -import { - W3cJsonLdVerifiableCredential, - W3cJsonLdVerifiablePresentation, - W3cJwtVerifiableCredential, - W3cJwtVerifiablePresentation, - ClaimFormat, -} from '../../vc' -import { DifPresentationExchangeError } from '../DifPresentationExchangeError' +import { SdJwtVcApi } from '../../sd-jwt-vc' +import { W3cCredentialRecord, W3cJsonLdVerifiablePresentation, W3cJwtVerifiablePresentation } from '../../vc' export function getSphereonOriginalVerifiableCredential( - w3cVerifiableCredential: W3cVerifiableCredential + credentialRecord: W3cCredentialRecord | SdJwtVcRecord ): SphereonOriginalVerifiableCredential { - if (w3cVerifiableCredential.claimFormat === ClaimFormat.LdpVc) { - return JsonTransformer.toJSON(w3cVerifiableCredential) as SphereonOriginalVerifiableCredential - } else if (w3cVerifiableCredential.claimFormat === ClaimFormat.JwtVc) { - return w3cVerifiableCredential.serializedJwt + if (credentialRecord instanceof W3cCredentialRecord) { + return credentialRecord.credential.encoded as SphereonOriginalVerifiableCredential } else { - throw new DifPresentationExchangeError( - `Unsupported claim format. Only ${ClaimFormat.LdpVc} and ${ClaimFormat.JwtVc} are supported.` - ) + return credentialRecord.compactSdJwtVc } } -export function getSphereonW3cVerifiableCredential( - w3cVerifiableCredential: W3cVerifiableCredential -): SphereonW3cVerifiableCredential { - if (w3cVerifiableCredential.claimFormat === ClaimFormat.LdpVc) { - return JsonTransformer.toJSON(w3cVerifiableCredential) as SphereonW3cVerifiableCredential - } else if (w3cVerifiableCredential.claimFormat === ClaimFormat.JwtVc) { - return w3cVerifiableCredential.serializedJwt +export function getSphereonOriginalVerifiablePresentation( + verifiablePresentation: VerifiablePresentation +): SphereonOriginalVerifiablePresentation { + if ( + verifiablePresentation instanceof W3cJwtVerifiablePresentation || + verifiablePresentation instanceof W3cJsonLdVerifiablePresentation + ) { + return verifiablePresentation.encoded as SphereonOriginalVerifiablePresentation } else { - throw new DifPresentationExchangeError( - `Unsupported claim format. Only ${ClaimFormat.LdpVc} and ${ClaimFormat.JwtVc} are supported.` - ) + return verifiablePresentation.compact } } -export function getSphereonW3cVerifiablePresentation( - w3cVerifiablePresentation: W3cVerifiablePresentation -): SphereonW3cVerifiablePresentation { - if (w3cVerifiablePresentation instanceof W3cJsonLdVerifiablePresentation) { - return JsonTransformer.toJSON(w3cVerifiablePresentation) as SphereonW3cVerifiablePresentation - } else if (w3cVerifiablePresentation instanceof W3cJwtVerifiablePresentation) { - return w3cVerifiablePresentation.serializedJwt +// TODO: we might want to move this to some generic vc transformation util +export function getVerifiablePresentationFromEncoded( + agentContext: AgentContext, + encodedVerifiablePresentation: string | W3cJsonPresentation | SphereonW3CVerifiablePresentation +) { + if (typeof encodedVerifiablePresentation === 'string' && encodedVerifiablePresentation.includes('~')) { + const sdJwtVcApi = agentContext.dependencyManager.resolve(SdJwtVcApi) + return sdJwtVcApi.fromCompact(encodedVerifiablePresentation) + } else if (typeof encodedVerifiablePresentation === 'string') { + return W3cJwtVerifiablePresentation.fromSerializedJwt(encodedVerifiablePresentation) + } else if (typeof encodedVerifiablePresentation === 'object' && '@context' in encodedVerifiablePresentation) { + return JsonTransformer.fromJSON(encodedVerifiablePresentation, W3cJsonLdVerifiablePresentation) } else { - throw new DifPresentationExchangeError( - `Unsupported claim format. Only ${ClaimFormat.LdpVc} and ${ClaimFormat.JwtVc} are supported.` - ) - } -} - -export function getW3cVerifiablePresentationInstance( - w3cVerifiablePresentation: SphereonW3cVerifiablePresentation -): W3cVerifiablePresentation { - if (typeof w3cVerifiablePresentation === 'string') { - return W3cJwtVerifiablePresentation.fromSerializedJwt(w3cVerifiablePresentation) - } else { - return JsonTransformer.fromJSON(w3cVerifiablePresentation, W3cJsonLdVerifiablePresentation) - } -} - -export function getW3cVerifiableCredentialInstance( - w3cVerifiableCredential: SphereonW3cVerifiableCredential -): W3cVerifiableCredential { - if (typeof w3cVerifiableCredential === 'string') { - return W3cJwtVerifiableCredential.fromSerializedJwt(w3cVerifiableCredential) - } else { - return JsonTransformer.fromJSON(w3cVerifiableCredential, W3cJsonLdVerifiableCredential) + throw new CredoError('Unsupported verifiable presentation format') } } diff --git a/packages/core/src/modules/discover-features/DiscoverFeaturesModule.ts b/packages/core/src/modules/discover-features/DiscoverFeaturesModule.ts index bd97e12ec4..25c67f6d1d 100644 --- a/packages/core/src/modules/discover-features/DiscoverFeaturesModule.ts +++ b/packages/core/src/modules/discover-features/DiscoverFeaturesModule.ts @@ -21,9 +21,6 @@ export class DiscoverFeaturesModule implements Module { * Registers the dependencies of the discover features module on the dependency manager. */ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(DiscoverFeaturesApi) - // Config dependencyManager.registerInstance(DiscoverFeaturesModuleConfig, this.config) diff --git a/packages/core/src/modules/discover-features/__tests__/DiscoverFeaturesModule.test.ts b/packages/core/src/modules/discover-features/__tests__/DiscoverFeaturesModule.test.ts index e4c259b69c..d7aa96511e 100644 --- a/packages/core/src/modules/discover-features/__tests__/DiscoverFeaturesModule.test.ts +++ b/packages/core/src/modules/discover-features/__tests__/DiscoverFeaturesModule.test.ts @@ -1,7 +1,6 @@ import { FeatureRegistry } from '../../../agent/FeatureRegistry' import { Protocol } from '../../../agent/models' import { DependencyManager } from '../../../plugins/DependencyManager' -import { DiscoverFeaturesApi } from '../DiscoverFeaturesApi' import { DiscoverFeaturesModule } from '../DiscoverFeaturesModule' import { V1DiscoverFeaturesService } from '../protocol/v1' import { V2DiscoverFeaturesService } from '../protocol/v2' @@ -19,9 +18,6 @@ describe('DiscoverFeaturesModule', () => { test('registers dependencies on the dependency manager', () => { new DiscoverFeaturesModule().register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(DiscoverFeaturesApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(V1DiscoverFeaturesService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(V2DiscoverFeaturesService) diff --git a/packages/core/src/modules/generic-records/GenericRecordsModule.ts b/packages/core/src/modules/generic-records/GenericRecordsModule.ts index a302933083..9ba63eecc4 100644 --- a/packages/core/src/modules/generic-records/GenericRecordsModule.ts +++ b/packages/core/src/modules/generic-records/GenericRecordsModule.ts @@ -11,9 +11,6 @@ export class GenericRecordsModule implements Module { * Registers the dependencies of the generic records module on the dependency manager. */ public register(dependencyManager: DependencyManager) { - // Api - dependencyManager.registerContextScoped(GenericRecordsApi) - // Services dependencyManager.registerSingleton(GenericRecordService) diff --git a/packages/core/src/modules/generic-records/__tests__/GenericRecordsModule.test.ts b/packages/core/src/modules/generic-records/__tests__/GenericRecordsModule.test.ts index 498c7f6fc2..8913cc0a8b 100644 --- a/packages/core/src/modules/generic-records/__tests__/GenericRecordsModule.test.ts +++ b/packages/core/src/modules/generic-records/__tests__/GenericRecordsModule.test.ts @@ -1,5 +1,4 @@ import { DependencyManager } from '../../../plugins/DependencyManager' -import { GenericRecordsApi } from '../GenericRecordsApi' import { GenericRecordsModule } from '../GenericRecordsModule' import { GenericRecordsRepository } from '../repository/GenericRecordsRepository' import { GenericRecordService } from '../services/GenericRecordService' @@ -13,9 +12,6 @@ describe('GenericRecordsModule', () => { test('registers dependencies on the dependency manager', () => { new GenericRecordsModule().register(dependencyManager) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(GenericRecordsApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(GenericRecordService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(GenericRecordsRepository) diff --git a/packages/core/src/modules/message-pickup/MessagePickupModule.ts b/packages/core/src/modules/message-pickup/MessagePickupModule.ts index 5c8d869694..a108392287 100644 --- a/packages/core/src/modules/message-pickup/MessagePickupModule.ts +++ b/packages/core/src/modules/message-pickup/MessagePickupModule.ts @@ -43,9 +43,6 @@ export class MessagePickupModule { const module = new MessagePickupModule() module.register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(MessagePickupApi) - expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(1) expect(dependencyManager.registerInstance).toHaveBeenCalledWith(MessagePickupModuleConfig, module.config) diff --git a/packages/core/src/modules/oob/OutOfBandModule.ts b/packages/core/src/modules/oob/OutOfBandModule.ts index e79ab11ac8..c13fc6a150 100644 --- a/packages/core/src/modules/oob/OutOfBandModule.ts +++ b/packages/core/src/modules/oob/OutOfBandModule.ts @@ -14,9 +14,6 @@ export class OutOfBandModule implements Module { * Registers the dependencies of the ot of band module on the dependency manager. */ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(OutOfBandApi) - // Services dependencyManager.registerSingleton(OutOfBandService) diff --git a/packages/core/src/modules/oob/__tests__/OutOfBandModule.test.ts b/packages/core/src/modules/oob/__tests__/OutOfBandModule.test.ts index b1c9337335..1f012a8608 100644 --- a/packages/core/src/modules/oob/__tests__/OutOfBandModule.test.ts +++ b/packages/core/src/modules/oob/__tests__/OutOfBandModule.test.ts @@ -1,6 +1,5 @@ import { FeatureRegistry } from '../../../agent/FeatureRegistry' import { DependencyManager } from '../../../plugins/DependencyManager' -import { OutOfBandApi } from '../OutOfBandApi' import { OutOfBandModule } from '../OutOfBandModule' import { OutOfBandService } from '../OutOfBandService' import { OutOfBandRepository } from '../repository/OutOfBandRepository' @@ -18,9 +17,6 @@ describe('OutOfBandModule', () => { test('registers dependencies on the dependency manager', () => { new OutOfBandModule().register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(OutOfBandApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OutOfBandService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OutOfBandRepository) diff --git a/packages/core/src/modules/proofs/ProofsModule.ts b/packages/core/src/modules/proofs/ProofsModule.ts index b154e6bef3..483b0ee057 100644 --- a/packages/core/src/modules/proofs/ProofsModule.ts +++ b/packages/core/src/modules/proofs/ProofsModule.ts @@ -39,9 +39,6 @@ export class ProofsModule { }) proofsModule.register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(ProofsApi) - expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(1) expect(dependencyManager.registerInstance).toHaveBeenCalledWith(ProofsModuleConfig, proofsModule.config) diff --git a/packages/core/src/modules/proofs/formats/dif-presentation-exchange/DifPresentationExchangeProofFormatService.ts b/packages/core/src/modules/proofs/formats/dif-presentation-exchange/DifPresentationExchangeProofFormatService.ts index ee86351c68..48d792982d 100644 --- a/packages/core/src/modules/proofs/formats/dif-presentation-exchange/DifPresentationExchangeProofFormatService.ts +++ b/packages/core/src/modules/proofs/formats/dif-presentation-exchange/DifPresentationExchangeProofFormatService.ts @@ -28,7 +28,10 @@ import type { import { Attachment, AttachmentData } from '../../../../decorators/attachment/Attachment' import { CredoError } from '../../../../error' import { deepEquality, JsonTransformer } from '../../../../utils' -import { DifPresentationExchangeService } from '../../../dif-presentation-exchange' +import { + DifPresentationExchangeService, + DifPresentationExchangeSubmissionLocation, +} from '../../../dif-presentation-exchange' import { W3cCredentialService, ClaimFormat, @@ -179,28 +182,18 @@ export class PresentationExchangeProofFormatService implements ProofFormatServic const { presentation_definition: presentationDefinition, options } = requestAttachment.getDataAsJson() - const credentials: DifPexInputDescriptorToCredentials = proofFormats?.presentationExchange?.credentials ?? {} - if (Object.keys(credentials).length === 0) { - const { areRequirementsSatisfied, requirements } = await ps.getCredentialsForRequest( - agentContext, - presentationDefinition - ) - - if (!areRequirementsSatisfied) { - throw new CredoError('Requirements of the presentation definition could not be satisfied') - } - - requirements.forEach((r) => { - r.submissionEntry.forEach((r) => { - credentials[r.inputDescriptorId] = r.verifiableCredentials.map((c) => c.credential) - }) - }) + let credentials: DifPexInputDescriptorToCredentials + if (proofFormats?.presentationExchange?.credentials) { + credentials = proofFormats.presentationExchange.credentials + } else { + const credentialsForRequest = await ps.getCredentialsForRequest(agentContext, presentationDefinition) + credentials = ps.selectCredentialsForRequest(credentialsForRequest) } const presentation = await ps.createPresentation(agentContext, { presentationDefinition, credentialsForInputDescriptor: credentials, - challenge: options?.challenge, + challenge: options?.challenge ?? (await agentContext.wallet.generateNonce()), domain: options?.domain, }) @@ -208,9 +201,19 @@ export class PresentationExchangeProofFormatService implements ProofFormatServic throw new CredoError('Invalid amount of verifiable presentations. Only one is allowed.') } + if (presentation.presentationSubmissionLocation === DifPresentationExchangeSubmissionLocation.EXTERNAL) { + throw new CredoError('External presentation submission is not supported.') + } + const firstPresentation = presentation.verifiablePresentations[0] - const attachmentData = firstPresentation.encoded as DifPresentationExchangePresentation - const attachment = this.getFormatData(attachmentData, format.attachmentId) + + // TODO: they should all have `encoded` property so it's easy to use the resulting VP + const encodedFirstPresentation = + firstPresentation instanceof W3cJwtVerifiablePresentation || + firstPresentation instanceof W3cJsonLdVerifiablePresentation + ? firstPresentation.encoded + : firstPresentation?.compact + const attachment = this.getFormatData(encodedFirstPresentation, format.attachmentId) return { attachment, format } } @@ -229,10 +232,15 @@ export class PresentationExchangeProofFormatService implements ProofFormatServic // TODO: we should probably move this transformation logic into the VC module, so it // can be reused in Credo when we need to go from encoded -> parsed - if (typeof presentation === 'string') { + if (typeof presentation === 'string' && presentation.includes('~')) { + // NOTE: we need to define in the PEX RFC where to put the presentation_submission + throw new CredoError('Received SD-JWT VC in PEX proof format. This is not supported yet.') + } else if (typeof presentation === 'string') { + // If it's a string, we expect it to be a JWT VP parsedPresentation = W3cJwtVerifiablePresentation.fromSerializedJwt(presentation) jsonPresentation = parsedPresentation.presentation.toJSON() } else { + // Otherwise we expect it to be a JSON-LD VP parsedPresentation = JsonTransformer.fromJSON(presentation, W3cJsonLdVerifiablePresentation) jsonPresentation = parsedPresentation.toJSON() } diff --git a/packages/core/src/modules/routing/MediationRecipientModule.ts b/packages/core/src/modules/routing/MediationRecipientModule.ts index f27da353c9..e54fc294ef 100644 --- a/packages/core/src/modules/routing/MediationRecipientModule.ts +++ b/packages/core/src/modules/routing/MediationRecipientModule.ts @@ -22,9 +22,6 @@ export class MediationRecipientModule implements Module { * Registers the dependencies of the mediator recipient module on the dependency manager. */ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(MediationRecipientApi) - // Config dependencyManager.registerInstance(MediationRecipientModuleConfig, this.config) diff --git a/packages/core/src/modules/routing/MediatorModule.ts b/packages/core/src/modules/routing/MediatorModule.ts index 0ddc220263..afcfdd05b3 100644 --- a/packages/core/src/modules/routing/MediatorModule.ts +++ b/packages/core/src/modules/routing/MediatorModule.ts @@ -22,9 +22,6 @@ export class MediatorModule implements Module { * Registers the dependencies of the question answer module on the dependency manager. */ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(MediatorApi) - // Config dependencyManager.registerInstance(MediatorModuleConfig, this.config) diff --git a/packages/core/src/modules/routing/__tests__/MediationRecipientModule.test.ts b/packages/core/src/modules/routing/__tests__/MediationRecipientModule.test.ts index dad1f499be..4dcba55a5f 100644 --- a/packages/core/src/modules/routing/__tests__/MediationRecipientModule.test.ts +++ b/packages/core/src/modules/routing/__tests__/MediationRecipientModule.test.ts @@ -1,6 +1,5 @@ import { FeatureRegistry } from '../../../agent/FeatureRegistry' import { DependencyManager } from '../../../plugins/DependencyManager' -import { MediationRecipientApi } from '../MediationRecipientApi' import { MediationRecipientModule } from '../MediationRecipientModule' import { MediationRepository } from '../repository' import { MediationRecipientService, RoutingService } from '../services' @@ -19,9 +18,6 @@ describe('MediationRecipientModule', () => { test('registers dependencies on the dependency manager', () => { new MediationRecipientModule().register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(MediationRecipientApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(3) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(MediationRecipientService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(RoutingService) diff --git a/packages/core/src/modules/routing/__tests__/MediatorModule.test.ts b/packages/core/src/modules/routing/__tests__/MediatorModule.test.ts index 81ba044281..6161857475 100644 --- a/packages/core/src/modules/routing/__tests__/MediatorModule.test.ts +++ b/packages/core/src/modules/routing/__tests__/MediatorModule.test.ts @@ -1,6 +1,5 @@ import { FeatureRegistry } from '../../../agent/FeatureRegistry' import { DependencyManager } from '../../../plugins/DependencyManager' -import { MediatorApi } from '../MediatorApi' import { MediatorModule } from '../MediatorModule' import { MediationRepository, MediatorRoutingRepository } from '../repository' import { MediatorService } from '../services' @@ -18,9 +17,6 @@ describe('MediatorModule', () => { test('registers dependencies on the dependency manager', () => { new MediatorModule().register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(MediatorApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(3) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(MediatorService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(MediationRepository) diff --git a/packages/core/src/modules/sd-jwt-vc/SdJwtVcApi.ts b/packages/core/src/modules/sd-jwt-vc/SdJwtVcApi.ts new file mode 100644 index 0000000000..17dbd81273 --- /dev/null +++ b/packages/core/src/modules/sd-jwt-vc/SdJwtVcApi.ts @@ -0,0 +1,87 @@ +import type { + SdJwtVcSignOptions, + SdJwtVcHeader, + SdJwtVcPayload, + SdJwtVcPresentOptions, + SdJwtVcVerifyOptions, +} from './SdJwtVcOptions' +import type { SdJwtVcRecord } from './repository' +import type { Query } from '../../storage/StorageService' + +import { AgentContext } from '../../agent' +import { injectable } from '../../plugins' + +import { SdJwtVcService } from './SdJwtVcService' + +/** + * @public + */ +@injectable() +export class SdJwtVcApi { + private agentContext: AgentContext + private sdJwtVcService: SdJwtVcService + + public constructor(agentContext: AgentContext, sdJwtVcService: SdJwtVcService) { + this.agentContext = agentContext + this.sdJwtVcService = sdJwtVcService + } + + public async sign(options: SdJwtVcSignOptions) { + return await this.sdJwtVcService.sign(this.agentContext, options) + } + + /** + * + * Create a compact presentation of the sd-jwt. + * This presentation can be send in- or out-of-band to the verifier. + * + * Also, whether to include the holder key binding. + */ + public async present
( + options: SdJwtVcPresentOptions + ): Promise { + return await this.sdJwtVcService.present(this.agentContext, options) + } + + /** + * + * Verify an incoming sd-jwt. It will check whether everything is valid, but also returns parts of the validation. + * + * For example, you might still want to continue with a flow if not all the claims are included, but the signature is valid. + * + */ + public async verify
(options: SdJwtVcVerifyOptions) { + return await this.sdJwtVcService.verify(this.agentContext, options) + } + + /** + * Get and validate a sd-jwt-vc from a serialized JWT. + */ + public fromCompact
(sdJwtVcCompact: string) { + return this.sdJwtVcService.fromCompact(sdJwtVcCompact) + } + + public async store(compactSdJwtVc: string) { + return await this.sdJwtVcService.store(this.agentContext, compactSdJwtVc) + } + + public async getById(id: string): Promise { + return await this.sdJwtVcService.getById(this.agentContext, id) + } + + public async getAll(): Promise> { + return await this.sdJwtVcService.getAll(this.agentContext) + } + + public async findAllByQuery(query: Query): Promise> { + return await this.sdJwtVcService.findByQuery(this.agentContext, query) + } + + public async deleteById(id: string) { + return await this.sdJwtVcService.deleteById(this.agentContext, id) + } + + public async update(sdJwtVcRecord: SdJwtVcRecord) { + return await this.sdJwtVcService.update(this.agentContext, sdJwtVcRecord) + } +} diff --git a/packages/sd-jwt-vc/src/SdJwtVcError.ts b/packages/core/src/modules/sd-jwt-vc/SdJwtVcError.ts similarity index 52% rename from packages/sd-jwt-vc/src/SdJwtVcError.ts rename to packages/core/src/modules/sd-jwt-vc/SdJwtVcError.ts index 805dfaf741..f904811686 100644 --- a/packages/sd-jwt-vc/src/SdJwtVcError.ts +++ b/packages/core/src/modules/sd-jwt-vc/SdJwtVcError.ts @@ -1,3 +1,3 @@ -import { CredoError } from '@credo-ts/core' +import { CredoError } from '../../error' export class SdJwtVcError extends CredoError {} diff --git a/packages/sd-jwt-vc/src/SdJwtVcModule.ts b/packages/core/src/modules/sd-jwt-vc/SdJwtVcModule.ts similarity index 64% rename from packages/sd-jwt-vc/src/SdJwtVcModule.ts rename to packages/core/src/modules/sd-jwt-vc/SdJwtVcModule.ts index 19f92b3230..f25d959d97 100644 --- a/packages/sd-jwt-vc/src/SdJwtVcModule.ts +++ b/packages/core/src/modules/sd-jwt-vc/SdJwtVcModule.ts @@ -1,6 +1,6 @@ -import type { DependencyManager, Module } from '@credo-ts/core' +import type { Module, DependencyManager } from '../../plugins' -import { AgentConfig } from '@credo-ts/core' +import { AgentConfig } from '../../agent/AgentConfig' import { SdJwtVcApi } from './SdJwtVcApi' import { SdJwtVcService } from './SdJwtVcService' @@ -20,12 +20,9 @@ export class SdJwtVcModule implements Module { dependencyManager .resolve(AgentConfig) .logger.warn( - "The '@credo-ts/sd-jwt-vc' module is experimental and could have unexpected breaking changes. When using this module, make sure to use strict versions for all @credo-ts packages." + "The 'SdJwtVc' module is experimental and could have unexpected breaking changes. When using this module, make sure to use strict versions for all @credo-ts packages." ) - // Api - dependencyManager.registerContextScoped(this.api) - // Services dependencyManager.registerSingleton(SdJwtVcService) diff --git a/packages/core/src/modules/sd-jwt-vc/SdJwtVcOptions.ts b/packages/core/src/modules/sd-jwt-vc/SdJwtVcOptions.ts new file mode 100644 index 0000000000..fcad595f33 --- /dev/null +++ b/packages/core/src/modules/sd-jwt-vc/SdJwtVcOptions.ts @@ -0,0 +1,86 @@ +import type { JwkJson, Jwk } from '../../crypto' +import type { HashName } from '../../utils' +import type { DisclosureFrame, PresentationFrame } from '@sd-jwt/core' + +// TODO: extend with required claim names for input (e.g. vct) +export type SdJwtVcPayload = Record +export type SdJwtVcHeader = Record + +export interface SdJwtVcHolderDidBinding { + method: 'did' + didUrl: string +} + +export interface SdJwtVcHolderJwkBinding { + method: 'jwk' + jwk: JwkJson | Jwk +} + +export interface SdJwtVcIssuerDid { + method: 'did' + // didUrl referencing a specific key in a did document. + didUrl: string +} + +// We support jwk and did based binding for the holder at the moment +export type SdJwtVcHolderBinding = SdJwtVcHolderDidBinding | SdJwtVcHolderJwkBinding + +// We only support did based issuance currently, but we might want to add support +// for x509 or issuer metadata (as defined in SD-JWT VC) in the future +export type SdJwtVcIssuer = SdJwtVcIssuerDid + +export interface SdJwtVcSignOptions { + payload: Payload + holder: SdJwtVcHolderBinding + issuer: SdJwtVcIssuer + disclosureFrame?: DisclosureFrame + + /** + * Default of sha-256 will be used if not provided + */ + hashingAlgorithm?: HashName +} + +export type SdJwtVcPresentOptions = { + compactSdJwtVc: string + + /** + * Use true to disclose everything + */ + presentationFrame: PresentationFrame | true + + /** + * This information is received out-of-band from the verifier. + * The claims will be used to create a normal JWT, used for key binding. + */ + verifierMetadata: { + audience: string + nonce: string + issuedAt: number + } +} + +export type SdJwtVcVerifyOptions = { + compactSdJwtVc: string + + /** + * If the key binding object is present, the sd-jwt is required to have a key binding jwt attached + * and will be validated against the provided key binding options. + */ + keyBinding?: { + /** + * The expected `aud` value in the payload of the KB-JWT. The value of this is dependant on the + * exchange protocol used. + */ + audience: string + + /** + * The expected `nonce` value in the payload of the KB-JWT. The value of this is dependant on the + * exchange protocol used. + */ + nonce: string + } + + // TODO: update to requiredClaimFrame + requiredClaimKeys?: Array +} diff --git a/packages/core/src/modules/sd-jwt-vc/SdJwtVcService.ts b/packages/core/src/modules/sd-jwt-vc/SdJwtVcService.ts new file mode 100644 index 0000000000..f559e1471a --- /dev/null +++ b/packages/core/src/modules/sd-jwt-vc/SdJwtVcService.ts @@ -0,0 +1,425 @@ +import type { + SdJwtVcSignOptions, + SdJwtVcPresentOptions, + SdJwtVcVerifyOptions, + SdJwtVcPayload, + SdJwtVcHeader, + SdJwtVcHolderBinding, + SdJwtVcIssuer, +} from './SdJwtVcOptions' +import type { AgentContext } from '../../agent' +import type { JwkJson, Key } from '../../crypto' +import type { Query } from '../../storage/StorageService' +import type { Signer, SdJwtVcVerificationResult, Verifier, HasherAndAlgorithm, DisclosureItem } from '@sd-jwt/core' + +import { KeyBinding, SdJwtVc as _SdJwtVc, HasherAlgorithm } from '@sd-jwt/core' +import { decodeSdJwtVc } from '@sd-jwt/decode' +import { injectable } from 'tsyringe' + +import { Jwk, getJwkFromJson, getJwkFromKey } from '../../crypto' +import { TypedArrayEncoder, Hasher, Buffer } from '../../utils' +import { DidResolverService, parseDid, getKeyFromVerificationMethod } from '../dids' + +import { SdJwtVcError } from './SdJwtVcError' +import { SdJwtVcRecord, SdJwtVcRepository } from './repository' + +export { SdJwtVcVerificationResult, DisclosureItem } + +export interface SdJwtVc< + Header extends SdJwtVcHeader = SdJwtVcHeader, + Payload extends SdJwtVcPayload = SdJwtVcPayload +> { + compact: string + header: Header + + // TODO: payload type here is a lie, as it is the signed payload (so fields replaced with _sd) + payload: Payload + prettyClaims: Payload +} + +/** + * @internal + */ +@injectable() +export class SdJwtVcService { + private sdJwtVcRepository: SdJwtVcRepository + + public constructor(sdJwtVcRepository: SdJwtVcRepository) { + this.sdJwtVcRepository = sdJwtVcRepository + } + + public async sign(agentContext: AgentContext, options: SdJwtVcSignOptions) { + const { payload, disclosureFrame, hashingAlgorithm } = options + + // default is sha-256 + if (hashingAlgorithm && hashingAlgorithm !== 'sha-256') { + throw new SdJwtVcError(`Unsupported hashing algorithm used: ${hashingAlgorithm}`) + } + + const issuer = await this.extractKeyFromIssuer(agentContext, options.issuer) + const holderBinding = await this.extractKeyFromHolderBinding(agentContext, options.holder) + + const header = { + alg: issuer.alg, + typ: 'vc+sd-jwt', + kid: issuer.kid, + } as const + + const sdJwtVc = new _SdJwtVc({}, { disclosureFrame }) + .withHasher(this.hasher) + .withSigner(this.signer(agentContext, issuer.key)) + .withSaltGenerator(agentContext.wallet.generateNonce) + .withHeader(header) + .withPayload({ ...payload }) + + // Add the `cnf` claim for the holder key binding + sdJwtVc.addPayloadClaim('cnf', holderBinding.cnf) + + // Add `iss` claim + sdJwtVc.addPayloadClaim('iss', issuer.iss) + + // Add the issued at (iat) claim + sdJwtVc.addPayloadClaim('iat', Math.floor(new Date().getTime() / 1000)) + + const compact = await sdJwtVc.toCompact() + if (!sdJwtVc.signature) { + throw new SdJwtVcError('Invalid sd-jwt-vc state. Signature should have been set when calling `toCompact`.') + } + + return { + compact, + prettyClaims: await sdJwtVc.getPrettyClaims(), + header: sdJwtVc.header, + payload: sdJwtVc.payload, + } satisfies SdJwtVc + } + + public fromCompact
( + compactSdJwtVc: string + ): SdJwtVc { + // NOTE: we use decodeSdJwtVc so we can make this method sync + const { decodedPayload, header, signedPayload } = decodeSdJwtVc(compactSdJwtVc, Hasher.hash) + + return { + compact: compactSdJwtVc, + header: header as Header, + payload: signedPayload as Payload, + prettyClaims: decodedPayload as Payload, + } + } + + public async present
( + agentContext: AgentContext, + { compactSdJwtVc, presentationFrame, verifierMetadata }: SdJwtVcPresentOptions + ): Promise { + const sdJwtVc = _SdJwtVc.fromCompact
(compactSdJwtVc).withHasher(this.hasher) + const holder = await this.extractKeyFromHolderBinding(agentContext, this.parseHolderBindingFromCredential(sdJwtVc)) + + // FIXME: we create the SD-JWT in two steps as the _sd_hash is currently not included in the SD-JWT library + // so we add it ourselves, but for that we need the contents of the derived SD-JWT first + const compactDerivedSdJwtVc = await sdJwtVc.present(presentationFrame === true ? undefined : presentationFrame) + + let sdAlg: string + try { + sdAlg = sdJwtVc.getClaimInPayload('_sd_alg') + } catch (error) { + sdAlg = 'sha-256' + } + + const header = { + alg: holder.alg, + typ: 'kb+jwt', + } as const + + const payload = { + iat: verifierMetadata.issuedAt, + nonce: verifierMetadata.nonce, + aud: verifierMetadata.audience, + + // FIXME: _sd_hash is missing. See + // https://github.com/berendsliedrecht/sd-jwt-ts/issues/8 + _sd_hash: TypedArrayEncoder.toBase64URL(Hasher.hash(compactDerivedSdJwtVc, sdAlg)), + } + + const compactKbJwt = await new KeyBinding({ header, payload }) + .withSigner(this.signer(agentContext, holder.key)) + .toCompact() + + return `${compactDerivedSdJwtVc}${compactKbJwt}` + } + + public async verify
( + agentContext: AgentContext, + { compactSdJwtVc, keyBinding, requiredClaimKeys }: SdJwtVcVerifyOptions + ) { + const sdJwtVc = _SdJwtVc.fromCompact(compactSdJwtVc).withHasher(this.hasher) + + const issuer = await this.extractKeyFromIssuer(agentContext, this.parseIssuerFromCredential(sdJwtVc)) + const holder = await this.extractKeyFromHolderBinding(agentContext, this.parseHolderBindingFromCredential(sdJwtVc)) + + // FIXME: we currently pass in the required keys in the verification method and based on the header.typ we + // check if we need to use the issuer or holder key. Once better support in sd-jwt lib is available we can + // update this. + // See https://github.com/berendsliedrecht/sd-jwt-ts/pull/34 + // See https://github.com/berendsliedrecht/sd-jwt-ts/issues/15 + const verificationResult = await sdJwtVc.verify( + this.verifier(agentContext, { + issuer: issuer.key, + holder: holder.key, + }), + requiredClaimKeys, + holder.cnf + ) + + // If keyBinding is present, verify the key binding + try { + if (keyBinding) { + if (!sdJwtVc.keyBinding || !sdJwtVc.keyBinding.payload) { + throw new SdJwtVcError('Keybinding is required for verification of the sd-jwt-vc') + } + + let sdAlg: string + try { + sdAlg = sdJwtVc.getClaimInPayload('_sd_alg') + } catch (error) { + sdAlg = 'sha-256' + } + + // FIXME: Calculate _sd_hash. can be removed once below is resolved + // https://github.com/berendsliedrecht/sd-jwt-ts/issues/8 + const sdJwtParts = compactSdJwtVc.split('~') + sdJwtParts.pop() // remove kb-jwt + const sdJwtWithoutKbJwt = `${sdJwtParts.join('~')}~` + const sdHash = TypedArrayEncoder.toBase64URL(Hasher.hash(sdJwtWithoutKbJwt, sdAlg)) + + // Assert `aud` and `nonce` claims + sdJwtVc.keyBinding.assertClaimInPayload('aud', keyBinding.audience) + sdJwtVc.keyBinding.assertClaimInPayload('nonce', keyBinding.nonce) + sdJwtVc.keyBinding.assertClaimInPayload('_sd_hash', sdHash) + } + } catch (error) { + verificationResult.isKeyBindingValid = false + verificationResult.isValid = false + } + + return { + verification: verificationResult, + sdJwtVc: { + payload: sdJwtVc.payload, + header: sdJwtVc.header, + compact: compactSdJwtVc, + prettyClaims: await sdJwtVc.getPrettyClaims(), + } satisfies SdJwtVc, + } + } + + public async store(agentContext: AgentContext, compactSdJwtVc: string) { + const sdJwtVcRecord = new SdJwtVcRecord({ + compactSdJwtVc, + }) + await this.sdJwtVcRepository.save(agentContext, sdJwtVcRecord) + + return sdJwtVcRecord + } + + public async getById(agentContext: AgentContext, id: string): Promise { + return await this.sdJwtVcRepository.getById(agentContext, id) + } + + public async getAll(agentContext: AgentContext): Promise> { + return await this.sdJwtVcRepository.getAll(agentContext) + } + + public async findByQuery(agentContext: AgentContext, query: Query): Promise> { + return await this.sdJwtVcRepository.findByQuery(agentContext, query) + } + + public async deleteById(agentContext: AgentContext, id: string) { + await this.sdJwtVcRepository.deleteById(agentContext, id) + } + + public async update(agentContext: AgentContext, sdJwtVcRecord: SdJwtVcRecord) { + await this.sdJwtVcRepository.update(agentContext, sdJwtVcRecord) + } + + private async resolveDidUrl(agentContext: AgentContext, didUrl: string) { + const didResolver = agentContext.dependencyManager.resolve(DidResolverService) + const didDocument = await didResolver.resolveDidDocument(agentContext, didUrl) + + return { + verificationMethod: didDocument.dereferenceKey(didUrl, ['assertionMethod']), + didDocument, + } + } + + private get hasher(): HasherAndAlgorithm { + return { + algorithm: HasherAlgorithm.Sha256, + hasher: Hasher.hash, + } + } + + /** + * @todo validate the JWT header (alg) + */ + private signer
(agentContext: AgentContext, key: Key): Signer
{ + return async (input: string) => agentContext.wallet.sign({ key, data: TypedArrayEncoder.fromString(input) }) + } + + /** + * @todo validate the JWT header (alg) + */ + private verifier
( + agentContext: AgentContext, + verificationKeys: { + issuer: Key + holder: Key + } + ): Verifier
{ + return async ({ message, signature, publicKeyJwk, header }) => { + const keyFromPublicKeyJwk = publicKeyJwk ? getJwkFromJson(publicKeyJwk as JwkJson).key : undefined + + let key: Key + if (header.typ === 'kb+jwt') { + key = verificationKeys.holder + } else if (header.typ === 'vc+sd-jwt') { + key = verificationKeys.issuer + } else { + throw new SdJwtVcError(`Unsupported JWT type '${header.typ}'`) + } + + if (keyFromPublicKeyJwk && key.fingerprint !== keyFromPublicKeyJwk.fingerprint) { + throw new SdJwtVcError('The key used to verify the signature does not match the expected key') + } + + return await agentContext.wallet.verify({ + signature: Buffer.from(signature), + key, + data: TypedArrayEncoder.fromString(message), + }) + } + } + + private async extractKeyFromIssuer(agentContext: AgentContext, issuer: SdJwtVcIssuer) { + if (issuer.method === 'did') { + const parsedDid = parseDid(issuer.didUrl) + if (!parsedDid.fragment) { + throw new SdJwtVcError( + `didUrl '${issuer.didUrl}' does not contain a '#'. Unable to derive key from did document` + ) + } + + const { verificationMethod } = await this.resolveDidUrl(agentContext, issuer.didUrl) + const key = getKeyFromVerificationMethod(verificationMethod) + const alg = getJwkFromKey(key).supportedSignatureAlgorithms[0] + + return { + alg, + key, + iss: parsedDid.did, + kid: `#${parsedDid.fragment}`, + } + } + + throw new SdJwtVcError("Unsupported credential issuer. Only 'did' is supported at the moment.") + } + + private parseIssuerFromCredential
( + sdJwtVc: _SdJwtVc + ): SdJwtVcIssuer { + const iss = sdJwtVc.getClaimInPayload('iss') + + if (iss.startsWith('did:')) { + // If `did` is used, we require a relative KID to be present to identify + // the key used by issuer to sign the sd-jwt-vc + sdJwtVc.assertClaimInHeader('kid') + const issuerKid = sdJwtVc.getClaimInHeader('kid') + + let didUrl: string + if (issuerKid.startsWith('#')) { + didUrl = `${iss}${issuerKid}` + } else if (issuerKid.startsWith('did:')) { + const didFromKid = parseDid(issuerKid) + if (didFromKid.did !== iss) { + throw new SdJwtVcError( + `kid in header is an absolute DID URL, but the did (${didFromKid.did}) does not match with the 'iss' did (${iss})` + ) + } + + didUrl = issuerKid + } else { + throw new SdJwtVcError( + 'Invalid issuer kid for did. Only absolute or relative (starting with #) did urls are supported.' + ) + } + + return { + method: 'did', + didUrl, + } + } + throw new SdJwtVcError("Unsupported 'iss' value. Only did is supported at the moment.") + } + + private parseHolderBindingFromCredential
( + sdJwtVc: _SdJwtVc + ): SdJwtVcHolderBinding { + const cnf = sdJwtVc.getClaimInPayload<{ jwk?: JwkJson; kid?: string }>('cnf') + + if (cnf.jwk) { + return { + method: 'jwk', + jwk: cnf.jwk, + } + } else if (cnf.kid) { + if (!cnf.kid.startsWith('did:') || !cnf.kid.includes('#')) { + throw new SdJwtVcError('Invalid holder kid for did. Only absolute KIDs for cnf are supported') + } + return { + method: 'did', + didUrl: cnf.kid, + } + } + + throw new SdJwtVcError("Unsupported credential holder binding. Only 'did' and 'jwk' are supported at the moment.") + } + + private async extractKeyFromHolderBinding(agentContext: AgentContext, holder: SdJwtVcHolderBinding) { + if (holder.method === 'did') { + const parsedDid = parseDid(holder.didUrl) + if (!parsedDid.fragment) { + throw new SdJwtVcError( + `didUrl '${holder.didUrl}' does not contain a '#'. Unable to derive key from did document` + ) + } + + const { verificationMethod } = await this.resolveDidUrl(agentContext, holder.didUrl) + const key = getKeyFromVerificationMethod(verificationMethod) + const alg = getJwkFromKey(key).supportedSignatureAlgorithms[0] + + return { + alg, + key, + cnf: { + // We need to include the whole didUrl here, otherwise the verifier + // won't know which did it is associated with + kid: holder.didUrl, + }, + } + } else if (holder.method === 'jwk') { + const jwk = holder.jwk instanceof Jwk ? holder.jwk : getJwkFromJson(holder.jwk) + const key = jwk.key + const alg = jwk.supportedSignatureAlgorithms[0] + + return { + alg, + key, + cnf: { + jwk: jwk.toJson(), + }, + } + } + + throw new SdJwtVcError("Unsupported credential holder binding. Only 'did' and 'jwk' are supported at the moment.") + } +} diff --git a/packages/sd-jwt-vc/src/__tests__/SdJwtVcModule.test.ts b/packages/core/src/modules/sd-jwt-vc/__tests__/SdJwtVcModule.test.ts similarity index 81% rename from packages/sd-jwt-vc/src/__tests__/SdJwtVcModule.test.ts rename to packages/core/src/modules/sd-jwt-vc/__tests__/SdJwtVcModule.test.ts index ad9e2b2e2b..7ceb1a2873 100644 --- a/packages/sd-jwt-vc/src/__tests__/SdJwtVcModule.test.ts +++ b/packages/core/src/modules/sd-jwt-vc/__tests__/SdJwtVcModule.test.ts @@ -1,6 +1,5 @@ import type { DependencyManager } from '@credo-ts/core' -import { SdJwtVcApi } from '../SdJwtVcApi' import { SdJwtVcModule } from '../SdJwtVcModule' import { SdJwtVcService } from '../SdJwtVcService' import { SdJwtVcRepository } from '../repository' @@ -17,9 +16,6 @@ describe('SdJwtVcModule', () => { const sdJwtVcModule = new SdJwtVcModule() sdJwtVcModule.register(dependencyManager) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(SdJwtVcApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(SdJwtVcService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(SdJwtVcRepository) diff --git a/packages/sd-jwt-vc/src/__tests__/SdJwtVcService.test.ts b/packages/core/src/modules/sd-jwt-vc/__tests__/SdJwtVcService.test.ts similarity index 50% rename from packages/sd-jwt-vc/src/__tests__/SdJwtVcService.test.ts rename to packages/core/src/modules/sd-jwt-vc/__tests__/SdJwtVcService.test.ts index f21a5510c6..d0768ed58a 100644 --- a/packages/sd-jwt-vc/src/__tests__/SdJwtVcService.test.ts +++ b/packages/core/src/modules/sd-jwt-vc/__tests__/SdJwtVcService.test.ts @@ -1,17 +1,7 @@ -import type { Key, Logger } from '@credo-ts/core' +import type { SdJwtVcHeader } from '../SdJwtVcOptions' +import type { Jwk, Key } from '@credo-ts/core' -import { - getJwkFromKey, - DidKey, - DidsModule, - KeyDidRegistrar, - KeyDidResolver, - KeyType, - Agent, - TypedArrayEncoder, -} from '@credo-ts/core' - -import { getInMemoryAgentOptions } from '../../../core/tests' +import { getInMemoryAgentOptions } from '../../../../tests' import { SdJwtVcService } from '../SdJwtVcService' import { SdJwtVcRepository } from '../repository' @@ -24,6 +14,24 @@ import { simpleJwtVcPresentation, } from './sdjwtvc.fixtures' +import { + parseDid, + getJwkFromKey, + DidKey, + DidsModule, + KeyDidRegistrar, + KeyDidResolver, + KeyType, + Agent, + TypedArrayEncoder, +} from '@credo-ts/core' + +const jwkJsonWithoutUse = (jwk: Jwk) => { + const jwkJson = jwk.toJson() + delete jwkJson.use + return jwkJson +} + const agent = new Agent( getInMemoryAgentOptions( 'sdjwtvcserviceagent', @@ -37,7 +45,6 @@ const agent = new Agent( ) ) -const logger = jest.fn() as unknown as Logger agent.context.wallet.generateNonce = jest.fn(() => Promise.resolve('salt')) Date.prototype.getTime = jest.fn(() => 1698151532000) @@ -47,7 +54,6 @@ const SdJwtVcRepositoryMock = SdJwtVcRepository as jest.Mock describe('SdJwtVcService', () => { const verifierDid = 'did:key:zUC74VEqqhEHQcgv4zagSPkqFJxuNWuoBPKjJuHETEUeHLoSqWt92viSsmaWjy82y' let issuerDidUrl: string - let holderDidUrl: string let issuerKey: Key let holderKey: Key let sdJwtVcService: SdJwtVcService @@ -72,88 +78,109 @@ describe('SdJwtVcService', () => { const holderDidKey = new DidKey(holderKey) const holderDidDocument = holderDidKey.didDocument - holderDidUrl = (holderDidDocument.verificationMethod ?? [])[0].id await agent.dids.import({ didDocument: holderDidDocument, did: holderDidDocument.id }) const sdJwtVcRepositoryMock = new SdJwtVcRepositoryMock() - sdJwtVcService = new SdJwtVcService(sdJwtVcRepositoryMock, logger) + sdJwtVcService = new SdJwtVcService(sdJwtVcRepositoryMock) }) - describe('SdJwtVcService.create', () => { - test('Create sd-jwt-vc from a basic payload without disclosures', async () => { - const { compact, sdJwtVcRecord } = await sdJwtVcService.create( - agent.context, - { + describe('SdJwtVcService.sign', () => { + test('Sign sd-jwt-vc from a basic payload without disclosures', async () => { + const { compact } = await sdJwtVcService.sign(agent.context, { + payload: { claim: 'some-claim', - type: 'IdentityCredential', + vct: 'IdentityCredential', }, - { - issuerDidUrl, - holderDidUrl, - } - ) + holder: { + // FIXME: is it nicer API to just pass either didUrl or JWK? + // Or none if you don't want to bind it? + method: 'jwk', + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), + }, + issuer: { + method: 'did', + didUrl: issuerDidUrl, + }, + }) expect(compact).toStrictEqual(simpleJwtVc) - expect(sdJwtVcRecord.sdJwtVc.header).toEqual({ + const sdJwtVc = await sdJwtVcService.fromCompact(compact) + + expect(sdJwtVc.header).toEqual({ alg: 'EdDSA', typ: 'vc+sd-jwt', - kid: 'z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + kid: '#z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', }) - expect(sdJwtVcRecord.sdJwtVc.payload).toEqual({ + expect(sdJwtVc.prettyClaims).toEqual({ claim: 'some-claim', - type: 'IdentityCredential', + vct: 'IdentityCredential', iat: Math.floor(new Date().getTime() / 1000), - iss: issuerDidUrl.split('#')[0], + iss: parseDid(issuerDidUrl).did, cnf: { - jwk: getJwkFromKey(holderKey).toJson(), + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), }, }) }) test('Create sd-jwt-vc from a basic payload with a disclosure', async () => { - const { compact, sdJwtVcRecord } = await sdJwtVcService.create( - agent.context, - { claim: 'some-claim', type: 'IdentityCredential' }, - { - issuerDidUrl, - holderDidUrl, - disclosureFrame: { claim: true }, - } - ) + const { compact, header, prettyClaims, payload } = await sdJwtVcService.sign(agent.context, { + payload: { claim: 'some-claim', vct: 'IdentityCredential' }, + disclosureFrame: { claim: true }, + holder: { + method: 'jwk', + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), + }, + issuer: { + method: 'did', + didUrl: issuerDidUrl, + }, + }) expect(compact).toStrictEqual(sdJwtVcWithSingleDisclosure) - expect(sdJwtVcRecord.sdJwtVc.header).toEqual({ + expect(header).toEqual({ alg: 'EdDSA', typ: 'vc+sd-jwt', - kid: 'z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + kid: '#z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', }) - expect(sdJwtVcRecord.sdJwtVc.payload).toEqual({ - type: 'IdentityCredential', + expect(payload).toEqual({ + vct: 'IdentityCredential', iat: Math.floor(new Date().getTime() / 1000), iss: issuerDidUrl.split('#')[0], _sd: ['vcvFU4DsFKTqQ1vl4nelJWXTb_-0dNoBks6iqNFptyg'], _sd_alg: 'sha-256', cnf: { - jwk: getJwkFromKey(holderKey).toJson(), + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), }, }) - expect(sdJwtVcRecord.sdJwtVc.payload).not.toContain({ + expect(prettyClaims).toEqual({ + vct: 'IdentityCredential', + iat: Math.floor(new Date().getTime() / 1000), + iss: issuerDidUrl.split('#')[0], claim: 'some-claim', + cnf: { + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), + }, }) - - expect(sdJwtVcRecord.sdJwtVc.disclosures).toEqual(expect.arrayContaining([['salt', 'claim', 'some-claim']])) }) test('Create sd-jwt-vc from a basic payload with multiple (nested) disclosure', async () => { - const { compact, sdJwtVcRecord } = await sdJwtVcService.create( - agent.context, - { - type: 'IdentityCredential', + const { compact, header, payload, prettyClaims } = await sdJwtVcService.sign(agent.context, { + disclosureFrame: { + is_over_65: true, + is_over_21: true, + is_over_18: true, + birthdate: true, + email: true, + address: { region: true, country: true }, + given_name: true, + }, + payload: { + vct: 'IdentityCredential', given_name: 'John', family_name: 'Doe', email: 'johndoe@example.com', @@ -169,31 +196,26 @@ describe('SdJwtVcService', () => { is_over_21: true, is_over_65: true, }, - { - issuerDidUrl: issuerDidUrl, - holderDidUrl: holderDidUrl, - disclosureFrame: { - is_over_65: true, - is_over_21: true, - is_over_18: true, - birthdate: true, - email: true, - address: { region: true, country: true }, - given_name: true, - }, - } - ) + holder: { + method: 'jwk', + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), + }, + issuer: { + method: 'did', + didUrl: issuerDidUrl, + }, + }) expect(compact).toStrictEqual(complexSdJwtVc) - expect(sdJwtVcRecord.sdJwtVc.header).toEqual({ + expect(header).toEqual({ alg: 'EdDSA', typ: 'vc+sd-jwt', - kid: 'z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + kid: '#z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', }) - expect(sdJwtVcRecord.sdJwtVc.payload).toEqual({ - type: 'IdentityCredential', + expect(payload).toEqual({ + vct: 'IdentityCredential', iat: Math.floor(new Date().getTime() / 1000), address: { _sd: ['NJnmct0BqBME1JfBlC6jRQVRuevpEONiYw7A7MHuJyQ', 'om5ZztZHB-Gd00LG21CV_xM4FaENSoiaOXnTAJNczB4'], @@ -213,109 +235,94 @@ describe('SdJwtVcService', () => { ], _sd_alg: 'sha-256', cnf: { - jwk: getJwkFromKey(holderKey).toJson(), + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), }, }) - expect(sdJwtVcRecord.sdJwtVc.payload).not.toContain({ - family_name: 'Doe', - phone_number: '+1-202-555-0101', + expect(prettyClaims).toEqual({ + vct: 'IdentityCredential', + iat: Math.floor(new Date().getTime() / 1000), address: { region: 'Anystate', country: 'US', + locality: 'Anytown', + street_address: '123 Main St', }, + email: 'johndoe@example.com', + given_name: 'John', + phone_number: '+1-202-555-0101', + family_name: 'Doe', + iss: issuerDidUrl.split('#')[0], birthdate: '1940-01-01', is_over_18: true, is_over_21: true, is_over_65: true, + cnf: { + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), + }, }) - - expect(sdJwtVcRecord.sdJwtVc.disclosures).toEqual( - expect.arrayContaining([ - ['salt', 'is_over_65', true], - ['salt', 'is_over_21', true], - ['salt', 'is_over_18', true], - ['salt', 'birthdate', '1940-01-01'], - ['salt', 'email', 'johndoe@example.com'], - ['salt', 'region', 'Anystate'], - ['salt', 'country', 'US'], - ['salt', 'given_name', 'John'], - ]) - ) }) }) describe('SdJwtVcService.receive', () => { test('Receive sd-jwt-vc from a basic payload without disclosures', async () => { - const sdJwtVc = simpleJwtVc + const sdJwtVc = await sdJwtVcService.fromCompact(simpleJwtVc) + const sdJwtVcRecord = await sdJwtVcService.store(agent.context, sdJwtVc.compact) + expect(sdJwtVcRecord.compactSdJwtVc).toEqual(simpleJwtVc) - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { - issuerDidUrl, - holderDidUrl, - }) - - expect(sdJwtVcRecord.sdJwtVc.header).toEqual({ + expect(sdJwtVc.header).toEqual({ alg: 'EdDSA', typ: 'vc+sd-jwt', - kid: 'z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + kid: '#z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', }) - expect(sdJwtVcRecord.sdJwtVc.payload).toEqual({ + expect(sdJwtVc.payload).toEqual({ claim: 'some-claim', - type: 'IdentityCredential', + vct: 'IdentityCredential', iat: Math.floor(new Date().getTime() / 1000), iss: issuerDidUrl.split('#')[0], cnf: { - jwk: getJwkFromKey(holderKey).toJson(), + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), }, }) }) test('Receive sd-jwt-vc from a basic payload with a disclosure', async () => { - const sdJwtVc = sdJwtVcWithSingleDisclosure - - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { - issuerDidUrl, - holderDidUrl, - }) + const sdJwtVc = await sdJwtVcService.fromCompact(sdJwtVcWithSingleDisclosure) - expect(sdJwtVcRecord.sdJwtVc.header).toEqual({ + expect(sdJwtVc.header).toEqual({ alg: 'EdDSA', typ: 'vc+sd-jwt', - kid: 'z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + kid: '#z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', }) - expect(sdJwtVcRecord.sdJwtVc.payload).toEqual({ - type: 'IdentityCredential', + expect(sdJwtVc.payload).toEqual({ + vct: 'IdentityCredential', iat: Math.floor(new Date().getTime() / 1000), iss: issuerDidUrl.split('#')[0], _sd: ['vcvFU4DsFKTqQ1vl4nelJWXTb_-0dNoBks6iqNFptyg'], _sd_alg: 'sha-256', cnf: { - jwk: getJwkFromKey(holderKey).toJson(), + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), }, }) - expect(sdJwtVcRecord.sdJwtVc.payload).not.toContain({ + expect(sdJwtVc.payload).not.toContain({ claim: 'some-claim', }) - - expect(sdJwtVcRecord.sdJwtVc.disclosures).toEqual(expect.arrayContaining([['salt', 'claim', 'some-claim']])) }) test('Receive sd-jwt-vc from a basic payload with multiple (nested) disclosure', async () => { - const sdJwtVc = complexSdJwtVc - - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { holderDidUrl, issuerDidUrl }) + const sdJwtVc = await sdJwtVcService.fromCompact(complexSdJwtVc) - expect(sdJwtVcRecord.sdJwtVc.header).toEqual({ + expect(sdJwtVc.header).toEqual({ alg: 'EdDSA', typ: 'vc+sd-jwt', - kid: 'z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + kid: '#z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', }) - expect(sdJwtVcRecord.sdJwtVc.payload).toEqual({ - type: 'IdentityCredential', + expect(sdJwtVc.payload).toEqual({ + vct: 'IdentityCredential', iat: Math.floor(new Date().getTime() / 1000), family_name: 'Doe', iss: issuerDidUrl.split('#')[0], @@ -324,6 +331,7 @@ describe('SdJwtVcService', () => { locality: 'Anytown', street_address: '123 Main St', }, + _sd_alg: 'sha-256', phone_number: '+1-202-555-0101', _sd: [ '1Cur2k2A2oIB5CshSIf_A_Kg-l26u_qKuWQ79P0Vdas', @@ -333,50 +341,59 @@ describe('SdJwtVcService', () => { 'psauKUNWEi09nu3Cl89xKXgmpWENZl5uy1N1nyn_jMk', 'sN_ge0pHXF6qmsYnX1A9SdwJ8ch8aENkxbODsT74YwI', ], - _sd_alg: 'sha-256', cnf: { - jwk: getJwkFromKey(holderKey).toJson(), + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), }, }) - expect(sdJwtVcRecord.sdJwtVc.payload).not.toContain({ - family_name: 'Doe', - phone_number: '+1-202-555-0101', + expect(sdJwtVc.payload).not.toContain({ address: { region: 'Anystate', country: 'US', }, + family_name: 'Doe', + phone_number: '+1-202-555-0101', + email: 'johndoe@example.com', + given_name: 'John', birthdate: '1940-01-01', is_over_18: true, is_over_21: true, is_over_65: true, }) - expect(sdJwtVcRecord.sdJwtVc.disclosures).toEqual( - expect.arrayContaining([ - ['salt', 'is_over_65', true], - ['salt', 'is_over_21', true], - ['salt', 'is_over_18', true], - ['salt', 'birthdate', '1940-01-01'], - ['salt', 'email', 'johndoe@example.com'], - ['salt', 'region', 'Anystate'], - ['salt', 'country', 'US'], - ['salt', 'given_name', 'John'], - ]) - ) + expect(sdJwtVc.prettyClaims).toEqual({ + vct: 'IdentityCredential', + iat: Math.floor(new Date().getTime() / 1000), + family_name: 'Doe', + iss: issuerDidUrl.split('#')[0], + phone_number: '+1-202-555-0101', + email: 'johndoe@example.com', + given_name: 'John', + birthdate: '1940-01-01', + is_over_18: true, + is_over_21: true, + is_over_65: true, + address: { + region: 'Anystate', + country: 'US', + locality: 'Anytown', + street_address: '123 Main St', + }, + cnf: { + jwk: jwkJsonWithoutUse(getJwkFromKey(holderKey)), + }, + }) }) }) describe('SdJwtVcService.present', () => { test('Present sd-jwt-vc from a basic payload without disclosures', async () => { - const sdJwtVc = simpleJwtVc - - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { issuerDidUrl, holderDidUrl }) - - const presentation = await sdJwtVcService.present(agent.context, sdJwtVcRecord, { + const presentation = await sdJwtVcService.present(agent.context, { + compactSdJwtVc: simpleJwtVc, + presentationFrame: {}, verifierMetadata: { issuedAt: new Date().getTime() / 1000, - verifierDid, + audience: verifierDid, nonce: await agent.context.wallet.generateNonce(), }, }) @@ -385,34 +402,47 @@ describe('SdJwtVcService', () => { }) test('Present sd-jwt-vc from a basic payload with a disclosure', async () => { - const sdJwtVc = sdJwtVcWithSingleDisclosure - - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { holderDidUrl, issuerDidUrl }) - - const presentation = await sdJwtVcService.present(agent.context, sdJwtVcRecord, { + const presentation = await sdJwtVcService.present(agent.context, { + compactSdJwtVc: sdJwtVcWithSingleDisclosure, + presentationFrame: { + claim: true, + }, verifierMetadata: { issuedAt: new Date().getTime() / 1000, - verifierDid, + audience: verifierDid, nonce: await agent.context.wallet.generateNonce(), }, - includedDisclosureIndices: [0], }) expect(presentation).toStrictEqual(sdJwtVcWithSingleDisclosurePresentation) }) test('Present sd-jwt-vc from a basic payload with multiple (nested) disclosure', async () => { - const sdJwtVc = complexSdJwtVc - - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { holderDidUrl, issuerDidUrl }) - - const presentation = await sdJwtVcService.present(agent.context, sdJwtVcRecord, { + const presentation = await sdJwtVcService.present< + Record, + { + // FIXME: when not passing a payload, adding nested presentationFrame is broken + // Needs to be fixed in sd-jwt library + address: { + country: string + } + } + >(agent.context, { + compactSdJwtVc: complexSdJwtVc, verifierMetadata: { issuedAt: new Date().getTime() / 1000, - verifierDid, + audience: verifierDid, nonce: await agent.context.wallet.generateNonce(), }, - includedDisclosureIndices: [0, 1, 4, 6, 7], + presentationFrame: { + is_over_65: true, + is_over_21: true, + email: true, + address: { + country: true, + }, + given_name: true, + }, }) expect(presentation).toStrictEqual(complexSdJwtVcPresentation) @@ -421,27 +451,28 @@ describe('SdJwtVcService', () => { describe('SdJwtVcService.verify', () => { test('Verify sd-jwt-vc without disclosures', async () => { - const sdJwtVc = simpleJwtVc - - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { holderDidUrl, issuerDidUrl }) - - const presentation = await sdJwtVcService.present(agent.context, sdJwtVcRecord, { + const nonce = await agent.context.wallet.generateNonce() + const presentation = await sdJwtVcService.present(agent.context, { + compactSdJwtVc: simpleJwtVc, + // no disclosures + presentationFrame: {}, verifierMetadata: { issuedAt: new Date().getTime() / 1000, - verifierDid, - nonce: await agent.context.wallet.generateNonce(), + audience: verifierDid, + nonce, }, }) - const { validation } = await sdJwtVcService.verify(agent.context, presentation, { - challenge: { verifierDid }, - holderDidUrl, + const { verification } = await sdJwtVcService.verify(agent.context, { + compactSdJwtVc: presentation, + keyBinding: { audience: verifierDid, nonce }, requiredClaimKeys: ['claim'], }) - expect(validation).toEqual({ + expect(verification).toEqual({ isSignatureValid: true, containsRequiredVcProperties: true, + containsExpectedKeyBinding: true, areRequiredClaimsIncluded: true, isValid: true, isKeyBindingValid: true, @@ -449,53 +480,67 @@ describe('SdJwtVcService', () => { }) test('Verify sd-jwt-vc with a disclosure', async () => { - const sdJwtVc = sdJwtVcWithSingleDisclosure + const nonce = await agent.context.wallet.generateNonce() - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { holderDidUrl, issuerDidUrl }) - - const presentation = await sdJwtVcService.present(agent.context, sdJwtVcRecord, { + const presentation = await sdJwtVcService.present(agent.context, { + compactSdJwtVc: sdJwtVcWithSingleDisclosure, verifierMetadata: { issuedAt: new Date().getTime() / 1000, - verifierDid, - nonce: await agent.context.wallet.generateNonce(), + audience: verifierDid, + nonce, + }, + presentationFrame: { + claim: true, }, - includedDisclosureIndices: [0], }) - const { validation } = await sdJwtVcService.verify(agent.context, presentation, { - challenge: { verifierDid }, - holderDidUrl, - requiredClaimKeys: ['type', 'cnf', 'claim', 'iat'], + const { verification } = await sdJwtVcService.verify(agent.context, { + compactSdJwtVc: presentation, + keyBinding: { audience: verifierDid, nonce }, + requiredClaimKeys: ['vct', 'cnf', 'claim', 'iat'], }) - expect(validation).toEqual({ + expect(verification).toEqual({ isSignatureValid: true, containsRequiredVcProperties: true, areRequiredClaimsIncluded: true, isValid: true, isKeyBindingValid: true, + containsExpectedKeyBinding: true, }) }) test('Verify sd-jwt-vc with multiple (nested) disclosure', async () => { - const sdJwtVc = complexSdJwtVc + const nonce = await agent.context.wallet.generateNonce() - const sdJwtVcRecord = await sdJwtVcService.storeCredential(agent.context, sdJwtVc, { holderDidUrl, issuerDidUrl }) - - const presentation = await sdJwtVcService.present(agent.context, sdJwtVcRecord, { - verifierMetadata: { - issuedAt: new Date().getTime() / 1000, - verifierDid, - nonce: await agent.context.wallet.generateNonce(), - }, - includedDisclosureIndices: [0, 1, 4, 6, 7], - }) + const presentation = await sdJwtVcService.present( + agent.context, + { + compactSdJwtVc: complexSdJwtVc, + verifierMetadata: { + issuedAt: new Date().getTime() / 1000, + audience: verifierDid, + nonce, + }, + presentationFrame: { + is_over_65: true, + is_over_21: true, + email: true, + address: { + country: true, + }, + given_name: true, + }, + } + ) - const { validation } = await sdJwtVcService.verify(agent.context, presentation, { - challenge: { verifierDid }, - holderDidUrl, + const { verification } = await sdJwtVcService.verify(agent.context, { + compactSdJwtVc: presentation, + keyBinding: { audience: verifierDid, nonce }, + // FIXME: this should be a requiredFrame to be consistent with the other methods + // using frames requiredClaimKeys: [ - 'type', + 'vct', 'family_name', 'phone_number', 'address', @@ -512,13 +557,30 @@ describe('SdJwtVcService', () => { ], }) - expect(validation).toEqual({ + expect(verification).toEqual({ isSignatureValid: true, areRequiredClaimsIncluded: true, + containsExpectedKeyBinding: true, containsRequiredVcProperties: true, isValid: true, isKeyBindingValid: true, }) }) + + test('Verify did holder-bound sd-jwt-vc with disclosures and kb-jwt', async () => { + const verificationResult = await sdJwtVcService.verify( + agent.context, + { + compactSdJwtVc: + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rcnpRUEJyNHB5cUM3NzZLS3RyejEzU2NoTTVlUFBic3N1UHVRWmI1dDR1S1EifQ.eyJ2Y3QiOiJPcGVuQmFkZ2VDcmVkZW50aWFsIiwiZGVncmVlIjoiYmFjaGVsb3IiLCJjbmYiOnsia2lkIjoiZGlkOmtleTp6Nk1rcEdSNGdzNFJjM1pwaDR2ajh3Um5qbkF4Z0FQU3hjUjhNQVZLdXRXc3BRemMjejZNa3BHUjRnczRSYzNacGg0dmo4d1Juam5BeGdBUFN4Y1I4TUFWS3V0V3NwUXpjIn0sImlzcyI6ImRpZDprZXk6ejZNa3J6UVBCcjRweXFDNzc2S0t0cnoxM1NjaE01ZVBQYnNzdVB1UVpiNXQ0dUtRIiwiaWF0IjoxNzA2MjY0ODQwLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyJTSm81ME0xX3NUQWRPSjFObF82ekJzZWg3Ynd4czhhbDhleVotQl9nTXZFIiwiYTJjT2xWOXY4TUlWNTRvMVFrODdBMDRNZ0c3Q0hiaFZUN1lkb00zUnM4RSJdfQ.PrZtmLFPr8tBY0FKsv2yHJeqzds8m0Rlrof-Z36o7ksNvON3ZSrKHOD8fFDJaQ8oFJcZAnjpUS6pY9kwAgU1Ag~WyI5Mjg3NDM3NDQyMTg0ODk1NTU3OTA1NTkiLCJ1bml2ZXJzaXR5IiwiaW5uc2JydWNrIl0~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE3MDYyNjQ4NDAsIm5vbmNlIjoiODExNzMxNDIwNTMxODQ3NzAwNjM2ODUiLCJhdWQiOiJkaWQ6a2V5Ono2TWt0aVFRRXFtMnlhcFhCRHQxV0VWQjNkcWd2eXppOTZGdUZBTlltcmdUcktWOSIsIl9zZF9oYXNoIjoiSVd0cTEtOGUtLU9wWWpXa3Z1RTZrRjlaa2h5aDVfV3lOYXItaWtVT0FscyJ9.cJNnYH16lHn0PsF9tOQPofpONGoY19bQB5k6Ezux9TvQWS_Opnd-3m_fO9yKu8S0pmjyG2mu3Uzn1pUNqhL9AQ', + keyBinding: { + audience: 'did:key:z6MktiQQEqm2yapXBDt1WEVB3dqgvyzi96FuFANYmrgTrKV9', + nonce: '81173142053184770063685', + }, + } + ) + + expect(verificationResult.verification.isValid).toBe(true) + }) }) }) diff --git a/packages/core/src/modules/sd-jwt-vc/__tests__/sdJwtVc.e2e.test.ts b/packages/core/src/modules/sd-jwt-vc/__tests__/sdJwtVc.e2e.test.ts new file mode 100644 index 0000000000..5174041566 --- /dev/null +++ b/packages/core/src/modules/sd-jwt-vc/__tests__/sdJwtVc.e2e.test.ts @@ -0,0 +1,241 @@ +import type { Key } from '@credo-ts/core' + +import { AskarModule } from '../../../../../askar/src' +import { askarModuleConfig } from '../../../../../askar/tests/helpers' +import { agentDependencies } from '../../../../tests' + +import { + Agent, + DidKey, + DidsModule, + getJwkFromKey, + KeyDidRegistrar, + KeyDidResolver, + KeyType, + TypedArrayEncoder, + utils, +} from '@credo-ts/core' + +const getAgent = (label: string) => + new Agent({ + config: { label, walletConfig: { id: utils.uuid(), key: utils.uuid() } }, + modules: { + askar: new AskarModule(askarModuleConfig), + dids: new DidsModule({ + resolvers: [new KeyDidResolver()], + registrars: [new KeyDidRegistrar()], + }), + }, + dependencies: agentDependencies, + }) + +describe('sd-jwt-vc end to end test', () => { + const issuer = getAgent('sdjwtvcissueragent') + let issuerKey: Key + let issuerDidUrl: string + + const holder = getAgent('sdjwtvcholderagent') + let holderKey: Key + + const verifier = getAgent('sdjwtvcverifieragent') + const verifierDid = 'did:key:zUC74VEqqhEHQcgv4zagSPkqFJxuNWuoBPKjJuHETEUeHLoSqWt92viSsmaWjy82y' + + beforeAll(async () => { + await issuer.initialize() + issuerKey = await issuer.context.wallet.createKey({ + keyType: KeyType.Ed25519, + seed: TypedArrayEncoder.fromString('00000000000000000000000000000000'), + }) + + const issuerDidKey = new DidKey(issuerKey) + const issuerDidDocument = issuerDidKey.didDocument + issuerDidUrl = (issuerDidDocument.verificationMethod ?? [])[0].id + await issuer.dids.import({ didDocument: issuerDidDocument, did: issuerDidDocument.id }) + + await holder.initialize() + holderKey = await holder.context.wallet.createKey({ + keyType: KeyType.Ed25519, + seed: TypedArrayEncoder.fromString('00000000000000000000000000000001'), + }) + + await verifier.initialize() + }) + + test('end to end flow', async () => { + const credential = { + vct: 'IdentityCredential', + given_name: 'John', + family_name: 'Doe', + email: 'johndoe@example.com', + phone_number: '+1-202-555-0101', + address: { + street_address: '123 Main St', + locality: 'Anytown', + region: 'Anystate', + country: 'US', + }, + birthdate: '1940-01-01', + is_over_18: true, + is_over_21: true, + is_over_65: true, + } as const + + const { compact, header, payload } = await issuer.sdJwtVc.sign({ + payload: credential, + holder: { + method: 'jwk', + jwk: getJwkFromKey(holderKey), + }, + issuer: { + didUrl: issuerDidUrl, + method: 'did', + }, + disclosureFrame: { + is_over_65: true, + is_over_21: true, + is_over_18: true, + birthdate: true, + email: true, + address: { country: true, region: true, locality: true, __decoyCount: 2, street_address: true }, + __decoyCount: 2, + given_name: true, + family_name: true, + phone_number: true, + }, + }) + + type Payload = typeof payload + type Header = typeof header + + // parse SD-JWT + const sdJwtVc = holder.sdJwtVc.fromCompact(compact) + expect(sdJwtVc).toEqual({ + compact: expect.any(String), + header: { + alg: 'EdDSA', + kid: '#z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + typ: 'vc+sd-jwt', + }, + payload: { + _sd: [ + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + ], + _sd_alg: 'sha-256', + address: { + _sd: [ + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + expect.any(String), + ], + }, + cnf: { + jwk: { + crv: 'Ed25519', + kty: 'OKP', + x: 'oENVsxOUiH54X8wJLaVkicCRk00wBIQ4sRgbk54N8Mo', + }, + }, + iat: expect.any(Number), + iss: 'did:key:z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + vct: 'IdentityCredential', + }, + prettyClaims: { + address: { + country: 'US', + locality: 'Anytown', + region: 'Anystate', + street_address: '123 Main St', + }, + birthdate: '1940-01-01', + cnf: { + jwk: { + crv: 'Ed25519', + kty: 'OKP', + x: 'oENVsxOUiH54X8wJLaVkicCRk00wBIQ4sRgbk54N8Mo', + }, + }, + email: 'johndoe@example.com', + family_name: 'Doe', + given_name: 'John', + iat: expect.any(Number), + is_over_18: true, + is_over_21: true, + is_over_65: true, + iss: 'did:key:z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW', + phone_number: '+1-202-555-0101', + vct: 'IdentityCredential', + }, + }) + + // Verify SD-JWT (does not require key binding) + const { verification } = await holder.sdJwtVc.verify({ + compactSdJwtVc: compact, + }) + expect(verification.isValid).toBe(true) + + // Store credential + await holder.sdJwtVc.store(compact) + + // Metadata created by the verifier and send out of band by the verifier to the holder + const verifierMetadata = { + audience: verifierDid, + issuedAt: new Date().getTime() / 1000, + nonce: await verifier.wallet.generateNonce(), + } + + const presentation = await holder.sdJwtVc.present({ + compactSdJwtVc: compact, + verifierMetadata, + presentationFrame: { + vct: true, + given_name: true, + family_name: true, + email: true, + phone_number: true, + address: { + street_address: true, + locality: true, + region: true, + country: true, + }, + birthdate: true, + is_over_18: true, + is_over_21: true, + is_over_65: true, + }, + }) + + const { verification: presentationVerification } = await verifier.sdJwtVc.verify({ + compactSdJwtVc: presentation, + keyBinding: { audience: verifierDid, nonce: verifierMetadata.nonce }, + requiredClaimKeys: [ + 'is_over_65', + 'is_over_21', + 'is_over_18', + 'birthdate', + 'email', + 'country', + 'region', + 'locality', + 'street_address', + 'given_name', + 'family_name', + 'phone_number', + ], + }) + + expect(presentationVerification.isValid).toBeTruthy() + }) +}) diff --git a/packages/core/src/modules/sd-jwt-vc/__tests__/sdjwtvc.fixtures.ts b/packages/core/src/modules/sd-jwt-vc/__tests__/sdjwtvc.fixtures.ts new file mode 100644 index 0000000000..1cbb1b112c --- /dev/null +++ b/packages/core/src/modules/sd-jwt-vc/__tests__/sdjwtvc.fixtures.ts @@ -0,0 +1,17 @@ +export const simpleJwtVc = + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJjbGFpbSI6InNvbWUtY2xhaW0iLCJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJjbmYiOnsiandrIjp7Imt0eSI6Ik9LUCIsImNydiI6IkVkMjU1MTkiLCJ4Ijoib0VOVnN4T1VpSDU0WDh3SkxhVmtpY0NSazAwd0JJUTRzUmdiazU0TjhNbyJ9fSwiaXNzIjoiZGlkOmtleTp6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlciLCJpYXQiOjE2OTgxNTE1MzJ9.hcNF6_PnQO4Gm0vqD_iblyBknUG0PeQLbIpPJ5s0P4UCQ7YdSSNCNL7VNOfzzAxZRWbH5knhje0_xYl6OXQ-CA~' + +export const simpleJwtVcPresentation = + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJjbGFpbSI6InNvbWUtY2xhaW0iLCJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJjbmYiOnsiandrIjp7Imt0eSI6Ik9LUCIsImNydiI6IkVkMjU1MTkiLCJ4Ijoib0VOVnN4T1VpSDU0WDh3SkxhVmtpY0NSazAwd0JJUTRzUmdiazU0TjhNbyJ9fSwiaXNzIjoiZGlkOmtleTp6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlciLCJpYXQiOjE2OTgxNTE1MzJ9.hcNF6_PnQO4Gm0vqD_iblyBknUG0PeQLbIpPJ5s0P4UCQ7YdSSNCNL7VNOfzzAxZRWbH5knhje0_xYl6OXQ-CA~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkiLCJfc2RfaGFzaCI6IkN4SnFuQ1Btd0d6bjg4YTlDdGhta2pHZXFXbnlKVTVKc2NLMXJ1VThOS28ifQ.0QaDyJrvZO91o7gdKPduKQIj5Z1gBAdWPNE8-PFqhj_rC56_I5aL8QtlwL8Mdl6iSjpUPDQ4LAN2JgB2nNOFBw' + +export const sdJwtVcWithSingleDisclosure = + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJjbmYiOnsiandrIjp7Imt0eSI6Ik9LUCIsImNydiI6IkVkMjU1MTkiLCJ4Ijoib0VOVnN4T1VpSDU0WDh3SkxhVmtpY0NSazAwd0JJUTRzUmdiazU0TjhNbyJ9fSwiaXNzIjoiZGlkOmtleTp6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlciLCJpYXQiOjE2OTgxNTE1MzIsIl9zZF9hbGciOiJzaGEtMjU2IiwiX3NkIjpbInZjdkZVNERzRktUcVExdmw0bmVsSldYVGJfLTBkTm9Ca3M2aXFORnB0eWciXX0.Op3rwd7t6ZsdMSMa1EchAm31bP5aqLF6pB-Z1y-h3CFJYGmhNTkMpTeft1I3hSWq7QmbqBo1GKBEiZc7D9B9DA~WyJzYWx0IiwiY2xhaW0iLCJzb21lLWNsYWltIl0~' + +export const sdJwtVcWithSingleDisclosurePresentation = + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJjbmYiOnsiandrIjp7Imt0eSI6Ik9LUCIsImNydiI6IkVkMjU1MTkiLCJ4Ijoib0VOVnN4T1VpSDU0WDh3SkxhVmtpY0NSazAwd0JJUTRzUmdiazU0TjhNbyJ9fSwiaXNzIjoiZGlkOmtleTp6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlciLCJpYXQiOjE2OTgxNTE1MzIsIl9zZF9hbGciOiJzaGEtMjU2IiwiX3NkIjpbInZjdkZVNERzRktUcVExdmw0bmVsSldYVGJfLTBkTm9Ca3M2aXFORnB0eWciXX0.Op3rwd7t6ZsdMSMa1EchAm31bP5aqLF6pB-Z1y-h3CFJYGmhNTkMpTeft1I3hSWq7QmbqBo1GKBEiZc7D9B9DA~WyJzYWx0IiwiY2xhaW0iLCJzb21lLWNsYWltIl0~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkiLCJfc2RfaGFzaCI6IlBNbEo3bjhjdVdvUU9YTFZ4cTRhaWRaNHJTY2FrVUtMT1hUaUtWYjYtYTQifQ.5iYVLw6U7NIdW7Eoo2jYYBsR3fSJZ-ocOtI6rxl-GYUj8ZeCx_-IZ2rbwCMf71tq6M16x4ROooKGAdfWUSWQAg' + +export const complexSdJwtVc = + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJmYW1pbHlfbmFtZSI6IkRvZSIsInBob25lX251bWJlciI6IisxLTIwMi01NTUtMDEwMSIsImFkZHJlc3MiOnsic3RyZWV0X2FkZHJlc3MiOiIxMjMgTWFpbiBTdCIsImxvY2FsaXR5IjoiQW55dG93biIsIl9zZCI6WyJOSm5tY3QwQnFCTUUxSmZCbEM2alJRVlJ1ZXZwRU9OaVl3N0E3TUh1SnlRIiwib201Wnp0WkhCLUdkMDBMRzIxQ1ZfeE00RmFFTlNvaWFPWG5UQUpOY3pCNCJdfSwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyIxQ3VyMmsyQTJvSUI1Q3NoU0lmX0FfS2ctbDI2dV9xS3VXUTc5UDBWZGFzIiwiUjF6VFV2T1lIZ2NlcGowakh5cEdIejlFSHR0VktmdDB5c3diYzlFVFBiVSIsImVEcVFwZFRYSlhiV2hmLUVzSTd6dzVYNk92WW1GTi1VWlFRTWVzWHdLUHciLCJwZERrMl9YQUtIbzdnT0Fmd0YxYjdPZENVVlRpdDJrSkhheFNFQ1E5eGZjIiwicHNhdUtVTldFaTA5bnUzQ2w4OXhLWGdtcFdFTlpsNXV5MU4xbnluX2pNayIsInNOX2dlMHBIWEY2cW1zWW5YMUE5U2R3SjhjaDhhRU5reGJPRHNUNzRZd0kiXX0.coOK8NzJmEWz4qx-qRhjo-RK7aejrSkQM9La9Cw3eWmzcja9DXrkBoQZKbIJtNoSzSPLjwK2V71W78z0miZsDQ~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8xOCIsdHJ1ZV0~WyJzYWx0IiwiYmlydGhkYXRlIiwiMTk0MC0wMS0wMSJd~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwicmVnaW9uIiwiQW55c3RhdGUiXQ~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~' + +export const complexSdJwtVcPresentation = + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJmYW1pbHlfbmFtZSI6IkRvZSIsInBob25lX251bWJlciI6IisxLTIwMi01NTUtMDEwMSIsImFkZHJlc3MiOnsic3RyZWV0X2FkZHJlc3MiOiIxMjMgTWFpbiBTdCIsImxvY2FsaXR5IjoiQW55dG93biIsIl9zZCI6WyJOSm5tY3QwQnFCTUUxSmZCbEM2alJRVlJ1ZXZwRU9OaVl3N0E3TUh1SnlRIiwib201Wnp0WkhCLUdkMDBMRzIxQ1ZfeE00RmFFTlNvaWFPWG5UQUpOY3pCNCJdfSwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyIxQ3VyMmsyQTJvSUI1Q3NoU0lmX0FfS2ctbDI2dV9xS3VXUTc5UDBWZGFzIiwiUjF6VFV2T1lIZ2NlcGowakh5cEdIejlFSHR0VktmdDB5c3diYzlFVFBiVSIsImVEcVFwZFRYSlhiV2hmLUVzSTd6dzVYNk92WW1GTi1VWlFRTWVzWHdLUHciLCJwZERrMl9YQUtIbzdnT0Fmd0YxYjdPZENVVlRpdDJrSkhheFNFQ1E5eGZjIiwicHNhdUtVTldFaTA5bnUzQ2w4OXhLWGdtcFdFTlpsNXV5MU4xbnluX2pNayIsInNOX2dlMHBIWEY2cW1zWW5YMUE5U2R3SjhjaDhhRU5reGJPRHNUNzRZd0kiXX0.coOK8NzJmEWz4qx-qRhjo-RK7aejrSkQM9La9Cw3eWmzcja9DXrkBoQZKbIJtNoSzSPLjwK2V71W78z0miZsDQ~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkiLCJfc2RfaGFzaCI6Ii1kTUd4OGZhUnpOQm91a2EwU0R6V2JkS3JYckw1TFVmUlNQTHN2Q2xPMFkifQ.TQQLqc4ZzoKjQfAghAzC_4aaU3KCS8YqzxAJtzT124guzkv9XSHtPN8d3z181_v-ca2ATXjTRoRciozitE6wBA' diff --git a/packages/sd-jwt-vc/src/index.ts b/packages/core/src/modules/sd-jwt-vc/index.ts similarity index 82% rename from packages/sd-jwt-vc/src/index.ts rename to packages/core/src/modules/sd-jwt-vc/index.ts index 18d611ca76..0d1891ea62 100644 --- a/packages/sd-jwt-vc/src/index.ts +++ b/packages/core/src/modules/sd-jwt-vc/index.ts @@ -2,4 +2,5 @@ export * from './SdJwtVcApi' export * from './SdJwtVcModule' export * from './SdJwtVcService' export * from './SdJwtVcError' +export * from './SdJwtVcOptions' export * from './repository' diff --git a/packages/core/src/modules/sd-jwt-vc/repository/SdJwtVcRecord.ts b/packages/core/src/modules/sd-jwt-vc/repository/SdJwtVcRecord.ts new file mode 100644 index 0000000000..e2a77a73bb --- /dev/null +++ b/packages/core/src/modules/sd-jwt-vc/repository/SdJwtVcRecord.ts @@ -0,0 +1,66 @@ +import type { JwaSignatureAlgorithm } from '../../../crypto' +import type { TagsBase } from '../../../storage/BaseRecord' +import type { Constructable } from '../../../utils/mixins' + +import { SdJwtVc } from '@sd-jwt/core' + +import { BaseRecord } from '../../../storage/BaseRecord' +import { JsonTransformer } from '../../../utils' +import { uuid } from '../../../utils/uuid' + +export type DefaultSdJwtVcRecordTags = { + vct: string + + /** + * The sdAlg is the alg used for creating digests for selective disclosures + */ + sdAlg: string + + /** + * The alg is the alg used to sign the SD-JWT + */ + alg: JwaSignatureAlgorithm +} + +export type SdJwtVcRecordStorageProps = { + id?: string + createdAt?: Date + tags?: TagsBase + compactSdJwtVc: string +} + +export class SdJwtVcRecord extends BaseRecord { + public static readonly type = 'SdJwtVcRecord' + public readonly type = SdJwtVcRecord.type + + // We store the sdJwtVc in compact format. + public compactSdJwtVc!: string + + // TODO: should we also store the pretty claims so it's not needed to + // re-calculate the hashes each time? I think for now it's fine to re-calculate + public constructor(props: SdJwtVcRecordStorageProps) { + super() + + if (props) { + this.id = props.id ?? uuid() + this.createdAt = props.createdAt ?? new Date() + this.compactSdJwtVc = props.compactSdJwtVc + this._tags = props.tags ?? {} + } + } + + public getTags() { + const sdJwtVc = SdJwtVc.fromCompact(this.compactSdJwtVc) + + return { + ...this._tags, + vct: sdJwtVc.getClaimInPayload('vct'), + sdAlg: (sdJwtVc.payload._sd_alg as string | undefined) ?? 'sha-256', + alg: sdJwtVc.getClaimInHeader('alg'), + } + } + + public clone(): this { + return JsonTransformer.fromJSON(JsonTransformer.toJSON(this), this.constructor as Constructable) + } +} diff --git a/packages/sd-jwt-vc/src/repository/SdJwtVcRepository.ts b/packages/core/src/modules/sd-jwt-vc/repository/SdJwtVcRepository.ts similarity index 54% rename from packages/sd-jwt-vc/src/repository/SdJwtVcRepository.ts rename to packages/core/src/modules/sd-jwt-vc/repository/SdJwtVcRepository.ts index 1054cb4767..0aa8bbce3d 100644 --- a/packages/sd-jwt-vc/src/repository/SdJwtVcRepository.ts +++ b/packages/core/src/modules/sd-jwt-vc/repository/SdJwtVcRepository.ts @@ -1,4 +1,8 @@ -import { EventEmitter, InjectionSymbols, inject, injectable, Repository, StorageService } from '@credo-ts/core' +import { EventEmitter } from '../../../agent/EventEmitter' +import { InjectionSymbols } from '../../../constants' +import { inject, injectable } from '../../../plugins' +import { Repository } from '../../../storage/Repository' +import { StorageService } from '../../../storage/StorageService' import { SdJwtVcRecord } from './SdJwtVcRecord' diff --git a/packages/core/src/modules/sd-jwt-vc/repository/__tests__/SdJwtVcRecord.test.ts b/packages/core/src/modules/sd-jwt-vc/repository/__tests__/SdJwtVcRecord.test.ts new file mode 100644 index 0000000000..294ad39c08 --- /dev/null +++ b/packages/core/src/modules/sd-jwt-vc/repository/__tests__/SdJwtVcRecord.test.ts @@ -0,0 +1,68 @@ +import { SdJwtVcRecord } from '../SdJwtVcRecord' + +import { JsonTransformer } from '@credo-ts/core' + +describe('SdJwtVcRecord', () => { + test('sets the values passed in the constructor on the record', () => { + const compactSdJwtVc = + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6Ino2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyJ9.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJmYW1pbHlfbmFtZSI6IkRvZSIsInBob25lX251bWJlciI6IisxLTIwMi01NTUtMDEwMSIsImFkZHJlc3MiOnsic3RyZWV0X2FkZHJlc3MiOiIxMjMgTWFpbiBTdCIsImxvY2FsaXR5IjoiQW55dG93biIsIl9zZCI6WyJOSm5tY3QwQnFCTUUxSmZCbEM2alJRVlJ1ZXZwRU9OaVl3N0E3TUh1SnlRIiwib201Wnp0WkhCLUdkMDBMRzIxQ1ZfeE00RmFFTlNvaWFPWG5UQUpOY3pCNCJdfSwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyIxQ3VyMmsyQTJvSUI1Q3NoU0lmX0FfS2ctbDI2dV9xS3VXUTc5UDBWZGFzIiwiUjF6VFV2T1lIZ2NlcGowakh5cEdIejlFSHR0VktmdDB5c3diYzlFVFBiVSIsImVEcVFwZFRYSlhiV2hmLUVzSTd6dzVYNk92WW1GTi1VWlFRTWVzWHdLUHciLCJwZERrMl9YQUtIbzdnT0Fmd0YxYjdPZENVVlRpdDJrSkhheFNFQ1E5eGZjIiwicHNhdUtVTldFaTA5bnUzQ2w4OXhLWGdtcFdFTlpsNXV5MU4xbnluX2pNayIsInNOX2dlMHBIWEY2cW1zWW5YMUE5U2R3SjhjaDhhRU5reGJPRHNUNzRZd0kiXX0.Yz5U__nC0Nccza-NNfqhp-GueKXqeFNjm_NNtC1AJ2KdmERhCHdO6KNjM7bOiruHlo4oAlj-xObuB9LRiKXeCw~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8xOCIsdHJ1ZV0~WyJzYWx0IiwiYmlydGhkYXRlIiwiMTk0MC0wMS0wMSJd~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwicmVnaW9uIiwiQW55c3RhdGUiXQ~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~' + const createdAt = new Date() + const sdJwtVcRecord = new SdJwtVcRecord({ + id: 'sdjwt-id', + createdAt, + tags: { + some: 'tag', + }, + compactSdJwtVc, + }) + + expect(sdJwtVcRecord.type).toBe('SdJwtVcRecord') + expect(sdJwtVcRecord.id).toBe('sdjwt-id') + expect(sdJwtVcRecord.createdAt).toBe(createdAt) + expect(sdJwtVcRecord.getTags()).toEqual({ + some: 'tag', + alg: 'EdDSA', + sdAlg: 'sha-256', + vct: 'IdentityCredential', + }) + expect(sdJwtVcRecord.compactSdJwtVc).toEqual(compactSdJwtVc) + }) + + test('serializes and deserializes', () => { + const compactSdJwtVc = + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6Ino2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyJ9.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJmYW1pbHlfbmFtZSI6IkRvZSIsInBob25lX251bWJlciI6IisxLTIwMi01NTUtMDEwMSIsImFkZHJlc3MiOnsic3RyZWV0X2FkZHJlc3MiOiIxMjMgTWFpbiBTdCIsImxvY2FsaXR5IjoiQW55dG93biIsIl9zZCI6WyJOSm5tY3QwQnFCTUUxSmZCbEM2alJRVlJ1ZXZwRU9OaVl3N0E3TUh1SnlRIiwib201Wnp0WkhCLUdkMDBMRzIxQ1ZfeE00RmFFTlNvaWFPWG5UQUpOY3pCNCJdfSwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyIxQ3VyMmsyQTJvSUI1Q3NoU0lmX0FfS2ctbDI2dV9xS3VXUTc5UDBWZGFzIiwiUjF6VFV2T1lIZ2NlcGowakh5cEdIejlFSHR0VktmdDB5c3diYzlFVFBiVSIsImVEcVFwZFRYSlhiV2hmLUVzSTd6dzVYNk92WW1GTi1VWlFRTWVzWHdLUHciLCJwZERrMl9YQUtIbzdnT0Fmd0YxYjdPZENVVlRpdDJrSkhheFNFQ1E5eGZjIiwicHNhdUtVTldFaTA5bnUzQ2w4OXhLWGdtcFdFTlpsNXV5MU4xbnluX2pNayIsInNOX2dlMHBIWEY2cW1zWW5YMUE5U2R3SjhjaDhhRU5reGJPRHNUNzRZd0kiXX0.Yz5U__nC0Nccza-NNfqhp-GueKXqeFNjm_NNtC1AJ2KdmERhCHdO6KNjM7bOiruHlo4oAlj-xObuB9LRiKXeCw~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8xOCIsdHJ1ZV0~WyJzYWx0IiwiYmlydGhkYXRlIiwiMTk0MC0wMS0wMSJd~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwicmVnaW9uIiwiQW55c3RhdGUiXQ~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~' + const createdAt = new Date('2022-02-02') + const sdJwtVcRecord = new SdJwtVcRecord({ + id: 'sdjwt-id', + createdAt, + tags: { + some: 'tag', + }, + compactSdJwtVc, + }) + + const json = sdJwtVcRecord.toJSON() + expect(json).toMatchObject({ + id: 'sdjwt-id', + createdAt: '2022-02-02T00:00:00.000Z', + metadata: {}, + _tags: { + some: 'tag', + }, + compactSdJwtVc, + }) + + const instance = JsonTransformer.deserialize(JSON.stringify(json), SdJwtVcRecord) + + expect(instance.type).toBe('SdJwtVcRecord') + expect(instance.id).toBe('sdjwt-id') + expect(instance.createdAt.getTime()).toBe(createdAt.getTime()) + expect(instance.getTags()).toEqual({ + some: 'tag', + alg: 'EdDSA', + sdAlg: 'sha-256', + vct: 'IdentityCredential', + }) + expect(instance.compactSdJwtVc).toBe(compactSdJwtVc) + }) +}) diff --git a/packages/sd-jwt-vc/src/repository/index.ts b/packages/core/src/modules/sd-jwt-vc/repository/index.ts similarity index 100% rename from packages/sd-jwt-vc/src/repository/index.ts rename to packages/core/src/modules/sd-jwt-vc/repository/index.ts diff --git a/packages/core/src/modules/vc/W3cCredentialService.ts b/packages/core/src/modules/vc/W3cCredentialService.ts index 511d2cc348..5743629cb8 100644 --- a/packages/core/src/modules/vc/W3cCredentialService.ts +++ b/packages/core/src/modules/vc/W3cCredentialService.ts @@ -54,14 +54,16 @@ export class W3cCredentialService { * @param credential the credential to be signed * @returns the signed credential */ - public async signCredential( + public async signCredential( agentContext: AgentContext, - options: W3cSignCredentialOptions - ): Promise> { + options: W3cSignCredentialOptions + ): Promise> { if (options.format === ClaimFormat.JwtVc) { - return this.w3cJwtCredentialService.signCredential(agentContext, options) + const signed = await this.w3cJwtCredentialService.signCredential(agentContext, options) + return signed as W3cVerifiableCredential } else if (options.format === ClaimFormat.LdpVc) { - return this.w3cJsonLdCredentialService.signCredential(agentContext, options) + const signed = await this.w3cJsonLdCredentialService.signCredential(agentContext, options) + return signed as W3cVerifiableCredential } else { throw new CredoError(`Unsupported format in options. Format must be either 'jwt_vc' or 'ldp_vc'`) } @@ -110,14 +112,16 @@ export class W3cCredentialService { * @param presentation the presentation to be signed * @returns the signed presentation */ - public async signPresentation( + public async signPresentation( agentContext: AgentContext, - options: W3cSignPresentationOptions - ): Promise> { + options: W3cSignPresentationOptions + ): Promise> { if (options.format === ClaimFormat.JwtVp) { - return this.w3cJwtCredentialService.signPresentation(agentContext, options) + const signed = await this.w3cJwtCredentialService.signPresentation(agentContext, options) + return signed as W3cVerifiablePresentation } else if (options.format === ClaimFormat.LdpVp) { - return this.w3cJsonLdCredentialService.signPresentation(agentContext, options) + const signed = await this.w3cJsonLdCredentialService.signPresentation(agentContext, options) + return signed as W3cVerifiablePresentation } else { throw new CredoError(`Unsupported format in options. Format must be either 'jwt_vp' or 'ldp_vp'`) } diff --git a/packages/core/src/modules/vc/W3cCredentialServiceOptions.ts b/packages/core/src/modules/vc/W3cCredentialServiceOptions.ts index 6f15025e1c..3a9b892e89 100644 --- a/packages/core/src/modules/vc/W3cCredentialServiceOptions.ts +++ b/packages/core/src/modules/vc/W3cCredentialServiceOptions.ts @@ -8,9 +8,24 @@ import type { W3cPresentation } from './models/presentation/W3cPresentation' import type { JwaSignatureAlgorithm } from '../../crypto/jose/jwa' import type { SingleOrArray } from '../../utils/type' -export type W3cSignCredentialOptions = W3cJwtSignCredentialOptions | W3cJsonLdSignCredentialOptions -export type W3cVerifyCredentialOptions = W3cJwtVerifyCredentialOptions | W3cJsonLdVerifyCredentialOptions -export type W3cSignPresentationOptions = W3cJwtSignPresentationOptions | W3cJsonLdSignPresentationOptions +export type W3cSignCredentialOptions = + Format extends ClaimFormat.JwtVc + ? W3cJwtSignCredentialOptions + : Format extends ClaimFormat.LdpVc + ? W3cJsonLdSignCredentialOptions + : W3cJwtSignCredentialOptions | W3cJsonLdSignCredentialOptions +export type W3cVerifyCredentialOptions = + Format extends ClaimFormat.JwtVc + ? W3cJwtVerifyCredentialOptions + : Format extends ClaimFormat.LdpVc + ? W3cJsonLdVerifyCredentialOptions + : W3cJwtVerifyCredentialOptions | W3cJsonLdVerifyCredentialOptions +export type W3cSignPresentationOptions = + Format extends ClaimFormat.JwtVp + ? W3cJwtSignPresentationOptions + : Format extends ClaimFormat.LdpVp + ? W3cJsonLdSignPresentationOptions + : W3cJwtSignPresentationOptions | W3cJsonLdSignPresentationOptions export type W3cVerifyPresentationOptions = W3cJwtVerifyPresentationOptions | W3cJsonLdVerifyPresentationOptions interface W3cSignCredentialOptionsBase { diff --git a/packages/core/src/modules/vc/W3cCredentialsApi.ts b/packages/core/src/modules/vc/W3cCredentialsApi.ts index bb86cbb8f5..a378974992 100644 --- a/packages/core/src/modules/vc/W3cCredentialsApi.ts +++ b/packages/core/src/modules/vc/W3cCredentialsApi.ts @@ -1,5 +1,12 @@ -import type { StoreCredentialOptions } from './W3cCredentialServiceOptions' -import type { W3cVerifiableCredential } from './models' +import type { + StoreCredentialOptions, + W3cCreatePresentationOptions, + W3cSignCredentialOptions, + W3cSignPresentationOptions, + W3cVerifyCredentialOptions, + W3cVerifyPresentationOptions, +} from './W3cCredentialServiceOptions' +import type { W3cVerifiableCredential, ClaimFormat } from './models' import type { W3cCredentialRecord } from './repository' import type { Query } from '../../storage/StorageService' @@ -40,4 +47,28 @@ export class W3cCredentialsApi { public async findCredentialRecordsByQuery(query: Query): Promise { return this.w3cCredentialService.findCredentialsByQuery(this.agentContext, query) } + + public async signCredential( + options: W3cSignCredentialOptions + ) { + return this.w3cCredentialService.signCredential(this.agentContext, options) + } + + public async verifyCredential(options: W3cVerifyCredentialOptions) { + return this.w3cCredentialService.verifyCredential(this.agentContext, options) + } + + public async createPresentation(options: W3cCreatePresentationOptions) { + return this.w3cCredentialService.createPresentation(options) + } + + public async signPresentation( + options: W3cSignPresentationOptions + ) { + return this.w3cCredentialService.signPresentation(this.agentContext, options) + } + + public async verifyPresentation(options: W3cVerifyPresentationOptions) { + return this.w3cCredentialService.verifyPresentation(this.agentContext, options) + } } diff --git a/packages/core/src/modules/vc/W3cCredentialsModule.ts b/packages/core/src/modules/vc/W3cCredentialsModule.ts index 5fbad97ec7..3b1fd7da8b 100644 --- a/packages/core/src/modules/vc/W3cCredentialsModule.ts +++ b/packages/core/src/modules/vc/W3cCredentialsModule.ts @@ -28,7 +28,6 @@ export class W3cCredentialsModule implements Module { } public register(dependencyManager: DependencyManager) { - dependencyManager.registerContextScoped(W3cCredentialsApi) dependencyManager.registerSingleton(W3cCredentialService) dependencyManager.registerSingleton(W3cJwtCredentialService) dependencyManager.registerSingleton(W3cJsonLdCredentialService) diff --git a/packages/core/src/modules/vc/__tests__/W3CredentialsModule.test.ts b/packages/core/src/modules/vc/__tests__/W3CredentialsModule.test.ts index 94d1acc70d..263d9f03ee 100644 --- a/packages/core/src/modules/vc/__tests__/W3CredentialsModule.test.ts +++ b/packages/core/src/modules/vc/__tests__/W3CredentialsModule.test.ts @@ -1,7 +1,6 @@ import { KeyType } from '../../../crypto' import { DependencyManager } from '../../../plugins/DependencyManager' import { W3cCredentialService } from '../W3cCredentialService' -import { W3cCredentialsApi } from '../W3cCredentialsApi' import { W3cCredentialsModule } from '../W3cCredentialsModule' import { W3cCredentialsModuleConfig } from '../W3cCredentialsModuleConfig' import { SignatureSuiteRegistry, SignatureSuiteToken } from '../data-integrity/SignatureSuiteRegistry' @@ -21,9 +20,6 @@ describe('W3cCredentialsModule', () => { module.register(dependencyManager) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(W3cCredentialsApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(5) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(W3cCredentialService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(W3cJsonLdCredentialService) diff --git a/packages/core/src/modules/vc/data-integrity/SignatureSuiteRegistry.ts b/packages/core/src/modules/vc/data-integrity/SignatureSuiteRegistry.ts index 61675ced7a..b59540d718 100644 --- a/packages/core/src/modules/vc/data-integrity/SignatureSuiteRegistry.ts +++ b/packages/core/src/modules/vc/data-integrity/SignatureSuiteRegistry.ts @@ -27,12 +27,15 @@ export class SignatureSuiteRegistry { return this.suiteMapping.map((x) => x.proofType) } + /** + * @deprecated recommended to always search by key type instead as that will have broader support + */ public getByVerificationMethodType(verificationMethodType: string) { return this.suiteMapping.find((x) => x.verificationMethodTypes.includes(verificationMethodType)) } - public getByKeyType(keyType: KeyType) { - return this.suiteMapping.find((x) => x.keyTypes.includes(keyType)) + public getAllByKeyType(keyType: KeyType) { + return this.suiteMapping.filter((x) => x.keyTypes.includes(keyType)) } public getByProofType(proofType: string) { diff --git a/packages/core/src/modules/vc/data-integrity/W3cJsonLdCredentialService.ts b/packages/core/src/modules/vc/data-integrity/W3cJsonLdCredentialService.ts index 98151c0432..74d174e793 100644 --- a/packages/core/src/modules/vc/data-integrity/W3cJsonLdCredentialService.ts +++ b/packages/core/src/modules/vc/data-integrity/W3cJsonLdCredentialService.ts @@ -324,16 +324,6 @@ export class W3cJsonLdCredentialService { return this.signatureSuiteRegistry.getByProofType(proofType).keyTypes } - public getProofTypeByVerificationMethodType(verificationMethodType: string): string { - const suite = this.signatureSuiteRegistry.getByVerificationMethodType(verificationMethodType) - - if (!suite) { - throw new CredoError(`No suite found for verification method type ${verificationMethodType}}`) - } - - return suite.proofType - } - public async getExpandedTypesForCredential(agentContext: AgentContext, credential: W3cJsonLdVerifiableCredential) { // Get the expanded types const expandedTypes: SingleOrArray = ( diff --git a/packages/core/src/modules/vc/data-integrity/models/W3cJsonLdVerifiableCredential.ts b/packages/core/src/modules/vc/data-integrity/models/W3cJsonLdVerifiableCredential.ts index 2fad970565..c0a281a7ba 100644 --- a/packages/core/src/modules/vc/data-integrity/models/W3cJsonLdVerifiableCredential.ts +++ b/packages/core/src/modules/vc/data-integrity/models/W3cJsonLdVerifiableCredential.ts @@ -1,5 +1,6 @@ import type { LinkedDataProofOptions } from './LinkedDataProof' import type { W3cCredentialOptions } from '../../models/credential/W3cCredential' +import type { W3cJsonCredential } from '../../models/credential/W3cJsonCredential' import { ValidateNested } from 'class-validator' @@ -41,6 +42,10 @@ export class W3cJsonLdVerifiableCredential extends W3cCredential { return JsonTransformer.toJSON(this) } + public static fromJson(json: Record) { + return JsonTransformer.fromJSON(json, W3cJsonLdVerifiableCredential) + } + /** * The {@link ClaimFormat} of the credential. For JSON-LD credentials this is always `ldp_vc`. */ @@ -55,4 +60,8 @@ export class W3cJsonLdVerifiableCredential extends W3cCredential { public get encoded() { return this.toJson() } + + public get jsonCredential(): W3cJsonCredential { + return this.toJson() as W3cJsonCredential + } } diff --git a/packages/core/src/modules/vc/jwt-vc/W3cJwtCredentialService.ts b/packages/core/src/modules/vc/jwt-vc/W3cJwtCredentialService.ts index 6047cbf0f4..3f4e442b59 100644 --- a/packages/core/src/modules/vc/jwt-vc/W3cJwtCredentialService.ts +++ b/packages/core/src/modules/vc/jwt-vc/W3cJwtCredentialService.ts @@ -29,23 +29,11 @@ import { getJwtPayloadFromPresentation } from './presentationTransformer' @injectable() export class W3cJwtCredentialService { private jwsService: JwsService - private hasWarned = false public constructor(jwsService: JwsService) { this.jwsService = jwsService } - private warnExperimentalOnce(agentContext: AgentContext) { - if (this.hasWarned) return - - // Warn about experimental module - agentContext.config.logger.warn( - "The 'W3cJwtCredentialService' is experimental and could have unexpected breaking changes. When using this service, make sure to use strict versions for all @credo-ts packages." - ) - - this.hasWarned = true - } - /** * Signs a credential */ @@ -53,8 +41,6 @@ export class W3cJwtCredentialService { agentContext: AgentContext, options: W3cJwtSignCredentialOptions ): Promise { - this.warnExperimentalOnce(agentContext) - // Validate the instance MessageValidator.validateSync(options.credential) @@ -98,8 +84,6 @@ export class W3cJwtCredentialService { agentContext: AgentContext, options: W3cJwtVerifyCredentialOptions ): Promise { - this.warnExperimentalOnce(agentContext) - // NOTE: this is mostly from the JSON-LD service that adds this option. Once we support // the same granular validation results, we can remove this and the user could just check // which of the validations failed. Supporting for consistency with the JSON-LD service for now. @@ -232,8 +216,6 @@ export class W3cJwtCredentialService { agentContext: AgentContext, options: W3cJwtSignPresentationOptions ): Promise { - this.warnExperimentalOnce(agentContext) - // Validate the instance MessageValidator.validateSync(options.presentation) @@ -276,8 +258,6 @@ export class W3cJwtCredentialService { agentContext: AgentContext, options: W3cJwtVerifyPresentationOptions ): Promise { - this.warnExperimentalOnce(agentContext) - const validationResults: W3cVerifyPresentationResult = { isValid: false, validations: {}, diff --git a/packages/core/src/modules/vc/jwt-vc/W3cJwtVerifiableCredential.ts b/packages/core/src/modules/vc/jwt-vc/W3cJwtVerifiableCredential.ts index c9d3852a35..869f00121e 100644 --- a/packages/core/src/modules/vc/jwt-vc/W3cJwtVerifiableCredential.ts +++ b/packages/core/src/modules/vc/jwt-vc/W3cJwtVerifiableCredential.ts @@ -1,6 +1,8 @@ import type { W3cCredential } from '../models/credential/W3cCredential' +import type { W3cJsonCredential } from '../models/credential/W3cJsonCredential' import { Jwt } from '../../../crypto/jose/jwt/Jwt' +import { JsonTransformer } from '../../../utils' import { ClaimFormat } from '../models/ClaimFormat' import { getCredentialFromJwtPayload } from './credentialTransformer' @@ -117,4 +119,8 @@ export class W3cJwtVerifiableCredential { public get encoded() { return this.serializedJwt } + + public get jsonCredential(): W3cJsonCredential { + return JsonTransformer.toJSON(this.credential) as W3cJsonCredential + } } diff --git a/packages/core/src/modules/vc/models/ClaimFormat.ts b/packages/core/src/modules/vc/models/ClaimFormat.ts index f6c8cc909d..50ff6c58c9 100644 --- a/packages/core/src/modules/vc/models/ClaimFormat.ts +++ b/packages/core/src/modules/vc/models/ClaimFormat.ts @@ -9,4 +9,5 @@ export enum ClaimFormat { Ldp = 'ldp', LdpVc = 'ldp_vc', LdpVp = 'ldp_vp', + SdJwtVc = 'vc+sd-jwt', } diff --git a/packages/core/src/modules/vc/models/credential/W3cVerifiableCredential.ts b/packages/core/src/modules/vc/models/credential/W3cVerifiableCredential.ts index 93dc4e7e3c..8517276653 100644 --- a/packages/core/src/modules/vc/models/credential/W3cVerifiableCredential.ts +++ b/packages/core/src/modules/vc/models/credential/W3cVerifiableCredential.ts @@ -39,7 +39,7 @@ export function W3cVerifiableCredentialTransformer() { export type W3cVerifiableCredential = Format extends ClaimFormat.JwtVc - ? W3cJsonLdVerifiableCredential - : Format extends ClaimFormat.LdpVc ? W3cJwtVerifiableCredential + : Format extends ClaimFormat.LdpVc + ? W3cJsonLdVerifiableCredential : W3cJsonLdVerifiableCredential | W3cJwtVerifiableCredential diff --git a/packages/core/src/modules/vc/models/presentation/W3cVerifiablePresentation.ts b/packages/core/src/modules/vc/models/presentation/W3cVerifiablePresentation.ts index 65e7b68a4b..8ce1304a19 100644 --- a/packages/core/src/modules/vc/models/presentation/W3cVerifiablePresentation.ts +++ b/packages/core/src/modules/vc/models/presentation/W3cVerifiablePresentation.ts @@ -4,7 +4,7 @@ import type { ClaimFormat } from '../ClaimFormat' export type W3cVerifiablePresentation = Format extends ClaimFormat.JwtVp - ? W3cJsonLdVerifiablePresentation - : Format extends ClaimFormat.LdpVp ? W3cJwtVerifiablePresentation + : Format extends ClaimFormat.LdpVp + ? W3cJsonLdVerifiablePresentation : W3cJsonLdVerifiablePresentation | W3cJwtVerifiablePresentation diff --git a/packages/core/src/modules/vc/repository/W3cCredentialRecord.ts b/packages/core/src/modules/vc/repository/W3cCredentialRecord.ts index a5aa1fe070..01171ab68d 100644 --- a/packages/core/src/modules/vc/repository/W3cCredentialRecord.ts +++ b/packages/core/src/modules/vc/repository/W3cCredentialRecord.ts @@ -31,6 +31,7 @@ export type DefaultW3cCredentialTags = { claimFormat: W3cVerifiableCredential['claimFormat'] proofTypes?: Array + types: Array algs?: Array } @@ -64,6 +65,7 @@ export class W3cCredentialRecord extends BaseRecord { proofTypes: credential.proofTypes, givenId: credential.id, expandedTypes: ['https://expanded.tag#1'], + types: ['VerifiableCredential', 'UniversityDegreeCredential'], }) }) }) diff --git a/packages/core/src/plugins/DependencyManager.ts b/packages/core/src/plugins/DependencyManager.ts index fd3e5f6669..166bc1380c 100644 --- a/packages/core/src/plugins/DependencyManager.ts +++ b/packages/core/src/plugins/DependencyManager.ts @@ -34,6 +34,9 @@ export class DependencyManager { } this.registeredModules[moduleKey] = module + if (module.api) { + this.registerContextScoped(module.api) + } module.register(this, featureRegistry) } } diff --git a/packages/core/src/plugins/index.ts b/packages/core/src/plugins/index.ts index faee88c0f1..bf419032f6 100644 --- a/packages/core/src/plugins/index.ts +++ b/packages/core/src/plugins/index.ts @@ -1,3 +1,4 @@ export * from './DependencyManager' export * from './Module' +export * from './utils' export { inject, injectable, Disposable, injectAll } from 'tsyringe' diff --git a/packages/core/src/plugins/utils.ts b/packages/core/src/plugins/utils.ts new file mode 100644 index 0000000000..34ad85a7b9 --- /dev/null +++ b/packages/core/src/plugins/utils.ts @@ -0,0 +1,34 @@ +import type { ApiModule, Module } from './Module' +import type { AgentContext } from '../agent' + +export function getRegisteredModuleByInstance( + agentContext: AgentContext, + moduleType: { new (...args: unknown[]): M } +): M | undefined { + const module = Object.values(agentContext.dependencyManager.registeredModules).find( + (module): module is M => module instanceof moduleType + ) + + return module +} + +export function getRegisteredModuleByName( + agentContext: AgentContext, + constructorName: string +): M | undefined { + const module = Object.values(agentContext.dependencyManager.registeredModules).find( + (module): module is M => module.constructor.name === constructorName + ) + + return module +} + +export function getApiForModuleByName( + agentContext: AgentContext, + constructorName: string +): InstanceType | undefined { + const module = getRegisteredModuleByName(agentContext, constructorName) + if (!module || !module.api) return undefined + + return agentContext.dependencyManager.resolve(module.api) as InstanceType +} diff --git a/packages/core/src/storage/migration/__tests__/0.2.test.ts b/packages/core/src/storage/migration/__tests__/0.2.test.ts index 4ad72fca11..52c45da3a2 100644 --- a/packages/core/src/storage/migration/__tests__/0.2.test.ts +++ b/packages/core/src/storage/migration/__tests__/0.2.test.ts @@ -63,7 +63,7 @@ describe('UpdateAssistant | v0.2 - v0.3.1', () => { }, } - expect(await updateAssistant.isUpToDate()).toBe(false) + expect(await updateAssistant.isUpToDate('0.3.1')).toBe(false) expect(await updateAssistant.getNeededUpdates('0.3.1')).toEqual([ { fromVersion: '0.2', @@ -77,10 +77,10 @@ describe('UpdateAssistant | v0.2 - v0.3.1', () => { }, ]) - await updateAssistant.update() + await updateAssistant.update('0.3.1') - expect(await updateAssistant.isUpToDate()).toBe(true) - expect(await updateAssistant.getNeededUpdates()).toEqual([]) + expect(await updateAssistant.isUpToDate('0.3.1')).toBe(true) + expect(await updateAssistant.getNeededUpdates('0.3.1')).toEqual([]) expect(storageService.contextCorrelationIdToRecords[agent.context.contextCorrelationId].records).toMatchSnapshot() await agent.shutdown() diff --git a/packages/core/src/storage/migration/__tests__/0.3.test.ts b/packages/core/src/storage/migration/__tests__/0.3.test.ts index 7cef8aafd7..c4dc46c831 100644 --- a/packages/core/src/storage/migration/__tests__/0.3.test.ts +++ b/packages/core/src/storage/migration/__tests__/0.3.test.ts @@ -75,7 +75,7 @@ describe('UpdateAssistant | v0.3.1 - v0.4', () => { await updateAssistant.update() expect(await updateAssistant.isUpToDate()).toBe(true) - expect(await updateAssistant.getNeededUpdates()).toEqual([]) + expect(await updateAssistant.getNeededUpdates('0.4')).toEqual([]) expect(storageService.contextCorrelationIdToRecords[agent.context.contextCorrelationId].records).toMatchSnapshot() diff --git a/packages/core/src/storage/migration/__tests__/__snapshots__/0.2.test.ts.snap b/packages/core/src/storage/migration/__tests__/__snapshots__/0.2.test.ts.snap index cf2fb076af..16848424be 100644 --- a/packages/core/src/storage/migration/__tests__/__snapshots__/0.2.test.ts.snap +++ b/packages/core/src/storage/migration/__tests__/__snapshots__/0.2.test.ts.snap @@ -121,7 +121,7 @@ exports[`UpdateAssistant | v0.2 - v0.3.1 should correctly update proof records a "createdAt": "2022-09-08T19:35:53.872Z", "id": "STORAGE_VERSION_RECORD_ID", "metadata": {}, - "storageVersion": "0.4", + "storageVersion": "0.3.1", "updatedAt": "2023-01-21T22:50:20.522Z", }, }, @@ -757,7 +757,7 @@ exports[`UpdateAssistant | v0.2 - v0.3.1 should correctly update the did records "createdAt": "2022-09-08T19:35:53.872Z", "id": "STORAGE_VERSION_RECORD_ID", "metadata": {}, - "storageVersion": "0.4", + "storageVersion": "0.5", "updatedAt": "2023-01-21T22:50:20.522Z", }, }, @@ -885,7 +885,7 @@ exports[`UpdateAssistant | v0.2 - v0.3.1 should correctly update the proofs reco "createdAt": "2022-09-08T19:35:53.872Z", "id": "STORAGE_VERSION_RECORD_ID", "metadata": {}, - "storageVersion": "0.4", + "storageVersion": "0.5", "updatedAt": "2023-01-21T22:50:20.522Z", }, }, diff --git a/packages/core/src/storage/migration/__tests__/__snapshots__/0.3.test.ts.snap b/packages/core/src/storage/migration/__tests__/__snapshots__/0.3.test.ts.snap index 92ecc32e40..3fdfd7832c 100644 --- a/packages/core/src/storage/migration/__tests__/__snapshots__/0.3.test.ts.snap +++ b/packages/core/src/storage/migration/__tests__/__snapshots__/0.3.test.ts.snap @@ -52,7 +52,7 @@ exports[`UpdateAssistant | v0.3.1 - v0.4 should correctly update the did records "createdAt": "2023-03-18T18:35:02.888Z", "id": "STORAGE_VERSION_RECORD_ID", "metadata": {}, - "storageVersion": "0.4", + "storageVersion": "0.5", "updatedAt": "2023-03-18T22:50:20.522Z", }, }, diff --git a/packages/core/src/storage/migration/updates.ts b/packages/core/src/storage/migration/updates.ts index 4e1d09a898..ad06ad3178 100644 --- a/packages/core/src/storage/migration/updates.ts +++ b/packages/core/src/storage/migration/updates.ts @@ -6,6 +6,7 @@ import { updateV0_1ToV0_2 } from './updates/0.1-0.2' import { updateV0_2ToV0_3 } from './updates/0.2-0.3' import { updateV0_3ToV0_3_1 } from './updates/0.3-0.3.1' import { updateV0_3_1ToV0_4 } from './updates/0.3.1-0.4' +import { updateV0_4ToV0_5 } from './updates/0.4-0.5' export const INITIAL_STORAGE_VERSION = '0.1' @@ -46,6 +47,11 @@ export const supportedUpdates = [ toVersion: '0.4', doUpdate: updateV0_3_1ToV0_4, }, + { + fromVersion: '0.4', + toVersion: '0.5', + doUpdate: updateV0_4ToV0_5, + }, ] as const // Current version is last toVersion from the supported updates diff --git a/packages/core/src/storage/migration/updates/0.4-0.5/__tests__/w3cCredentialRecord.test.ts b/packages/core/src/storage/migration/updates/0.4-0.5/__tests__/w3cCredentialRecord.test.ts new file mode 100644 index 0000000000..d366426d82 --- /dev/null +++ b/packages/core/src/storage/migration/updates/0.4-0.5/__tests__/w3cCredentialRecord.test.ts @@ -0,0 +1,63 @@ +import { getAgentConfig, getAgentContext, mockFunction } from '../../../../../../tests/helpers' +import { Agent } from '../../../../../agent/Agent' +import { W3cCredentialRecord, W3cJsonLdVerifiableCredential } from '../../../../../modules/vc' +import { Ed25519Signature2018Fixtures } from '../../../../../modules/vc/data-integrity/__tests__/fixtures' +import { JsonTransformer } from '../../../../../utils' +import * as testModule from '../w3cCredentialRecord' + +const agentConfig = getAgentConfig('Migration W3cCredentialRecord 0.4-0.5') +const agentContext = getAgentContext() + +const repository = { + getAll: jest.fn(), + update: jest.fn(), +} + +jest.mock('../../../../../agent/Agent', () => { + return { + Agent: jest.fn(() => ({ + config: agentConfig, + context: agentContext, + dependencyManager: { + resolve: jest.fn(() => repository), + }, + })), + } +}) + +// Mock typed object +const AgentMock = Agent as jest.Mock + +describe('0.4-0.5 | W3cCredentialRecord', () => { + let agent: Agent + + beforeEach(() => { + agent = new AgentMock() + }) + + describe('migrateW3cCredentialRecordToV0_5()', () => { + it('should fetch all w3c credential records and re-save them', async () => { + const records = [ + new W3cCredentialRecord({ + tags: {}, + id: '3b3cf6ca-fa09-4498-b891-e280fbbb7fa7', + credential: JsonTransformer.fromJSON( + Ed25519Signature2018Fixtures.TEST_LD_DOCUMENT_SIGNED, + W3cJsonLdVerifiableCredential + ), + }), + ] + + mockFunction(repository.getAll).mockResolvedValue(records) + + await testModule.migrateW3cCredentialRecordToV0_5(agent) + + expect(repository.getAll).toHaveBeenCalledTimes(1) + expect(repository.getAll).toHaveBeenCalledWith(agent.context) + expect(repository.update).toHaveBeenCalledTimes(1) + + const [, record] = mockFunction(repository.update).mock.calls[0] + expect(record.getTags().types).toEqual(['VerifiableCredential', 'UniversityDegreeCredential']) + }) + }) +}) diff --git a/packages/core/src/storage/migration/updates/0.4-0.5/index.ts b/packages/core/src/storage/migration/updates/0.4-0.5/index.ts new file mode 100644 index 0000000000..8b1a9428b9 --- /dev/null +++ b/packages/core/src/storage/migration/updates/0.4-0.5/index.ts @@ -0,0 +1,7 @@ +import type { BaseAgent } from '../../../../agent/BaseAgent' + +import { migrateW3cCredentialRecordToV0_5 } from './w3cCredentialRecord' + +export async function updateV0_4ToV0_5(agent: Agent): Promise { + await migrateW3cCredentialRecordToV0_5(agent) +} diff --git a/packages/core/src/storage/migration/updates/0.4-0.5/w3cCredentialRecord.ts b/packages/core/src/storage/migration/updates/0.4-0.5/w3cCredentialRecord.ts new file mode 100644 index 0000000000..44adf36171 --- /dev/null +++ b/packages/core/src/storage/migration/updates/0.4-0.5/w3cCredentialRecord.ts @@ -0,0 +1,28 @@ +import type { BaseAgent } from '../../../../agent/BaseAgent' + +import { W3cCredentialRepository } from '../../../../modules/vc/repository' + +/** + * Re-saves the w3c credential records to add the new claimFormat tag. + */ +export async function migrateW3cCredentialRecordToV0_5(agent: Agent) { + agent.config.logger.info('Migration w3c credential records records to storage version 0.5') + + const w3cCredentialRepository = agent.dependencyManager.resolve(W3cCredentialRepository) + + agent.config.logger.debug(`Fetching all w3c credential records from storage`) + const records = await w3cCredentialRepository.getAll(agent.context) + + agent.config.logger.debug(`Found a total of ${records.length} w3c credential records to update.`) + + for (const record of records) { + agent.config.logger.debug( + `Re-saving w3c credential record with id ${record.id} to add claimFormat tag for storage version 0.5` + ) + + // Save updated record + await w3cCredentialRepository.update(agent.context, record) + + agent.config.logger.debug(`Successfully migrated w3c credential record with id ${record.id} to storage version 0.5`) + } +} diff --git a/packages/core/src/utils/Hasher.ts b/packages/core/src/utils/Hasher.ts index 023a69c708..4c9af1ac0c 100644 --- a/packages/core/src/utils/Hasher.ts +++ b/packages/core/src/utils/Hasher.ts @@ -1,23 +1,25 @@ import { hash as sha256 } from '@stablelib/sha256' -export type HashName = 'sha2-256' +import { TypedArrayEncoder } from './TypedArrayEncoder' + +export type HashName = 'sha-256' type HashingMap = { [key in HashName]: (data: Uint8Array) => Uint8Array } const hashingMap: HashingMap = { - 'sha2-256': (data) => sha256(data), + 'sha-256': (data) => sha256(data), } export class Hasher { - public static hash(data: Uint8Array, hashName: HashName): Uint8Array { - const hashFn = hashingMap[hashName] - - if (!hashFn) { - throw new Error(`Unsupported hash name '${hashName}'`) + public static hash(data: Uint8Array | string, hashName: HashName | string): Uint8Array { + const dataAsUint8Array = typeof data === 'string' ? TypedArrayEncoder.fromString(data) : data + if (hashName in hashingMap) { + const hashFn = hashingMap[hashName as HashName] + return hashFn(dataAsUint8Array) } - return hashFn(data) + throw new Error(`Unsupported hash name '${hashName}'`) } } diff --git a/packages/core/src/utils/HashlinkEncoder.ts b/packages/core/src/utils/HashlinkEncoder.ts index 6791b514f3..abb8728bf5 100644 --- a/packages/core/src/utils/HashlinkEncoder.ts +++ b/packages/core/src/utils/HashlinkEncoder.ts @@ -29,7 +29,7 @@ export class HashlinkEncoder { * Encodes a buffer, with optional metadata, into a hashlink * * @param buffer the buffer to encode into a hashlink - * @param hashAlgorithm the name of the hashing algorithm 'sha2-256' + * @param hashAlgorithm the name of the hashing algorithm 'sha-256' * @param baseEncoding the name of the base encoding algorithm 'base58btc' * @param metadata the optional metadata in the hashlink * diff --git a/packages/core/src/utils/MultiHashEncoder.ts b/packages/core/src/utils/MultiHashEncoder.ts index 43a333d495..d6742981b3 100644 --- a/packages/core/src/utils/MultiHashEncoder.ts +++ b/packages/core/src/utils/MultiHashEncoder.ts @@ -13,7 +13,7 @@ type MultiHashCodeMap = { } const multiHashNameMap: MultiHashNameMap = { - 'sha2-256': 0x12, + 'sha-256': 0x12, } const multiHashCodeMap: MultiHashCodeMap = Object.entries(multiHashNameMap).reduce( @@ -27,11 +27,11 @@ export class MultiHashEncoder { * Encodes a buffer into a hash * * @param buffer the buffer that has to be encoded - * @param hashName the hashing algorithm, 'sha2-256' + * @param hashName the hashing algorithm, 'sha-256' * * @returns a multihash */ - public static encode(data: Uint8Array, hashName: 'sha2-256'): Buffer { + public static encode(data: Uint8Array, hashName: HashName): Buffer { const hash = Hasher.hash(data, hashName) const hashCode = multiHashNameMap[hashName] diff --git a/packages/core/src/utils/__tests__/HashlinkEncoder.test.ts b/packages/core/src/utils/__tests__/HashlinkEncoder.test.ts index adf916866c..1beee86740 100644 --- a/packages/core/src/utils/__tests__/HashlinkEncoder.test.ts +++ b/packages/core/src/utils/__tests__/HashlinkEncoder.test.ts @@ -29,18 +29,18 @@ const invalidMetadata = describe('HashlinkEncoder', () => { describe('encode()', () => { it('Encodes string to hashlink', () => { - const hashlink = HashlinkEncoder.encode(validData.data, 'sha2-256') + const hashlink = HashlinkEncoder.encode(validData.data, 'sha-256') expect(hashlink).toEqual('hl:zQmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e') }) it('Encodes string and metadata to hashlink', () => { - const hashlink = HashlinkEncoder.encode(validData.data, 'sha2-256', 'base58btc', validData.metadata) + const hashlink = HashlinkEncoder.encode(validData.data, 'sha-256', 'base58btc', validData.metadata) expect(hashlink).toEqual(validHashlink) }) it('Encodes invalid metadata in hashlink', () => { expect(() => { - HashlinkEncoder.encode(validData.data, 'sha2-256', 'base58btc', invalidData.metadata) + HashlinkEncoder.encode(validData.data, 'sha-256', 'base58btc', invalidData.metadata) }).toThrow(/^Invalid metadata: /) }) }) diff --git a/packages/core/src/utils/__tests__/MultihashEncoder.test.ts b/packages/core/src/utils/__tests__/MultihashEncoder.test.ts index 6564f8d563..d60a2a1e2c 100644 --- a/packages/core/src/utils/__tests__/MultihashEncoder.test.ts +++ b/packages/core/src/utils/__tests__/MultihashEncoder.test.ts @@ -7,13 +7,13 @@ const validMultiHash = new Uint8Array([ 18, 32, 127, 131, 177, 101, 127, 241, 252, 83, 185, 45, 193, 129, 72, 161, 214, 93, 252, 45, 75, 31, 163, 214, 119, 40, 74, 221, 210, 0, 18, 109, 144, 105, ]) -const validHash = Hasher.hash(validData, 'sha2-256') +const validHash = Hasher.hash(validData, 'sha-256') const invalidMultiHash = new Uint8Array([99, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33]) describe('MultiHashEncoder', () => { describe('encode()', () => { it('encodes multihash', () => { - const multihash = MultiHashEncoder.encode(validData, 'sha2-256') + const multihash = MultiHashEncoder.encode(validData, 'sha-256') expect(multihash.equals(Buffer.from(validMultiHash))).toBe(true) }) }) @@ -21,7 +21,7 @@ describe('MultiHashEncoder', () => { describe('decode()', () => { it('Decodes multihash', () => { const { data, hashName } = MultiHashEncoder.decode(validMultiHash) - expect(hashName).toEqual('sha2-256') + expect(hashName).toEqual('sha-256') expect(data.equals(Buffer.from(validHash))).toBe(true) }) diff --git a/packages/core/src/utils/attachment.ts b/packages/core/src/utils/attachment.ts index f179ff6d1d..0cfdea098c 100644 --- a/packages/core/src/utils/attachment.ts +++ b/packages/core/src/utils/attachment.ts @@ -1,3 +1,4 @@ +import type { HashName } from './Hasher' import type { BaseName } from './MultiBaseEncoder' import type { Attachment } from '../decorators/attachment/Attachment' @@ -16,7 +17,7 @@ import { TypedArrayEncoder } from './TypedArrayEncoder' */ export function encodeAttachment( attachment: Attachment, - hashAlgorithm: 'sha2-256' = 'sha2-256', + hashAlgorithm: HashName = 'sha-256', baseName: BaseName = 'base58btc' ) { if (attachment.data.sha256) { diff --git a/packages/core/src/utils/deepEquality.ts b/packages/core/src/utils/deepEquality.ts index a8bb286d73..b2f2ac7aad 100644 --- a/packages/core/src/utils/deepEquality.ts +++ b/packages/core/src/utils/deepEquality.ts @@ -26,7 +26,7 @@ export function deepEquality(x: any, y: any): boolean { /** * @note This will only work for primitive array equality */ -function equalsIgnoreOrder(a: Array, b: Array): boolean { +export function equalsIgnoreOrder(a: Array, b: Array): boolean { if (a.length !== b.length) return false return a.every((k) => b.includes(k)) } diff --git a/packages/core/src/utils/path.ts b/packages/core/src/utils/path.ts index 8b4dc2c26b..6adbfe5616 100644 --- a/packages/core/src/utils/path.ts +++ b/packages/core/src/utils/path.ts @@ -7,3 +7,31 @@ export function getDirFromFilePath(path: string) { return path.substring(0, Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'))) } + +/** + * Combine multiple uri parts into a single uri taking into account slashes. + * + * @param parts the parts to combine + * @returns the combined url + */ +export function joinUriParts(base: string, parts: string[]) { + if (parts.length === 0) return base + + // take base without trailing / + let combined = base.trim() + combined = base.endsWith('/') ? base.slice(0, base.length - 1) : base + + for (const part of parts) { + // Remove leading and trailing / + let strippedPart = part.trim() + strippedPart = strippedPart.startsWith('/') ? strippedPart.slice(1) : strippedPart + strippedPart = strippedPart.endsWith('/') ? strippedPart.slice(0, strippedPart.length - 1) : strippedPart + + // Don't want to add if empty + if (strippedPart === '') continue + + combined += `/${strippedPart}` + } + + return combined +} diff --git a/packages/core/src/wallet/WalletModule.ts b/packages/core/src/wallet/WalletModule.ts index b8dfc25372..6b603b6a17 100644 --- a/packages/core/src/wallet/WalletModule.ts +++ b/packages/core/src/wallet/WalletModule.ts @@ -9,8 +9,8 @@ export class WalletModule implements Module { /** * Registers the dependencies of the wallet module on the injection dependencyManager. */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars public register(dependencyManager: DependencyManager) { - // Api - dependencyManager.registerContextScoped(WalletApi) + // no-op, only API needs to be registered } } diff --git a/packages/core/src/wallet/__tests__/WalletModule.test.ts b/packages/core/src/wallet/__tests__/WalletModule.test.ts index 894c911d58..a52a3a215f 100644 --- a/packages/core/src/wallet/__tests__/WalletModule.test.ts +++ b/packages/core/src/wallet/__tests__/WalletModule.test.ts @@ -1,5 +1,4 @@ import { DependencyManager } from '../../plugins/DependencyManager' -import { WalletApi } from '../WalletApi' import { WalletModule } from '../WalletModule' jest.mock('../../plugins/DependencyManager') @@ -10,8 +9,5 @@ const dependencyManager = new DependencyManagerMock() describe('WalletModule', () => { test('registers dependencies on the dependency manager', () => { new WalletModule().register(dependencyManager) - - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(WalletApi) }) }) diff --git a/packages/core/tests/index.ts b/packages/core/tests/index.ts index b8ea2ca430..4c4cb7819f 100644 --- a/packages/core/tests/index.ts +++ b/packages/core/tests/index.ts @@ -3,6 +3,6 @@ export * from './transport' export * from './events' export * from './helpers' -import testLogger from './logger' +import testLogger, { TestLogger } from './logger' -export { testLogger } +export { testLogger, TestLogger } diff --git a/packages/indy-sdk-to-askar-migration/tests/migrate.test.ts b/packages/indy-sdk-to-askar-migration/tests/migrate.test.ts index 7b3e7cea97..c1e69a2961 100644 --- a/packages/indy-sdk-to-askar-migration/tests/migrate.test.ts +++ b/packages/indy-sdk-to-askar-migration/tests/migrate.test.ts @@ -19,6 +19,7 @@ describe('Indy SDK To Askar Migration', () => { key: 'GfwU1DC7gEZNs3w41tjBiZYj7BNToDoFEqKY6wZXqs1A', keyDerivationMethod: KeyDerivationMethod.Raw, }, + autoUpdateStorageOnStartup: true, } const indySdkAgentDbPath = `${homedir()}/.indy_client/wallet/${indySdkAndAskarConfig.walletConfig?.id}/sqlite.db` @@ -90,7 +91,7 @@ describe('Indy SDK To Askar Migration', () => { mkdirSync(path.dirname(indySdkAgentDbPath), { recursive: true }) copyFileSync(indySdkWalletTestPath, indySdkAgentDbPath) - await expect(updater.update()).rejects.toThrowError(IndySdkToAskarMigrationError) + await expect(updater.update()).rejects.toThrow(IndySdkToAskarMigrationError) expect(existsSync(indySdkWalletTestPath)).toBe(true) }) }) diff --git a/packages/indy-vdr/src/IndyVdrModule.ts b/packages/indy-vdr/src/IndyVdrModule.ts index 85e48bc1af..63d0b262e9 100644 --- a/packages/indy-vdr/src/IndyVdrModule.ts +++ b/packages/indy-vdr/src/IndyVdrModule.ts @@ -1,8 +1,6 @@ import type { IndyVdrModuleConfigOptions } from './IndyVdrModuleConfig' import type { AgentContext, DependencyManager, Module } from '@credo-ts/core' -import { AgentConfig } from '@credo-ts/core' - import { IndyVdrApi } from './IndyVdrApi' import { IndyVdrModuleConfig } from './IndyVdrModuleConfig' import { IndyVdrPoolService } from './pool/IndyVdrPoolService' @@ -19,21 +17,11 @@ export class IndyVdrModule implements Module { } public register(dependencyManager: DependencyManager) { - // Warn about experimental module - dependencyManager - .resolve(AgentConfig) - .logger.warn( - "The '@credo-ts/indy-vdr' module is experimental and could have unexpected breaking changes. When using this module, make sure to use strict versions for all @credo-ts packages." - ) - // Config dependencyManager.registerInstance(IndyVdrModuleConfig, this.config) // Services dependencyManager.registerSingleton(IndyVdrPoolService) - - // Api - dependencyManager.registerContextScoped(IndyVdrApi) } public async initialize(agentContext: AgentContext): Promise { diff --git a/packages/indy-vdr/src/dids/IndyVdrIndyDidRegistrar.ts b/packages/indy-vdr/src/dids/IndyVdrIndyDidRegistrar.ts index 51d8e8e733..b100724107 100644 --- a/packages/indy-vdr/src/dids/IndyVdrIndyDidRegistrar.ts +++ b/packages/indy-vdr/src/dids/IndyVdrIndyDidRegistrar.ts @@ -173,7 +173,7 @@ export class IndyVdrIndyDidRegistrar implements DidRegistrar { } else { // Create a new key and calculate did according to the rules for indy did method verificationKey = await agentContext.wallet.createKey({ privateKey, seed, keyType: KeyType.Ed25519 }) - const buffer = Hasher.hash(verificationKey.publicKey, 'sha2-256') + const buffer = Hasher.hash(verificationKey.publicKey, 'sha-256') namespaceIdentifier = TypedArrayEncoder.toBase58(buffer.slice(0, 16)) did = `did:indy:${endorserNamespace}:${namespaceIdentifier}` diff --git a/packages/indy-vdr/src/dids/didIndyUtil.ts b/packages/indy-vdr/src/dids/didIndyUtil.ts index 38bcf88978..ebdfbd98ae 100644 --- a/packages/indy-vdr/src/dids/didIndyUtil.ts +++ b/packages/indy-vdr/src/dids/didIndyUtil.ts @@ -156,7 +156,7 @@ export function isSelfCertifiedIndyDid(did: string, verkey: string): boolean { } export function indyDidFromNamespaceAndInitialKey(namespace: string, initialKey: Key) { - const buffer = Hasher.hash(initialKey.publicKey, 'sha2-256') + const buffer = Hasher.hash(initialKey.publicKey, 'sha-256') const id = TypedArrayEncoder.toBase58(buffer.slice(0, 16)) const verkey = initialKey.publicKeyBase58 diff --git a/packages/openid4vc-client/CHANGELOG.md b/packages/openid4vc-client/CHANGELOG.md deleted file mode 100644 index 186aeaee17..0000000000 --- a/packages/openid4vc-client/CHANGELOG.md +++ /dev/null @@ -1,27 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [0.4.2](https://github.com/hyperledger/aries-framework-javascript/compare/v0.4.1...v0.4.2) (2023-10-05) - -**Note:** Version bump only for package @credo-ts/openid4vc-client - -## [0.4.1](https://github.com/hyperledger/aries-framework-javascript/compare/v0.4.0...v0.4.1) (2023-08-28) - -**Note:** Version bump only for package @credo-ts/openid4vc-client - -# [0.4.0](https://github.com/hyperledger/aries-framework-javascript/compare/v0.3.3...v0.4.0) (2023-06-03) - -### Bug Fixes - -- remove scope check from response ([#1450](https://github.com/hyperledger/aries-framework-javascript/issues/1450)) ([7dd4061](https://github.com/hyperledger/aries-framework-javascript/commit/7dd406170c75801529daf4bebebde81e84a4cb79)) - -### Features - -- **core:** add W3cCredentialsApi ([c888736](https://github.com/hyperledger/aries-framework-javascript/commit/c888736cb6b51014e23f5520fbc4074cf0e49e15)) -- **openid4vc-client:** openid authorization flow ([#1384](https://github.com/hyperledger/aries-framework-javascript/issues/1384)) ([996c08f](https://github.com/hyperledger/aries-framework-javascript/commit/996c08f8e32e58605408f5ed5b6d8116cea3b00c)) -- **openid4vc-client:** pre-authorized ([#1243](https://github.com/hyperledger/aries-framework-javascript/issues/1243)) ([3d86e78](https://github.com/hyperledger/aries-framework-javascript/commit/3d86e78a4df87869aa5df4e28b79cd91787b61fb)) -- **openid4vc:** jwt format and more crypto ([#1472](https://github.com/hyperledger/aries-framework-javascript/issues/1472)) ([bd4932d](https://github.com/hyperledger/aries-framework-javascript/commit/bd4932d34f7314a6d49097b6460c7570e1ebc7a8)) -- outbound message send via session ([#1335](https://github.com/hyperledger/aries-framework-javascript/issues/1335)) ([582c711](https://github.com/hyperledger/aries-framework-javascript/commit/582c711728db12b7d38a0be2e9fa78dbf31b34c6)) -- support more key types in jws service ([#1453](https://github.com/hyperledger/aries-framework-javascript/issues/1453)) ([8a3f03e](https://github.com/hyperledger/aries-framework-javascript/commit/8a3f03eb0dffcf46635556defdcebe1d329cf428)) diff --git a/packages/openid4vc-client/README.md b/packages/openid4vc-client/README.md deleted file mode 100644 index c5adad1948..0000000000 --- a/packages/openid4vc-client/README.md +++ /dev/null @@ -1,167 +0,0 @@ -

-
- Credo Logo -

-

Credo Open ID Connect For Verifiable Credentials Client Module

-

- License - typescript - @credo-ts/openid4vc-client version - -

-
- -Open ID Connect For Verifiable Credentials Client Module for [Credo](https://github.com/openwallet-foundation/credo-ts). - -### Installation - -Make sure you have set up the correct version of Credo according to the Credo repository. - -```sh -yarn add @credo-ts/openid4vc-client -``` - -### Quick start - -#### Requirements - -Before a credential can be requested, you need the issuer URI. This URI starts with `openid-initiate-issuance://` and is provided by the issuer. The issuer URI is commonly acquired by scanning a QR code. - -#### Module registration - -In order to get this module to work, we need to inject it into the agent. This makes the module's functionality accessible through the agent's `modules` api. - -```ts -import { OpenId4VcClientModule } from '@credo-ts/openid4vc-client' - -const agent = new Agent({ - config: { - /* config */ - }, - dependencies: agentDependencies, - modules: { - openId4VcClient: new OpenId4VcClientModule(), - /* other custom modules */ - }, -}) - -await agent.initialize() -``` - -How the module is injected and the agent has been initialized, you can access the module's functionality through `agent.modules.openId4VcClient`. - -#### Preparing a DID - -In order to request a credential, you'll need to provide a DID that the issuer will use for setting the credential subject. In the following snippet we create one for the sake of the example, but this can be any DID that has a _authentication verification method_ with key type `Ed25519`. - -```ts -// first we create the DID -const did = await agent.dids.create({ - method: 'key', - options: { - keyType: KeyType.Ed25519, - }, -}) - -// next we do some assertions and extract the key identifier (kid) - -if ( - !did.didState.didDocument || - !did.didState.didDocument.authentication || - did.didState.didDocument.authentication.length === 0 -) { - throw new Error("Error creating did document, or did document has no 'authentication' verificationMethods") -} - -const [verificationMethod] = did.didState.didDocument.authentication -const kid = typeof verificationMethod === 'string' ? verificationMethod : verificationMethod.id -``` - -#### Requesting the credential (Pre-Authorized) - -Now a credential issuance can be requested as follows. - -```ts -const w3cCredentialRecord = await agent.modules.openId4VcClient.requestCredentialPreAuthorized({ - issuerUri, - kid, - checkRevocationState: false, -}) - -console.log(w3cCredentialRecord) -``` - -#### Full example - -```ts -import { OpenId4VcClientModule } from '@credo-ts/openid4vc-client' -import { agentDependencies } from '@credo-ts/node' // use @credo-ts/react-native for React Native -import { Agent, KeyDidCreateOptions } from '@credo-ts/core' - -const run = async () => { - const issuerUri = '' // The obtained issuer URI - - // Create the Agent - const agent = new Agent({ - config: { - /* config */ - }, - dependencies: agentDependencies, - modules: { - openId4VcClient: new OpenId4VcClientModule(), - /* other custom modules */ - }, - }) - - // Initialize the Agent - await agent.initialize() - - // Create a DID - const did = await agent.dids.create({ - method: 'key', - options: { - keyType: KeyType.Ed25519, - }, - }) - - // Assert DIDDocument is valid - if ( - !did.didState.didDocument || - !did.didState.didDocument.authentication || - did.didState.didDocument.authentication.length === 0 - ) { - throw new Error("Error creating did document, or did document has no 'authentication' verificationMethods") - } - - // Extract key identified (kid) for authentication verification method - const [verificationMethod] = did.didState.didDocument.authentication - const kid = typeof verificationMethod === 'string' ? verificationMethod : verificationMethod.id - - // Request the credential - const w3cCredentialRecord = await agent.modules.openId4VcClient.requestCredentialPreAuthorized({ - issuerUri, - kid, - checkRevocationState: false, - }) - - // Log the received credential - console.log(w3cCredentialRecord) -} -``` diff --git a/packages/openid4vc-client/jest.config.ts b/packages/openid4vc-client/jest.config.ts deleted file mode 100644 index 93c0197296..0000000000 --- a/packages/openid4vc-client/jest.config.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { Config } from '@jest/types' - -import base from '../../jest.config.base' - -import packageJson from './package.json' - -const config: Config.InitialOptions = { - ...base, - displayName: packageJson.name, - setupFilesAfterEnv: ['./tests/setup.ts'], -} - -export default config diff --git a/packages/openid4vc-client/src/OpenId4VcClientApi.ts b/packages/openid4vc-client/src/OpenId4VcClientApi.ts deleted file mode 100644 index c5c24abfd1..0000000000 --- a/packages/openid4vc-client/src/OpenId4VcClientApi.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { - GenerateAuthorizationUrlOptions, - PreAuthCodeFlowOptions, - AuthCodeFlowOptions, -} from './OpenId4VcClientServiceOptions' -import type { W3cCredentialRecord } from '@credo-ts/core' - -import { AgentContext, injectable } from '@credo-ts/core' - -import { OpenId4VcClientService } from './OpenId4VcClientService' -import { AuthFlowType } from './OpenId4VcClientServiceOptions' - -/** - * @public - */ -@injectable() -export class OpenId4VcClientApi { - private agentContext: AgentContext - private openId4VcClientService: OpenId4VcClientService - - public constructor(agentContext: AgentContext, openId4VcClientService: OpenId4VcClientService) { - this.agentContext = agentContext - this.openId4VcClientService = openId4VcClientService - } - - public async requestCredentialUsingPreAuthorizedCode( - options: PreAuthCodeFlowOptions - ): Promise { - // set defaults - const verifyRevocationState = options.verifyCredentialStatus ?? true - - return this.openId4VcClientService.requestCredential(this.agentContext, { - ...options, - verifyCredentialStatus: verifyRevocationState, - flowType: AuthFlowType.PreAuthorizedCodeFlow, - }) - } - - public async requestCredentialUsingAuthorizationCode(options: AuthCodeFlowOptions): Promise { - // set defaults - const checkRevocationState = options.verifyCredentialStatus ?? true - - return this.openId4VcClientService.requestCredential(this.agentContext, { - ...options, - verifyCredentialStatus: checkRevocationState, - flowType: AuthFlowType.AuthorizationCodeFlow, - }) - } - - public async generateAuthorizationUrl(options: GenerateAuthorizationUrlOptions) { - return this.openId4VcClientService.generateAuthorizationUrl(options) - } -} diff --git a/packages/openid4vc-client/src/OpenId4VcClientModule.ts b/packages/openid4vc-client/src/OpenId4VcClientModule.ts deleted file mode 100644 index 932f90c8b8..0000000000 --- a/packages/openid4vc-client/src/OpenId4VcClientModule.ts +++ /dev/null @@ -1,31 +0,0 @@ -import type { DependencyManager, Module } from '@credo-ts/core' - -import { AgentConfig } from '@credo-ts/core' - -import { OpenId4VcClientApi } from './OpenId4VcClientApi' -import { OpenId4VcClientService } from './OpenId4VcClientService' - -/** - * @public - */ -export class OpenId4VcClientModule implements Module { - public readonly api = OpenId4VcClientApi - - /** - * Registers the dependencies of the openid4vc-client module on the dependency manager. - */ - public register(dependencyManager: DependencyManager) { - // Warn about experimental module - dependencyManager - .resolve(AgentConfig) - .logger.warn( - "The '@credo-ts/openid4vc-client' module is experimental and could have unexpected breaking changes. When using this module, make sure to use strict versions for all @credo-ts packages." - ) - - // Api - dependencyManager.registerContextScoped(OpenId4VcClientApi) - - // Services - dependencyManager.registerSingleton(OpenId4VcClientService) - } -} diff --git a/packages/openid4vc-client/src/OpenId4VcClientService.ts b/packages/openid4vc-client/src/OpenId4VcClientService.ts deleted file mode 100644 index 3c7d2ff9e2..0000000000 --- a/packages/openid4vc-client/src/OpenId4VcClientService.ts +++ /dev/null @@ -1,484 +0,0 @@ -import type { - GenerateAuthorizationUrlOptions, - RequestCredentialOptions, - ProofOfPossessionVerificationMethodResolver, - SupportedCredentialFormats, - ProofOfPossessionRequirements, -} from './OpenId4VcClientServiceOptions' -import type { - AgentContext, - W3cVerifiableCredential, - VerificationMethod, - JwaSignatureAlgorithm, - W3cCredentialRecord, - W3cVerifyCredentialResult, -} from '@credo-ts/core' -import type { CredentialMetadata, CredentialResponse, Jwt, OpenIDResponse } from '@sphereon/openid4vci-client' - -import { - ClaimFormat, - getJwkClassFromJwaSignatureAlgorithm, - W3cJwtVerifiableCredential, - CredoError, - getKeyFromVerificationMethod, - Hasher, - inject, - injectable, - InjectionSymbols, - JsonEncoder, - JsonTransformer, - JwsService, - Logger, - TypedArrayEncoder, - W3cCredentialService, - W3cJsonLdVerifiableCredential, - getJwkFromKey, - getSupportedVerificationMethodTypesFromKeyType, - getJwkClassFromKeyType, - parseDid, - SignatureSuiteRegistry, -} from '@credo-ts/core' -import { - AuthzFlowType, - CodeChallengeMethod, - CredentialRequestClientBuilder, - OpenID4VCIClient, - ProofOfPossessionBuilder, -} from '@sphereon/openid4vci-client' -import { randomStringForEntropy } from '@stablelib/random' - -import { supportedCredentialFormats, AuthFlowType } from './OpenId4VcClientServiceOptions' - -const flowTypeMapping = { - [AuthFlowType.AuthorizationCodeFlow]: AuthzFlowType.AUTHORIZATION_CODE_FLOW, - [AuthFlowType.PreAuthorizedCodeFlow]: AuthzFlowType.PRE_AUTHORIZED_CODE_FLOW, -} - -/** - * @internal - */ -@injectable() -export class OpenId4VcClientService { - private logger: Logger - private w3cCredentialService: W3cCredentialService - private jwsService: JwsService - - public constructor( - @inject(InjectionSymbols.Logger) logger: Logger, - w3cCredentialService: W3cCredentialService, - jwsService: JwsService - ) { - this.w3cCredentialService = w3cCredentialService - this.jwsService = jwsService - this.logger = logger - } - - private generateCodeVerifier(): string { - return randomStringForEntropy(256) - } - - public async generateAuthorizationUrl(options: GenerateAuthorizationUrlOptions) { - this.logger.debug('Generating authorization url') - - if (!options.scope || options.scope.length === 0) { - throw new CredoError( - 'Only scoped based authorization requests are supported at this time. Please provide at least one scope' - ) - } - - const client = await OpenID4VCIClient.initiateFromURI({ - issuanceInitiationURI: options.initiationUri, - flowType: AuthzFlowType.AUTHORIZATION_CODE_FLOW, - }) - const codeVerifier = this.generateCodeVerifier() - const codeVerifierSha256 = Hasher.hash(TypedArrayEncoder.fromString(codeVerifier), 'sha2-256') - const base64Url = TypedArrayEncoder.toBase64URL(codeVerifierSha256) - - this.logger.debug('Converted code_verifier to code_challenge', { - codeVerifier: codeVerifier, - sha256: codeVerifierSha256.toString(), - base64Url: base64Url, - }) - - const authorizationUrl = client.createAuthorizationRequestUrl({ - clientId: options.clientId, - codeChallengeMethod: CodeChallengeMethod.SHA256, - codeChallenge: base64Url, - redirectUri: options.redirectUri, - scope: options.scope?.join(' '), - }) - - return { - authorizationUrl, - codeVerifier, - } - } - - public async requestCredential(agentContext: AgentContext, options: RequestCredentialOptions) { - const receivedCredentials: W3cCredentialRecord[] = [] - const supportedJwaSignatureAlgorithms = this.getSupportedJwaSignatureAlgorithms(agentContext) - - const allowedProofOfPossessionSignatureAlgorithms = options.allowedProofOfPossessionSignatureAlgorithms - ? options.allowedProofOfPossessionSignatureAlgorithms.filter((algorithm) => - supportedJwaSignatureAlgorithms.includes(algorithm) - ) - : supportedJwaSignatureAlgorithms - - // Take the allowed credential formats from the options or use the default - const allowedCredentialFormats = options.allowedCredentialFormats ?? supportedCredentialFormats - - const flowType = flowTypeMapping[options.flowType] - if (!flowType) { - throw new CredoError(`Unsupported flowType ${options.flowType}. Valid values are ${Object.values(AuthFlowType)}`) - } - - const client = await OpenID4VCIClient.initiateFromURI({ - issuanceInitiationURI: options.issuerUri, - flowType, - }) - - // acquire the access token - // NOTE: only scope based flow is supported for authorized flow. However there's not clear mapping between - // the scope property and which credential to request (this is out of scope of the spec), so it will still - // just request all credentials that have been offered in the credential offer. We may need to add some extra - // input properties that allows to define the credential type(s) to request. - const accessToken = - options.flowType === AuthFlowType.AuthorizationCodeFlow - ? await client.acquireAccessToken({ - clientId: options.clientId, - code: options.authorizationCode, - codeVerifier: options.codeVerifier, - redirectUri: options.redirectUri, - }) - : await client.acquireAccessToken({}) - - const serverMetadata = await client.retrieveServerMetadata() - - this.logger.info('Fetched server metadata', { - issuer: serverMetadata.issuer, - credentialEndpoint: serverMetadata.credential_endpoint, - tokenEndpoint: serverMetadata.token_endpoint, - }) - - const credentialsSupported = client.getCredentialsSupported(true) - - this.logger.debug('Full server metadata', serverMetadata) - - // Loop through all the credentialTypes in the credential offer - for (const credentialType of client.getCredentialTypesFromInitiation()) { - const credentialMetadata = credentialsSupported[credentialType] - - // Get all options for the credential request (such as which kid to use, the signature algorithm, etc) - const { verificationMethod, credentialFormat, signatureAlgorithm } = await this.getCredentialRequestOptions( - agentContext, - { - allowedCredentialFormats, - allowedProofOfPossessionSignatureAlgorithms, - credentialMetadata, - credentialType, - proofOfPossessionVerificationMethodResolver: options.proofOfPossessionVerificationMethodResolver, - } - ) - - // Create the proof of possession - const proofInput = await ProofOfPossessionBuilder.fromAccessTokenResponse({ - accessTokenResponse: accessToken, - callbacks: { - signCallback: this.signCallback(agentContext, verificationMethod), - }, - }) - .withEndpointMetadata(serverMetadata) - .withAlg(signatureAlgorithm) - .withKid(verificationMethod.id) - .build() - - this.logger.debug('Generated JWS', proofInput) - - // Acquire the credential - const credentialRequestClient = CredentialRequestClientBuilder.fromIssuanceInitiationURI({ - uri: options.issuerUri, - metadata: serverMetadata, - }) - .withTokenFromResponse(accessToken) - .build() - - const credentialResponse = await credentialRequestClient.acquireCredentialsUsingProof({ - proofInput, - credentialType, - format: credentialFormat, - }) - - const storedCredential = await this.handleCredentialResponse(agentContext, credentialResponse, { - verifyCredentialStatus: options.verifyCredentialStatus, - }) - - receivedCredentials.push(storedCredential) - } - - return receivedCredentials - } - - /** - * Get the options for the credential request. Internally this will resolve the proof of possession - * requirements, and based on that it will call the proofOfPossessionVerificationMethodResolver to - * allow the caller to select the correct verification method based on the requirements for the proof - * of possession. - */ - private async getCredentialRequestOptions( - agentContext: AgentContext, - options: { - proofOfPossessionVerificationMethodResolver: ProofOfPossessionVerificationMethodResolver - allowedCredentialFormats: SupportedCredentialFormats[] - allowedProofOfPossessionSignatureAlgorithms: JwaSignatureAlgorithm[] - credentialMetadata: CredentialMetadata - credentialType: string - } - ) { - const { credentialFormat, signatureAlgorithm, supportedDidMethods, supportsAllDidMethods } = - this.getProofOfPossessionRequirements(agentContext, { - credentialType: options.credentialType, - credentialMetadata: options.credentialMetadata, - allowedCredentialFormats: options.allowedCredentialFormats, - allowedProofOfPossessionSignatureAlgorithms: options.allowedProofOfPossessionSignatureAlgorithms, - }) - - const JwkClass = getJwkClassFromJwaSignatureAlgorithm(signatureAlgorithm) - - if (!JwkClass) { - throw new CredoError(`Could not determine JWK key type based on JWA signature algorithm '${signatureAlgorithm}'`) - } - - const supportedVerificationMethods = getSupportedVerificationMethodTypesFromKeyType(JwkClass.keyType) - - // Now we need to determine the did method and alg based on the cryptographic suite - const verificationMethod = await options.proofOfPossessionVerificationMethodResolver({ - credentialFormat, - proofOfPossessionSignatureAlgorithm: signatureAlgorithm, - supportedVerificationMethods, - keyType: JwkClass.keyType, - credentialType: options.credentialType, - supportsAllDidMethods, - supportedDidMethods, - }) - - // Make sure the verification method uses a supported did method - if ( - !supportsAllDidMethods && - !supportedDidMethods.find((supportedDidMethod) => verificationMethod.id.startsWith(supportedDidMethod)) - ) { - const { method } = parseDid(verificationMethod.id) - const supportedDidMethodsString = supportedDidMethods.join(', ') - throw new CredoError( - `Verification method uses did method '${method}', but issuer only supports '${supportedDidMethodsString}'` - ) - } - - // Make sure the verification method uses a supported verification method type - if (!supportedVerificationMethods.includes(verificationMethod.type)) { - const supportedVerificationMethodsString = supportedVerificationMethods.join(', ') - throw new CredoError( - `Verification method uses verification method type '${verificationMethod.type}', but only '${supportedVerificationMethodsString}' verification methods are supported for key type '${JwkClass.keyType}'` - ) - } - - return { verificationMethod, signatureAlgorithm, credentialFormat } - } - - /** - * Get the requirements for creating the proof of possession. Based on the allowed - * credential formats, the allowed proof of possession signature algorithms, and the - * credential type, this method will select the best credential format and signature - * algorithm to use, based on the order of preference. - */ - private getProofOfPossessionRequirements( - agentContext: AgentContext, - options: { - allowedCredentialFormats: SupportedCredentialFormats[] - credentialMetadata: CredentialMetadata - allowedProofOfPossessionSignatureAlgorithms: JwaSignatureAlgorithm[] - credentialType: string - } - ): ProofOfPossessionRequirements { - // Find the potential credentialFormat to use - const potentialCredentialFormats = options.allowedCredentialFormats.filter( - (allowedFormat) => options.credentialMetadata.formats[allowedFormat] !== undefined - ) - - // TODO: we may want to add a logging statement here if the supported formats of the wallet - // DOES support one of the issuer formats, but it is not in the allowedFormats - if (potentialCredentialFormats.length === 0) { - const formatsString = Object.keys(options.credentialMetadata.formats).join(', ') - throw new CredoError( - `Issuer only supports formats '${formatsString}' for credential type '${ - options.credentialType - }', but the wallet only allows formats '${options.allowedCredentialFormats.join(', ')}'` - ) - } - - // Loop through all the potential credential formats and find the first one that we have a matching - // cryptographic suite supported for. - for (const potentialCredentialFormat of potentialCredentialFormats) { - const credentialFormat = options.credentialMetadata.formats[potentialCredentialFormat] - const issuerSupportedCryptographicSuites = credentialFormat.cryptographic_suites_supported ?? [] - // FIXME: somehow the MATTR Launchpad returns binding_methods_supported instead of cryptographic_binding_methods_supported - const issuerSupportedBindingMethods: string[] = - credentialFormat.cryptographic_binding_methods_supported ?? credentialFormat.binding_methods_supported ?? [] - - // For each of the supported algs, find the key types, then find the proof types - const signatureSuiteRegistry = agentContext.dependencyManager.resolve(SignatureSuiteRegistry) - - let potentialSignatureAlgorithm: JwaSignatureAlgorithm | undefined - - switch (potentialCredentialFormat) { - case ClaimFormat.JwtVc: - potentialSignatureAlgorithm = options.allowedProofOfPossessionSignatureAlgorithms.find((signatureAlgorithm) => - issuerSupportedCryptographicSuites.includes(signatureAlgorithm) - ) - break - case ClaimFormat.LdpVc: - // We need to find it based on the JSON-LD proof type - potentialSignatureAlgorithm = options.allowedProofOfPossessionSignatureAlgorithms.find( - (signatureAlgorithm) => { - const JwkClass = getJwkClassFromJwaSignatureAlgorithm(signatureAlgorithm) - if (!JwkClass) return false - - // TODO: getByKeyType should return a list - const matchingSuite = signatureSuiteRegistry.getByKeyType(JwkClass.keyType) - if (!matchingSuite) return false - - return issuerSupportedCryptographicSuites.includes(matchingSuite.proofType) - } - ) - break - } - - // If no match, continue to the next one. - if (!potentialSignatureAlgorithm) continue - - const supportsAllDidMethods = issuerSupportedBindingMethods.includes('did') - const supportedDidMethods = issuerSupportedBindingMethods.filter((method) => method.startsWith('did:')) - - // Make sure that the issuer supports the 'did' binding method, or at least one specific did method - if (!supportsAllDidMethods && supportedDidMethods.length === 0) continue - - return { - credentialFormat: potentialCredentialFormat, - signatureAlgorithm: potentialSignatureAlgorithm, - supportedDidMethods, - supportsAllDidMethods, - } - } - - throw new CredoError( - 'Could not determine the correct credential format and signature algorithm to use for the proof of possession.' - ) - } - - /** - * Returns the JWA Signature Algorithms that are supported by the wallet. - * - * This is an approximation based on the supported key types of the wallet. - * This is not 100% correct as a supporting a key type does not mean you support - * all the algorithms for that key type. However, this needs refactoring of the wallet - * that is planned for the 0.5.0 release. - */ - private getSupportedJwaSignatureAlgorithms(agentContext: AgentContext): JwaSignatureAlgorithm[] { - const supportedKeyTypes = agentContext.wallet.supportedKeyTypes - - // Extract the supported JWS algs based on the key types the wallet support. - const supportedJwaSignatureAlgorithms = supportedKeyTypes - // Map the supported key types to the supported JWK class - .map(getJwkClassFromKeyType) - // Filter out the undefined values - .filter((jwkClass): jwkClass is Exclude => jwkClass !== undefined) - // Extract the supported JWA signature algorithms from the JWK class - .map((jwkClass) => jwkClass.supportedSignatureAlgorithms) - // Flatten the array of arrays - .reduce((allAlgorithms, algorithms) => [...allAlgorithms, ...algorithms], []) - - return supportedJwaSignatureAlgorithms - } - - private async handleCredentialResponse( - agentContext: AgentContext, - credentialResponse: OpenIDResponse, - options: { verifyCredentialStatus: boolean } - ) { - this.logger.debug('Credential request response', credentialResponse) - - if (!credentialResponse.successBody) { - throw new CredoError('Did not receive a successful credential response') - } - - let credential: W3cVerifiableCredential - let result: W3cVerifyCredentialResult - if (credentialResponse.successBody.format === ClaimFormat.LdpVc) { - credential = JsonTransformer.fromJSON(credentialResponse.successBody.credential, W3cJsonLdVerifiableCredential) - result = await this.w3cCredentialService.verifyCredential(agentContext, { - credential, - verifyCredentialStatus: options.verifyCredentialStatus, - }) - } else if (credentialResponse.successBody.format === ClaimFormat.JwtVc) { - credential = W3cJwtVerifiableCredential.fromSerializedJwt(credentialResponse.successBody.credential as string) - result = await this.w3cCredentialService.verifyCredential(agentContext, { - credential, - verifyCredentialStatus: options.verifyCredentialStatus, - }) - } else { - throw new CredoError(`Unsupported credential format ${credentialResponse.successBody.format}`) - } - - if (!result || !result.isValid) { - throw new CredoError(`Failed to validate credential, error = ${result.error}`) - } - - const storedCredential = await this.w3cCredentialService.storeCredential(agentContext, { - credential, - }) - this.logger.info(`Stored credential with id: ${storedCredential.id}`) - this.logger.debug('Full credential', storedCredential) - - return storedCredential - } - - private signCallback(agentContext: AgentContext, verificationMethod: VerificationMethod) { - return async (jwt: Jwt, kid: string) => { - if (!jwt.header) { - throw new CredoError('No header present on JWT') - } - - if (!jwt.payload) { - throw new CredoError('No payload present on JWT') - } - - // We have determined the verification method before and already passed that when creating the callback, - // however we just want to make sure that the kid matches the verification method id - if (verificationMethod.id !== kid) { - throw new CredoError(`kid ${kid} does not match verification method id ${verificationMethod.id}`) - } - - const key = getKeyFromVerificationMethod(verificationMethod) - const jwk = getJwkFromKey(key) - - const payload = JsonEncoder.toBuffer(jwt.payload) - if (!jwk.supportsSignatureAlgorithm(jwt.header.alg)) { - throw new CredoError( - `kid ${kid} refers to a key of type '${jwk.keyType}', which does not support the JWS signature alg '${jwt.header.alg}'` - ) - } - - // We don't support these properties, remove them, so we can pass all other header properties to the JWS service - if (jwt.header.x5c || jwt.header.jwk) throw new CredoError('x5c and jwk are not supported') - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { x5c: _x5c, jwk: _jwk, ...supportedHeaderOptions } = jwt.header - - const jws = await this.jwsService.createJwsCompact(agentContext, { - key, - payload, - protectedHeaderOptions: supportedHeaderOptions, - }) - - return jws - } - } -} diff --git a/packages/openid4vc-client/src/OpenId4VcClientServiceOptions.ts b/packages/openid4vc-client/src/OpenId4VcClientServiceOptions.ts deleted file mode 100644 index 5ee1229dba..0000000000 --- a/packages/openid4vc-client/src/OpenId4VcClientServiceOptions.ts +++ /dev/null @@ -1,170 +0,0 @@ -import type { JwaSignatureAlgorithm, KeyType, VerificationMethod } from '@credo-ts/core' - -import { ClaimFormat } from '@credo-ts/core' - -/** - * The credential formats that are supported by the openid4vc client - */ -export type SupportedCredentialFormats = ClaimFormat.JwtVc | ClaimFormat.LdpVc -export const supportedCredentialFormats = [ClaimFormat.JwtVc, ClaimFormat.LdpVc] satisfies SupportedCredentialFormats[] - -/** - * Options that are used for the pre-authorized code flow. - */ -export interface PreAuthCodeFlowOptions { - issuerUri: string - verifyCredentialStatus: boolean - - /** - * A list of allowed credential formats in order of preference. - * - * If the issuer supports one of the allowed formats, that first format that is supported - * from the list will be used. - * - * If the issuer doesn't support any of the allowed formats, an error is thrown - * and the request is aborted. - */ - allowedCredentialFormats?: SupportedCredentialFormats[] - - /** - * A list of allowed proof of possession signature algorithms in order of preference. - * - * Note that the signature algorithms must be supported by the wallet implementation. - * Signature algorithms that are not supported by the wallet will be ignored. - * - * The proof of possession (pop) signature algorithm is used in the credential request - * to bind the credential to a did. In most cases the JWA signature algorithm - * that is used in the pop will determine the cryptographic suite that is used - * for signing the credential, but this not a requirement for the spec. E.g. if the - * pop uses EdDsa, the credential will most commonly also use EdDsa, or Ed25519Signature2018/2020. - */ - allowedProofOfPossessionSignatureAlgorithms?: JwaSignatureAlgorithm[] - - /** - * A function that should resolve a verification method based on the options passed. - * This method will be called once for each of the credentials that are included - * in the credential offer. - * - * Based on the credential format, JWA signature algorithm, verification method types - * and did methods, the resolver must return a verification method that will be used - * for the proof of possession signature. - */ - proofOfPossessionVerificationMethodResolver: ProofOfPossessionVerificationMethodResolver -} - -/** - * Options that are used for the authorization code flow. - * Extends the pre-authorized code flow options. - */ -export interface AuthCodeFlowOptions extends PreAuthCodeFlowOptions { - clientId: string - authorizationCode: string - codeVerifier: string - redirectUri: string -} - -/** - * The options that are used to generate the authorization url. - * - * NOTE: The `code_challenge` property is omitted here - * because we assume it will always be SHA256 - * as clear text code challenges are unsafe. - */ -export interface GenerateAuthorizationUrlOptions { - initiationUri: string - clientId: string - redirectUri: string - scope?: string[] -} - -export interface ProofOfPossessionVerificationMethodResolverOptions { - /** - * The credential format that will be requested from the issuer. - * E.g. `jwt_vc` or `ldp_vc`. - */ - credentialFormat: SupportedCredentialFormats - - /** - * The JWA Signature Algorithm that will be used in the proof of possession. - * This is based on the `allowedProofOfPossessionSignatureAlgorithms` passed - * to the request credential method, and the supported signature algorithms. - */ - proofOfPossessionSignatureAlgorithm: JwaSignatureAlgorithm - - /** - * This is a list of verification methods types that are supported - * for creating the proof of possession signature. The returned - * verification method type must be of one of these types. - */ - supportedVerificationMethods: string[] - - /** - * The key type that will be used to create the proof of possession signature. - * This is related to the verification method and the signature algorithm, and - * is added for convenience. - */ - keyType: KeyType - - /** - * The credential type that will be requested from the issuer. This is - * based on the credential types that are included the credential offer. - */ - credentialType: string - - /** - * Whether the issuer supports the `did` cryptographic binding method, - * indicating they support all did methods. In most cases, they do not - * support all did methods, and it means we have to make an assumption - * about the did methods they support. - * - * If this value is `false`, the `supportedDidMethods` property will - * contain a list of supported did methods. - */ - supportsAllDidMethods: boolean - - /** - * A list of supported did methods. This is only used if the `supportsAllDidMethods` - * property is `false`. When this array is populated, the returned verification method - * MUST be based on one of these did methods. - * - * The did methods are returned in the format `did:`, e.g. `did:web`. - */ - supportedDidMethods: string[] -} - -/** - * The proof of possession verification method resolver is a function that can be passed by the - * user of the framework and allows them to determine which verification method should be used - * for the proof of possession signature. - */ -export type ProofOfPossessionVerificationMethodResolver = ( - options: ProofOfPossessionVerificationMethodResolverOptions -) => Promise | VerificationMethod - -/** - * @internal - */ -export interface ProofOfPossessionRequirements { - credentialFormat: SupportedCredentialFormats - signatureAlgorithm: JwaSignatureAlgorithm - supportedDidMethods: string[] - supportsAllDidMethods: boolean -} - -/** - * @internal - */ -export enum AuthFlowType { - AuthorizationCodeFlow, - PreAuthorizedCodeFlow, -} - -type WithFlowType = Options & { flowType: FlowType } - -/** - * The options that are used to request a credential from an issuer. - * @internal - */ -export type RequestCredentialOptions = - | WithFlowType - | WithFlowType diff --git a/packages/openid4vc-client/src/index.ts b/packages/openid4vc-client/src/index.ts deleted file mode 100644 index 1ca13fe3b1..0000000000 --- a/packages/openid4vc-client/src/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -export * from './OpenId4VcClientModule' -export * from './OpenId4VcClientApi' -export * from './OpenId4VcClientService' - -// Contains internal types, so we don't export everything -export { - AuthCodeFlowOptions, - PreAuthCodeFlowOptions, - GenerateAuthorizationUrlOptions, - RequestCredentialOptions, - SupportedCredentialFormats, - ProofOfPossessionVerificationMethodResolver, - ProofOfPossessionVerificationMethodResolverOptions, -} from './OpenId4VcClientServiceOptions' diff --git a/packages/openid4vc-client/tests/fixtures.ts b/packages/openid4vc-client/tests/fixtures.ts deleted file mode 100644 index b8b322a428..0000000000 --- a/packages/openid4vc-client/tests/fixtures.ts +++ /dev/null @@ -1,326 +0,0 @@ -export const mattrLaunchpadJsonLd = { - credentialOffer: - 'openid-initiate-issuance://?issuer=https://launchpad.mattrlabs.com&credential_type=OpenBadgeCredential&pre-authorized_code=krBcsBIlye2T-G4-rHHnRZUCah9uzDKwohJK6ABNvL-', - getMetadataResponse: { - authorization_endpoint: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/authorize', - token_endpoint: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/token', - jwks_uri: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/jwks', - token_endpoint_auth_methods_supported: [ - 'none', - 'client_secret_basic', - 'client_secret_jwt', - 'client_secret_post', - 'private_key_jwt', - ], - code_challenge_methods_supported: ['S256'], - grant_types_supported: ['authorization_code', 'urn:ietf:params:oauth:grant-type:pre-authorized_code'], - response_modes_supported: ['form_post', 'fragment', 'query'], - response_types_supported: ['code id_token', 'code', 'id_token', 'none'], - scopes_supported: ['OpenBadgeCredential', 'AcademicAward', 'LearnerProfile', 'PermanentResidentCard'], - token_endpoint_auth_signing_alg_values_supported: ['HS256', 'RS256', 'PS256', 'ES256', 'EdDSA'], - credential_endpoint: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/credential', - credentials_supported: { - OpenBadgeCredential: { - formats: { - ldp_vc: { - name: 'JFF x vc-edu PlugFest 2', - description: "MATTR's submission for JFF Plugfest 2", - types: ['OpenBadgeCredential'], - binding_methods_supported: ['did'], - cryptographic_suites_supported: ['Ed25519Signature2018'], - }, - }, - }, - AcademicAward: { - formats: { - ldp_vc: { - name: 'Example Academic Award', - description: 'Microcredential from the MyCreds Network.', - types: ['AcademicAward'], - binding_methods_supported: ['did'], - cryptographic_suites_supported: ['Ed25519Signature2018'], - }, - }, - }, - LearnerProfile: { - formats: { - ldp_vc: { - name: 'Digitary Learner Profile', - description: 'Example', - types: ['LearnerProfile'], - binding_methods_supported: ['did'], - cryptographic_suites_supported: ['Ed25519Signature2018'], - }, - }, - }, - PermanentResidentCard: { - formats: { - ldp_vc: { - name: 'Permanent Resident Card', - description: 'Government of Kakapo', - types: ['PermanentResidentCard'], - binding_methods_supported: ['did'], - cryptographic_suites_supported: ['Ed25519Signature2018'], - }, - }, - }, - }, - }, - - acquireAccessTokenResponse: { - access_token: '7nikUotMQefxn7oRX56R7MDNE7KJTGfwGjOkHzGaUIG', - expires_in: 3600, - scope: 'OpenBadgeCredential', - token_type: 'Bearer', - }, - credentialResponse: { - format: 'ldp_vc', - credential: { - type: ['VerifiableCredential', 'VerifiableCredentialExtension', 'OpenBadgeCredential'], - issuer: { - id: 'did:web:launchpad.vii.electron.mattrlabs.io', - name: 'Jobs for the Future (JFF)', - iconUrl: 'https://w3c-ccg.github.io/vc-ed/plugfest-1-2022/images/JFF_LogoLockup.png', - image: 'https://w3c-ccg.github.io/vc-ed/plugfest-1-2022/images/JFF_LogoLockup.png', - }, - name: 'JFF x vc-edu PlugFest 2', - description: "MATTR's submission for JFF Plugfest 2", - credentialBranding: { - backgroundColor: '#464c49', - }, - issuanceDate: '2023-01-25T16:58:06.292Z', - credentialSubject: { - id: 'did:key:z6MkpGR4gs4Rc3Zph4vj8wRnjnAxgAPSxcR8MAVKutWspQzc', - type: ['AchievementSubject'], - achievement: { - id: 'urn:uuid:bd6d9316-f7ae-4073-a1e5-2f7f5bd22922', - name: 'JFF x vc-edu PlugFest 2 Interoperability', - type: ['Achievement'], - image: { - id: 'https://w3c-ccg.github.io/vc-ed/plugfest-2-2022/images/JFF-VC-EDU-PLUGFEST2-badge-image.png', - type: 'Image', - }, - criteria: { - type: 'Criteria', - narrative: - 'Solutions providers earned this badge by demonstrating interoperability between multiple providers based on the OBv3 candidate final standard, with some additional required fields. Credential issuers earning this badge successfully issued a credential into at least two wallets. Wallet implementers earning this badge successfully displayed credentials issued by at least two different credential issuers.', - }, - description: - 'This credential solution supports the use of OBv3 and w3c Verifiable Credentials and is interoperable with at least two other solutions. This was demonstrated successfully during JFF x vc-edu PlugFest 2.', - }, - }, - '@context': [ - 'https://www.w3.org/2018/credentials/v1', - { - '@vocab': 'https://w3id.org/security/undefinedTerm#', - }, - 'https://mattr.global/contexts/vc-extensions/v1', - 'https://purl.imsglobal.org/spec/ob/v3p0/context.json', - 'https://w3c-ccg.github.io/vc-status-rl-2020/contexts/vc-revocation-list-2020/v1.jsonld', - ], - credentialStatus: { - id: 'https://launchpad.vii.electron.mattrlabs.io/core/v1/revocation-lists/b4aa46a0-5539-4a6b-aa03-8f6791c22ce3#49', - type: 'RevocationList2020Status', - revocationListIndex: '49', - revocationListCredential: - 'https://launchpad.vii.electron.mattrlabs.io/core/v1/revocation-lists/b4aa46a0-5539-4a6b-aa03-8f6791c22ce3', - }, - proof: { - type: 'Ed25519Signature2018', - created: '2023-01-25T16:58:07Z', - jws: 'eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..PrpRKt60yXOzMNiQY5bELX40F6Svwm-FyQ-Jv02VJDfTTH8GPPByjtOb_n3YfWidQVgySfGQ_H7VmCGjvsU6Aw', - proofPurpose: 'assertionMethod', - verificationMethod: 'did:web:launchpad.vii.electron.mattrlabs.io#6BhFMCGTJg', - }, - }, - }, -} - -export const waltIdJffJwt = { - credentialOffer: - 'openid-initiate-issuance://?issuer=https%3A%2F%2Fjff.walt.id%2Fissuer-api%2Fdefault%2Foidc%2F&credential_type=VerifiableId&pre-authorized_code=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI4YmI0NWZiNC0zNDc1LTQ5YzItODVjNy0wYjkxZjY4N2RhNDQiLCJwcmUtYXV0aG9yaXplZCI6dHJ1ZX0.R8nHseZJvU3uVL3Ox-97i1HUnvjZH6wKSWDO_i8D12I&user_pin_required=false', - getMetadataResponse: { - authorization_endpoint: 'https://jff.walt.id/issuer-api/default/oidc/fulfillPAR', - token_endpoint: 'https://jff.walt.id/issuer-api/default/oidc/token', - pushed_authorization_request_endpoint: 'https://jff.walt.id/issuer-api/default/oidc/par', - issuer: 'https://jff.walt.id/issuer-api/default', - jwks_uri: 'https://jff.walt.id/issuer-api/default/oidc', - grant_types_supported: ['authorization_code', 'urn:ietf:params:oauth:grant-type:pre-authorized_code'], - request_uri_parameter_supported: true, - credentials_supported: { - VerifiableId: { - display: [{ name: 'VerifiableId' }], - formats: { - ldp_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: [ - 'Ed25519Signature2018', - 'Ed25519Signature2020', - 'EcdsaSecp256k1Signature2019', - 'RsaSignature2018', - 'JsonWebSignature2020', - 'JcsEd25519Signature2020', - ], - types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableId'], - }, - jwt_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: ['ES256', 'ES256K', 'EdDSA', 'RS256', 'PS256'], - types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableId'], - }, - }, - }, - VerifiableDiploma: { - display: [{ name: 'VerifiableDiploma' }], - formats: { - ldp_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: [ - 'Ed25519Signature2018', - 'Ed25519Signature2020', - 'EcdsaSecp256k1Signature2019', - 'RsaSignature2018', - 'JsonWebSignature2020', - 'JcsEd25519Signature2020', - ], - types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableDiploma'], - }, - jwt_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: ['ES256', 'ES256K', 'EdDSA', 'RS256', 'PS256'], - types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableDiploma'], - }, - }, - }, - VerifiableVaccinationCertificate: { - display: [{ name: 'VerifiableVaccinationCertificate' }], - formats: { - ldp_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: [ - 'Ed25519Signature2018', - 'Ed25519Signature2020', - 'EcdsaSecp256k1Signature2019', - 'RsaSignature2018', - 'JsonWebSignature2020', - 'JcsEd25519Signature2020', - ], - types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableVaccinationCertificate'], - }, - jwt_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: ['ES256', 'ES256K', 'EdDSA', 'RS256', 'PS256'], - types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableVaccinationCertificate'], - }, - }, - }, - ProofOfResidence: { - display: [{ name: 'ProofOfResidence' }], - formats: { - ldp_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: [ - 'Ed25519Signature2018', - 'Ed25519Signature2020', - 'EcdsaSecp256k1Signature2019', - 'RsaSignature2018', - 'JsonWebSignature2020', - 'JcsEd25519Signature2020', - ], - types: ['VerifiableCredential', 'VerifiableAttestation', 'ProofOfResidence'], - }, - jwt_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: ['ES256', 'ES256K', 'EdDSA', 'RS256', 'PS256'], - types: ['VerifiableCredential', 'VerifiableAttestation', 'ProofOfResidence'], - }, - }, - }, - ParticipantCredential: { - display: [{ name: 'ParticipantCredential' }], - formats: { - ldp_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: [ - 'Ed25519Signature2018', - 'Ed25519Signature2020', - 'EcdsaSecp256k1Signature2019', - 'RsaSignature2018', - 'JsonWebSignature2020', - 'JcsEd25519Signature2020', - ], - types: ['VerifiableCredential', 'ParticipantCredential'], - }, - jwt_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: ['ES256', 'ES256K', 'EdDSA', 'RS256', 'PS256'], - types: ['VerifiableCredential', 'ParticipantCredential'], - }, - }, - }, - Europass: { - display: [{ name: 'Europass' }], - formats: { - ldp_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: [ - 'Ed25519Signature2018', - 'Ed25519Signature2020', - 'EcdsaSecp256k1Signature2019', - 'RsaSignature2018', - 'JsonWebSignature2020', - 'JcsEd25519Signature2020', - ], - types: ['VerifiableCredential', 'VerifiableAttestation', 'Europass'], - }, - jwt_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: ['ES256', 'ES256K', 'EdDSA', 'RS256', 'PS256'], - types: ['VerifiableCredential', 'VerifiableAttestation', 'Europass'], - }, - }, - }, - OpenBadgeCredential: { - display: [{ name: 'OpenBadgeCredential' }], - formats: { - ldp_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: [ - 'Ed25519Signature2018', - 'Ed25519Signature2020', - 'EcdsaSecp256k1Signature2019', - 'RsaSignature2018', - 'JsonWebSignature2020', - 'JcsEd25519Signature2020', - ], - types: ['VerifiableCredential', 'OpenBadgeCredential'], - }, - jwt_vc: { - cryptographic_binding_methods_supported: ['did'], - cryptographic_suites_supported: ['ES256', 'ES256K', 'EdDSA', 'RS256', 'PS256'], - types: ['VerifiableCredential', 'OpenBadgeCredential'], - }, - }, - }, - }, - credential_issuer: { display: [{ locale: null, name: 'https://jff.walt.id/issuer-api/default' }] }, - credential_endpoint: 'https://jff.walt.id/issuer-api/default/oidc/credential', - subject_types_supported: ['public'], - }, - - acquireAccessTokenResponse: { - access_token: '8bb45fb4-3475-49c2-85c7-0b91f687da44', - refresh_token: 'WEjORX8NZccRGtRN4yvXFdYE8MeAOaLLmmGlcRbutq4', - c_nonce: 'cbad6376-f882-44c5-ae88-19bccc0de124', - id_token: - 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiI4YmI0NWZiNC0zNDc1LTQ5YzItODVjNy0wYjkxZjY4N2RhNDQifQ.Mca0Ln1AvNlxBJftYc1PZKQBlGdBmrHsFRQSBDoCgD0', - token_type: 'Bearer', - expires_in: 300, - }, - - credentialResponse: { - credential: - 'eyJraWQiOiJkaWQ6andrOmV5SnJkSGtpT2lKUFMxQWlMQ0oxYzJVaU9pSnphV2NpTENKamNuWWlPaUpGWkRJMU5URTVJaXdpYTJsa0lqb2lOMlEyWTJKbU1qUTRPV0l6TkRJM05tSXhOekl4T1RBMU5EbGtNak01TVRnaUxDSjRJam9pUm01RlZWVmhkV1J0T1RsT016QmlPREJxY3poV2REUkJiazk0ZGxKM1dIUm5VbU5MY1ROblFrbDFPQ0lzSW1Gc1p5STZJa1ZrUkZOQkluMCMwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJpc3MiOiJkaWQ6andrOmV5SnJkSGtpT2lKUFMxQWlMQ0oxYzJVaU9pSnphV2NpTENKamNuWWlPaUpGWkRJMU5URTVJaXdpYTJsa0lqb2lOMlEyWTJKbU1qUTRPV0l6TkRJM05tSXhOekl4T1RBMU5EbGtNak01TVRnaUxDSjRJam9pUm01RlZWVmhkV1J0T1RsT016QmlPREJxY3poV2REUkJiazk0ZGxKM1dIUm5VbU5MY1ROblFrbDFPQ0lzSW1Gc1p5STZJa1ZrUkZOQkluMCIsInN1YiI6ImRpZDprZXk6ekRuYWVpcFdnOURNWFB0OWpjbUFCcWFZUlZLYzE5dFgxeGZCUldGc0pTUG9VZE1udiIsIm5iZiI6MTY4NTM1MDc4OSwiaWF0IjoxNjg1MzUwNzg5LCJ2YyI6eyJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVmVyaWZpYWJsZUF0dGVzdGF0aW9uIiwiVmVyaWZpYWJsZUlkIl0sIkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIl0sImlkIjoidXJuOnV1aWQ6NTljZTRhYzItZWM2NS00YjhmLThmOTYtZWE3ODUxMmRmOWQzIiwiaXNzdWVyIjoiZGlkOmp3azpleUpyZEhraU9pSlBTMUFpTENKMWMyVWlPaUp6YVdjaUxDSmpjbllpT2lKRlpESTFOVEU1SWl3aWEybGtJam9pTjJRMlkySm1NalE0T1dJek5ESTNObUl4TnpJeE9UQTFORGxrTWpNNU1UZ2lMQ0o0SWpvaVJtNUZWVlZoZFdSdE9UbE9NekJpT0RCcWN6aFdkRFJCYms5NGRsSjNXSFJuVW1OTGNUTm5Ra2wxT0NJc0ltRnNaeUk2SWtWa1JGTkJJbjAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA1LTI5VDA4OjU5OjQ5WiIsImlzc3VlZCI6IjIwMjMtMDUtMjlUMDg6NTk6NDlaIiwidmFsaWRGcm9tIjoiMjAyMy0wNS0yOVQwODo1OTo0OVoiLCJjcmVkZW50aWFsU2NoZW1hIjp7ImlkIjoiaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3dhbHQtaWQvd2FsdGlkLXNzaWtpdC12Y2xpYi9tYXN0ZXIvc3JjL3Rlc3QvcmVzb3VyY2VzL3NjaGVtYXMvVmVyaWZpYWJsZUlkLmpzb24iLCJ0eXBlIjoiRnVsbEpzb25TY2hlbWFWYWxpZGF0b3IyMDIxIn0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmtleTp6RG5hZWlwV2c5RE1YUHQ5amNtQUJxYVlSVktjMTl0WDF4ZkJSV0ZzSlNQb1VkTW52IiwiY3VycmVudEFkZHJlc3MiOlsiMSBCb3VsZXZhcmQgZGUgbGEgTGliZXJ0w6ksIDU5ODAwIExpbGxlIl0sImRhdGVPZkJpcnRoIjoiMTk5My0wNC0wOCIsImZhbWlseU5hbWUiOiJET0UiLCJmaXJzdE5hbWUiOiJKYW5lIiwiZ2VuZGVyIjoiRkVNQUxFIiwibmFtZUFuZEZhbWlseU5hbWVBdEJpcnRoIjoiSmFuZSBET0UiLCJwZXJzb25hbElkZW50aWZpZXIiOiIwOTA0MDA4MDg0SCIsInBsYWNlT2ZCaXJ0aCI6IkxJTExFLCBGUkFOQ0UifSwiZXZpZGVuY2UiOlt7ImRvY3VtZW50UHJlc2VuY2UiOlsiUGh5c2ljYWwiXSwiZXZpZGVuY2VEb2N1bWVudCI6WyJQYXNzcG9ydCJdLCJzdWJqZWN0UHJlc2VuY2UiOiJQaHlzaWNhbCIsInR5cGUiOlsiRG9jdW1lbnRWZXJpZmljYXRpb24iXSwidmVyaWZpZXIiOiJkaWQ6ZWJzaToyQTlCWjlTVWU2QmF0YWNTcHZzMVY1Q2RqSHZMcFE3YkVzaTJKYjZMZEhLblF4YU4ifV19LCJqdGkiOiJ1cm46dXVpZDo1OWNlNGFjMi1lYzY1LTRiOGYtOGY5Ni1lYTc4NTEyZGY5ZDMifQ.6Wn8X2tEQJ9CmX3-meCxDuGmevRdtivnjVkGPXzfnJ-1M6AU4SFxxon0JmMjdmO_h4P9sCEe9RTtyTJou2yeCA', - format: 'jwt_vc', - }, -} diff --git a/packages/openid4vc-client/tests/openid4vc-client.e2e.test.ts b/packages/openid4vc-client/tests/openid4vc-client.e2e.test.ts deleted file mode 100644 index b0a19263af..0000000000 --- a/packages/openid4vc-client/tests/openid4vc-client.e2e.test.ts +++ /dev/null @@ -1,299 +0,0 @@ -import type { KeyDidCreateOptions } from '@credo-ts/core' - -import { - ClaimFormat, - JwaSignatureAlgorithm, - Agent, - KeyType, - TypedArrayEncoder, - W3cCredentialRecord, - W3cCredentialsModule, - DidKey, -} from '@credo-ts/core' -import nock, { cleanAll, enableNetConnect } from 'nock' - -import { InMemoryWalletModule } from '../../../tests/InMemoryWalletModule' -import { customDocumentLoader } from '../../core/src/modules/vc/data-integrity/__tests__/documentLoader' -import { getInMemoryAgentOptions } from '../../core/tests' - -import { mattrLaunchpadJsonLd, waltIdJffJwt } from './fixtures' - -import { OpenId4VcClientModule } from '@credo-ts/openid4vc-client' - -const modules = { - openId4VcClient: new OpenId4VcClientModule(), - w3cCredentials: new W3cCredentialsModule({ - documentLoader: customDocumentLoader, - }), - inMemory: new InMemoryWalletModule(), -} - -describe('OpenId4VcClient', () => { - let agent: Agent - - beforeEach(async () => { - const agentOptions = getInMemoryAgentOptions('OpenId4VcClient Agent', {}, modules) - agent = new Agent(agentOptions) - await agent.initialize() - }) - - afterEach(async () => { - await agent.wallet.delete() - await agent.shutdown() - }) - - describe('Pre-authorized flow', () => { - afterEach(() => { - cleanAll() - enableNetConnect() - }) - - it('Should successfully execute the pre-authorized flow using a did:key Ed25519 subject and JSON-LD credential', async () => { - /** - * Below we're setting up some mock HTTP responses. - * These responses are based on the openid-initiate-issuance URI above - * */ - - // setup temporary redirect mock - nock('https://launchpad.mattrlabs.com').get('/.well-known/openid-credential-issuer').reply(307, undefined, { - Location: 'https://launchpad.vii.electron.mattrlabs.io/.well-known/openid-credential-issuer', - }) - - // setup server metadata response - const httpMock = nock('https://launchpad.vii.electron.mattrlabs.io') - .get('/.well-known/openid-credential-issuer') - .reply(200, mattrLaunchpadJsonLd.getMetadataResponse) - - // setup access token response - httpMock.post('/oidc/v1/auth/token').reply(200, mattrLaunchpadJsonLd.acquireAccessTokenResponse) - - // setup credential request response - httpMock.post('/oidc/v1/auth/credential').reply(200, mattrLaunchpadJsonLd.credentialResponse) - - const did = await agent.dids.create({ - method: 'key', - options: { - keyType: KeyType.Ed25519, - }, - secret: { - privateKey: TypedArrayEncoder.fromString('96213c3d7fc8d4d6754c7a0fd969598e'), - }, - }) - - const didKey = DidKey.fromDid(did.didState.did as string) - const kid = `${did.didState.did as string}#${didKey.key.fingerprint}` - const verificationMethod = did.didState.didDocument?.dereferenceKey(kid, ['authentication']) - if (!verificationMethod) throw new Error('No verification method found') - - const w3cCredentialRecords = await agent.modules.openId4VcClient.requestCredentialUsingPreAuthorizedCode({ - issuerUri: mattrLaunchpadJsonLd.credentialOffer, - verifyCredentialStatus: false, - // We only allow EdDSa, as we've created a did with keyType ed25519. If we create - // or determine the did dynamically we could use any signature algorithm - allowedProofOfPossessionSignatureAlgorithms: [JwaSignatureAlgorithm.EdDSA], - proofOfPossessionVerificationMethodResolver: () => verificationMethod, - }) - - expect(w3cCredentialRecords).toHaveLength(1) - const w3cCredentialRecord = w3cCredentialRecords[0] - expect(w3cCredentialRecord).toBeInstanceOf(W3cCredentialRecord) - - expect(w3cCredentialRecord.credential.type).toEqual([ - 'VerifiableCredential', - 'VerifiableCredentialExtension', - 'OpenBadgeCredential', - ]) - - expect(w3cCredentialRecord.credential.credentialSubjectIds[0]).toEqual(did.didState.did) - }) - - it('Should successfully execute the pre-authorized flow using a did:key P256 subject and JWT credential', async () => { - /** - * Below we're setting up some mock HTTP responses. - * These responses are based on the openid-initiate-issuance URI above - */ - // setup server metadata response - const httpMock = nock('https://jff.walt.id/issuer-api/default/oidc') - .get('/.well-known/openid-credential-issuer') - .reply(200, waltIdJffJwt.getMetadataResponse) - // setup access token response - httpMock.post('/token').reply(200, waltIdJffJwt.credentialResponse) - // setup credential request response - httpMock.post('/credential').reply(200, waltIdJffJwt.credentialResponse) - - const did = await agent.dids.create({ - method: 'key', - options: { - keyType: KeyType.P256, - }, - secret: { - privateKey: TypedArrayEncoder.fromString('96213c3d7fc8d4d6754c7a0fd969598e'), - }, - }) - - const didKey = DidKey.fromDid(did.didState.did as string) - const kid = `${didKey.did}#${didKey.key.fingerprint}` - const verificationMethod = did.didState.didDocument?.dereferenceKey(kid, ['authentication']) - if (!verificationMethod) throw new Error('No verification method found') - - const w3cCredentialRecords = await agent.modules.openId4VcClient.requestCredentialUsingPreAuthorizedCode({ - issuerUri: waltIdJffJwt.credentialOffer, - allowedCredentialFormats: [ClaimFormat.JwtVc], - allowedProofOfPossessionSignatureAlgorithms: [JwaSignatureAlgorithm.ES256], - proofOfPossessionVerificationMethodResolver: () => verificationMethod, - verifyCredentialStatus: false, - }) - - expect(w3cCredentialRecords[0]).toBeInstanceOf(W3cCredentialRecord) - const w3cCredentialRecord = w3cCredentialRecords[0] - - expect(w3cCredentialRecord.credential.type).toEqual([ - 'VerifiableCredential', - 'VerifiableAttestation', - 'VerifiableId', - ]) - - expect(w3cCredentialRecord.credential.credentialSubjectIds[0]).toEqual(did.didState.did) - }) - }) - - describe('Authorization flow', () => { - beforeAll(async () => { - /** - * Below we're setting up some mock HTTP responses. - * These responses are based on the openid-initiate-issuance URI above - * */ - - // setup temporary redirect mock - nock('https://launchpad.mattrlabs.com').get('/.well-known/openid-credential-issuer').reply(307, undefined, { - Location: 'https://launchpad.vii.electron.mattrlabs.io/.well-known/openid-credential-issuer', - }) - - // setup server metadata response - const httpMock = nock('https://launchpad.vii.electron.mattrlabs.io') - .get('/.well-known/openid-credential-issuer') - .reply(200, mattrLaunchpadJsonLd.getMetadataResponse) - - // setup access token response - httpMock.post('/oidc/v1/auth/token').reply(200, mattrLaunchpadJsonLd.acquireAccessTokenResponse) - - // setup credential request response - httpMock.post('/oidc/v1/auth/credential').reply(200, mattrLaunchpadJsonLd.credentialResponse) - }) - - afterAll(async () => { - cleanAll() - enableNetConnect() - }) - - it('should generate a valid authorization url', async () => { - const clientId = 'test-client' - - const redirectUri = 'https://example.com/cb' - const scope = ['TestCredential'] - const initiationUri = - 'openid-initiate-issuance://?issuer=https://launchpad.mattrlabs.com&credential_type=OpenBadgeCredential' - const { authorizationUrl } = await agent.modules.openId4VcClient.generateAuthorizationUrl({ - clientId, - redirectUri, - scope, - initiationUri, - }) - - const parsedUrl = new URL(authorizationUrl) - expect(authorizationUrl.startsWith('https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/authorize')).toBe( - true - ) - expect(parsedUrl.searchParams.get('response_type')).toBe('code') - expect(parsedUrl.searchParams.get('client_id')).toBe(clientId) - expect(parsedUrl.searchParams.get('code_challenge_method')).toBe('S256') - expect(parsedUrl.searchParams.get('redirect_uri')).toBe(redirectUri) - }) - it('should throw if no scope is provided', async () => { - // setup temporary redirect mock - nock('https://launchpad.mattrlabs.com').get('/.well-known/openid-credential-issuer').reply(307, undefined, { - Location: 'https://launchpad.vii.electron.mattrlabs.io/.well-known/openid-credential-issuer', - }) - - // setup server metadata response - nock('https://launchpad.vii.electron.mattrlabs.io') - .get('/.well-known/openid-credential-issuer') - .reply(200, mattrLaunchpadJsonLd.getMetadataResponse) - - const clientId = 'test-client' - const redirectUri = 'https://example.com/cb' - const initiationUri = - 'openid-initiate-issuance://?issuer=https://launchpad.mattrlabs.com&credential_type=OpenBadgeCredential' - expect( - agent.modules.openId4VcClient.generateAuthorizationUrl({ - clientId, - redirectUri, - scope: [], - initiationUri, - }) - ).rejects.toThrow() - }) - it('should successfully execute request a credential', async () => { - // setup temporary redirect mock - nock('https://launchpad.mattrlabs.com').get('/.well-known/openid-credential-issuer').reply(307, undefined, { - Location: 'https://launchpad.vii.electron.mattrlabs.io/.well-known/openid-credential-issuer', - }) - - // setup server metadata response - nock('https://launchpad.vii.electron.mattrlabs.io') - .get('/.well-known/openid-credential-issuer') - .reply(200, mattrLaunchpadJsonLd.getMetadataResponse) - - const did = await agent.dids.create({ - method: 'key', - options: { - keyType: KeyType.Ed25519, - }, - secret: { - privateKey: TypedArrayEncoder.fromString('96213c3d7fc8d4d6754c7a0fd969598e'), - }, - }) - - const didKey = DidKey.fromDid(did.didState.did as string) - const kid = `${did.didState.did as string}#${didKey.key.fingerprint}` - const verificationMethod = did.didState.didDocument?.dereferenceKey(kid, ['authentication']) - if (!verificationMethod) throw new Error('No verification method found') - - const clientId = 'test-client' - - const redirectUri = 'https://example.com/cb' - const initiationUri = - 'openid-initiate-issuance://?issuer=https://launchpad.mattrlabs.com&credential_type=OpenBadgeCredential' - - const scope = ['TestCredential'] - const { codeVerifier } = await agent.modules.openId4VcClient.generateAuthorizationUrl({ - clientId, - redirectUri, - scope, - initiationUri, - }) - const w3cCredentialRecords = await agent.modules.openId4VcClient.requestCredentialUsingAuthorizationCode({ - clientId: clientId, - authorizationCode: 'test-code', - codeVerifier: codeVerifier, - verifyCredentialStatus: false, - proofOfPossessionVerificationMethodResolver: () => verificationMethod, - allowedProofOfPossessionSignatureAlgorithms: [JwaSignatureAlgorithm.EdDSA], - issuerUri: initiationUri, - redirectUri: redirectUri, - }) - - expect(w3cCredentialRecords).toHaveLength(1) - const w3cCredentialRecord = w3cCredentialRecords[0] - expect(w3cCredentialRecord).toBeInstanceOf(W3cCredentialRecord) - - expect(w3cCredentialRecord.credential.type).toEqual([ - 'VerifiableCredential', - 'VerifiableCredentialExtension', - 'OpenBadgeCredential', - ]) - - expect(w3cCredentialRecord.credential.credentialSubjectIds[0]).toEqual(did.didState.did) - }) - }) -}) diff --git a/packages/openid4vc/README.md b/packages/openid4vc/README.md new file mode 100644 index 0000000000..5e6522a379 --- /dev/null +++ b/packages/openid4vc/README.md @@ -0,0 +1,31 @@ +

+
+ Credo Logo +

+

Credo OpenID4VC Module

+

+ License + typescript + @credo-ts/openid4vc version + +

+
+ +Open ID Connect For Verifiable Credentials Holder Module for [Credo](https://credo.js.org). diff --git a/packages/sd-jwt-vc/jest.config.ts b/packages/openid4vc/jest.config.ts similarity index 99% rename from packages/sd-jwt-vc/jest.config.ts rename to packages/openid4vc/jest.config.ts index 93c0197296..8641cf4d67 100644 --- a/packages/sd-jwt-vc/jest.config.ts +++ b/packages/openid4vc/jest.config.ts @@ -6,6 +6,7 @@ import packageJson from './package.json' const config: Config.InitialOptions = { ...base, + displayName: packageJson.name, setupFilesAfterEnv: ['./tests/setup.ts'], } diff --git a/packages/openid4vc-client/package.json b/packages/openid4vc/package.json similarity index 62% rename from packages/openid4vc-client/package.json rename to packages/openid4vc/package.json index f5f3053dc0..98a5f7f9a2 100644 --- a/packages/openid4vc-client/package.json +++ b/packages/openid4vc/package.json @@ -1,5 +1,5 @@ { - "name": "@credo-ts/openid4vc-client", + "name": "@credo-ts/openid4vc", "main": "build/index", "types": "build/index", "version": "0.4.2", @@ -10,11 +10,11 @@ "publishConfig": { "access": "public" }, - "homepage": "https://github.com/openwallet-foundation/credo-ts/tree/main/packages/openid4vc-client", + "homepage": "https://github.com/openwallet-foundation/credo-ts/tree/main/packages/openid4vc", "repository": { "type": "git", "url": "https://github.com/openwallet-foundation/credo-ts", - "directory": "packages/openid4vc-client" + "directory": "packages/openid4vc" }, "scripts": { "build": "yarn run clean && yarn run compile", @@ -25,11 +25,16 @@ }, "dependencies": { "@credo-ts/core": "0.4.2", - "@sphereon/openid4vci-client": "^0.4.0", - "@stablelib/random": "^1.0.2" + "@sphereon/ssi-types": "^0.18.1", + "@sphereon/oid4vci-client": "0.8.2-next.46", + "@sphereon/oid4vci-common": "0.8.2-next.46", + "@sphereon/oid4vci-issuer": "0.8.2-next.46", + "@sphereon/did-auth-siop": "0.6.0-unstable.3" }, "devDependencies": { - "@credo-ts/node": "0.4.2", + "@credo-ts/tenants": "0.4.2", + "@types/express": "^4.17.21", + "express": "^4.18.2", "nock": "^13.3.0", "rimraf": "^4.4.0", "typescript": "~4.9.5" diff --git a/packages/openid4vc/src/index.ts b/packages/openid4vc/src/index.ts new file mode 100644 index 0000000000..222f8329c6 --- /dev/null +++ b/packages/openid4vc/src/index.ts @@ -0,0 +1,4 @@ +export * from './openid4vc-holder' +export * from './openid4vc-verifier' +export * from './openid4vc-issuer' +export * from './shared' diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderApi.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderApi.ts new file mode 100644 index 0000000000..97789677fb --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderApi.ts @@ -0,0 +1,127 @@ +import type { + OpenId4VciResolvedCredentialOffer, + OpenId4VciResolvedAuthorizationRequest, + OpenId4VciAuthCodeFlowOptions, + OpenId4VciAcceptCredentialOfferOptions, +} from './OpenId4VciHolderServiceOptions' +import type { OpenId4VcSiopAcceptAuthorizationRequestOptions } from './OpenId4vcSiopHolderServiceOptions' + +import { injectable, AgentContext } from '@credo-ts/core' + +import { OpenId4VciHolderService } from './OpenId4VciHolderService' +import { OpenId4VcSiopHolderService } from './OpenId4vcSiopHolderService' + +/** + * @public + */ +@injectable() +export class OpenId4VcHolderApi { + public constructor( + private agentContext: AgentContext, + private openId4VciHolderService: OpenId4VciHolderService, + private openId4VcSiopHolderService: OpenId4VcSiopHolderService + ) {} + + /** + * Resolves the authentication request given as URI or JWT to a unified format, and + * verifies the validity of the request. + * + * The resolved request can be accepted with the @see acceptSiopAuthorizationRequest. + * + * If the authorization request uses OpenID4VP and included presentation definitions, + * a `presentationExchange` property will be defined with credentials that satisfy the + * incoming request. When `presentationExchange` is present, you MUST supply `presentationExchange` + * when calling `acceptSiopAuthorizationRequest` as well. + * + * @param requestJwtOrUri JWT or an SIOPv2 request URI + * @returns the resolved and verified authentication request. + */ + public async resolveSiopAuthorizationRequest(requestJwtOrUri: string) { + return this.openId4VcSiopHolderService.resolveAuthorizationRequest(this.agentContext, requestJwtOrUri) + } + + /** + * Accepts the authentication request after it has been resolved and verified with {@link resolveSiopAuthorizationRequest}. + * + * If the resolved authorization request included a `presentationExchange` property, you MUST supply `presentationExchange` + * in the `options` parameter. + * + * If no `presentationExchange` property is present, you MUST supply `openIdTokenIssuer` in the `options` parameter. + */ + public async acceptSiopAuthorizationRequest(options: OpenId4VcSiopAcceptAuthorizationRequestOptions) { + return await this.openId4VcSiopHolderService.acceptAuthorizationRequest(this.agentContext, options) + } + + /** + * Resolves a credential offer given as credential offer URL, or issuance initiation URL, + * into a unified format with metadata. + * + * @param credentialOffer the credential offer to resolve + * @returns The uniform credential offer payload, the issuer metadata, protocol version, and the offered credentials with metadata. + */ + public async resolveCredentialOffer(credentialOffer: string) { + return await this.openId4VciHolderService.resolveCredentialOffer(credentialOffer) + } + + /** + * This function is to be used to receive an credential in OpenID4VCI using the Authorization Code Flow. + * + * Not to be confused with the {@link resolveSiopAuthorizationRequest}, which is only used for SIOP requests. + * + * It will generate the authorization request URI based on the provided options. + * The authorization request URI is used to obtain the authorization code. Currently this needs to be done manually. + * + * Authorization to request credentials can be requested via authorization_details or scopes. + * This function automatically generates the authorization_details for all offered credentials. + * If scopes are provided, the provided scopes are sent alongside the authorization_details. + * + * @param resolvedCredentialOffer Obtained through @see resolveCredentialOffer + * @param authCodeFlowOptions + * @returns The authorization request URI alongside the code verifier and original @param authCodeFlowOptions + */ + public async resolveIssuanceAuthorizationRequest( + resolvedCredentialOffer: OpenId4VciResolvedCredentialOffer, + authCodeFlowOptions: OpenId4VciAuthCodeFlowOptions + ) { + return await this.openId4VciHolderService.resolveAuthorizationRequest( + this.agentContext, + resolvedCredentialOffer, + authCodeFlowOptions + ) + } + + /** + * Accepts a credential offer using the pre-authorized code flow. + * @param resolvedCredentialOffer Obtained through @see resolveCredentialOffer + * @param acceptCredentialOfferOptions + */ + public async acceptCredentialOfferUsingPreAuthorizedCode( + resolvedCredentialOffer: OpenId4VciResolvedCredentialOffer, + acceptCredentialOfferOptions: OpenId4VciAcceptCredentialOfferOptions + ) { + return this.openId4VciHolderService.acceptCredentialOffer(this.agentContext, { + resolvedCredentialOffer, + acceptCredentialOfferOptions, + }) + } + + /** + * Accepts a credential offer using the authorization code flow. + * @param resolvedCredentialOffer Obtained through @see resolveCredentialOffer + * @param resolvedAuthorizationRequest Obtained through @see resolveIssuanceAuthorizationRequest + * @param code The authorization code obtained via the authorization request URI + * @param acceptCredentialOfferOptions + */ + public async acceptCredentialOfferUsingAuthorizationCode( + resolvedCredentialOffer: OpenId4VciResolvedCredentialOffer, + resolvedAuthorizationRequest: OpenId4VciResolvedAuthorizationRequest, + code: string, + acceptCredentialOfferOptions: OpenId4VciAcceptCredentialOfferOptions + ) { + return this.openId4VciHolderService.acceptCredentialOffer(this.agentContext, { + resolvedCredentialOffer, + resolvedAuthorizationRequestWithCode: { ...resolvedAuthorizationRequest, code }, + acceptCredentialOfferOptions, + }) + } +} diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderModule.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderModule.ts new file mode 100644 index 0000000000..64cd6b9f08 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4VcHolderModule.ts @@ -0,0 +1,31 @@ +import type { DependencyManager, Module } from '@credo-ts/core' + +import { AgentConfig } from '@credo-ts/core' + +import { OpenId4VcHolderApi } from './OpenId4VcHolderApi' +import { OpenId4VciHolderService } from './OpenId4VciHolderService' +import { OpenId4VcSiopHolderService } from './OpenId4vcSiopHolderService' + +/** + * @public @module OpenId4VcHolderModule + * This module provides the functionality to assume the role of owner in relation to the OpenId4VC specification suite. + */ +export class OpenId4VcHolderModule implements Module { + public readonly api = OpenId4VcHolderApi + + /** + * Registers the dependencies of the question answer module on the dependency manager. + */ + public register(dependencyManager: DependencyManager) { + // Warn about experimental module + dependencyManager + .resolve(AgentConfig) + .logger.warn( + "The '@credo-ts/openid4vc' Holder module is experimental and could have unexpected breaking changes. When using this module, make sure to use strict versions for all @credo-ts packages." + ) + + // Services + dependencyManager.registerSingleton(OpenId4VciHolderService) + dependencyManager.registerSingleton(OpenId4VcSiopHolderService) + } +} diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderService.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderService.ts new file mode 100644 index 0000000000..fb1b9a100e --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderService.ts @@ -0,0 +1,708 @@ +import type { + OpenId4VciAuthCodeFlowOptions, + OpenId4VciAcceptCredentialOfferOptions, + OpenId4VciProofOfPossessionRequirements, + OpenId4VciCredentialBindingResolver, + OpenId4VciResolvedCredentialOffer, + OpenId4VciResolvedAuthorizationRequest, + OpenId4VciResolvedAuthorizationRequestWithCode, + OpenId4VciSupportedCredentialFormats, +} from './OpenId4VciHolderServiceOptions' +import type { + OpenId4VciCredentialOfferPayload, + OpenId4VciCredentialSupported, + OpenId4VciCredentialSupportedWithId, + OpenId4VciIssuerMetadata, +} from '../shared' +import type { AgentContext, JwaSignatureAlgorithm, Key, JwkJson, VerifiableCredential } from '@credo-ts/core' +import type { + AccessTokenResponse, + CredentialResponse, + Jwt, + OpenIDResponse, + PushedAuthorizationResponse, + AuthorizationDetails, + AuthorizationDetailsJwtVcJson, +} from '@sphereon/oid4vci-common' + +import { + SdJwtVcApi, + getJwkFromJson, + DidsApi, + CredoError, + Hasher, + InjectionSymbols, + JsonEncoder, + JwsService, + Logger, + SignatureSuiteRegistry, + TypedArrayEncoder, + W3cCredentialService, + W3cJsonLdVerifiableCredential, + W3cJwtVerifiableCredential, + getJwkClassFromJwaSignatureAlgorithm, + getJwkFromKey, + getKeyFromVerificationMethod, + getSupportedVerificationMethodTypesFromKeyType, + inject, + injectable, + parseDid, +} from '@credo-ts/core' +import { + AccessTokenClient, + CredentialRequestClientBuilder, + ProofOfPossessionBuilder, + formPost, + OpenID4VCIClient, +} from '@sphereon/oid4vci-client' +import { CodeChallengeMethod, ResponseType, convertJsonToURI, JsonURIMode } from '@sphereon/oid4vci-common' + +import { OpenId4VciCredentialFormatProfile } from '../shared' +import { + getTypesFromCredentialSupported, + handleAuthorizationDetails, + getOfferedCredentials, +} from '../shared/issuerMetadataUtils' +import { getSupportedJwaSignatureAlgorithms } from '../shared/utils' + +import { openId4VciSupportedCredentialFormats } from './OpenId4VciHolderServiceOptions' + +@injectable() +export class OpenId4VciHolderService { + private logger: Logger + private w3cCredentialService: W3cCredentialService + private jwsService: JwsService + + public constructor( + @inject(InjectionSymbols.Logger) logger: Logger, + w3cCredentialService: W3cCredentialService, + jwsService: JwsService + ) { + this.w3cCredentialService = w3cCredentialService + this.jwsService = jwsService + this.logger = logger + } + + public async resolveCredentialOffer(credentialOffer: string): Promise { + const client = await OpenID4VCIClient.fromURI({ + uri: credentialOffer, + resolveOfferUri: true, + retrieveServerMetadata: true, + }) + + if (!client.credentialOffer?.credential_offer) { + throw new CredoError(`Could not resolve credential offer from '${credentialOffer}'`) + } + const credentialOfferPayload: OpenId4VciCredentialOfferPayload = client.credentialOffer.credential_offer + + const metadata = await client.retrieveServerMetadata() + if (!metadata.credentialIssuerMetadata) { + throw new CredoError(`Could not retrieve issuer metadata from '${metadata.issuer}'`) + } + const issuerMetadata = metadata.credentialIssuerMetadata as OpenId4VciIssuerMetadata + + this.logger.info('Fetched server metadata', { + issuer: metadata.issuer, + credentialEndpoint: metadata.credential_endpoint, + tokenEndpoint: metadata.token_endpoint, + }) + + this.logger.debug('Full server metadata', metadata) + + return { + metadata: { + ...metadata, + credentialIssuerMetadata: issuerMetadata, + }, + credentialOfferPayload, + offeredCredentials: getOfferedCredentials( + credentialOfferPayload.credentials, + issuerMetadata.credentials_supported + ), + version: client.version(), + } + } + + private getAuthDetailsFromOfferedCredential( + offeredCredential: OpenId4VciCredentialSupported, + authDetailsLocation: string | undefined + ): AuthorizationDetails | undefined { + const { format } = offeredCredential + const type = 'openid_credential' + + const locations = authDetailsLocation ? [authDetailsLocation] : undefined + if (format === OpenId4VciCredentialFormatProfile.JwtVcJson) { + return { type, format, types: offeredCredential.types, locations } satisfies AuthorizationDetailsJwtVcJson + } else if ( + format === OpenId4VciCredentialFormatProfile.LdpVc || + format === OpenId4VciCredentialFormatProfile.JwtVcJsonLd + ) { + const credential_definition = { + '@context': offeredCredential['@context'], + credentialSubject: offeredCredential.credentialSubject, + types: offeredCredential.types, + } + + return { type, format, locations, credential_definition } + } else if (format === OpenId4VciCredentialFormatProfile.SdJwtVc) { + return { + type, + format, + locations, + vct: offeredCredential.vct, + claims: offeredCredential.claims, + } + } else { + throw new CredoError(`Cannot create authorization_details. Unsupported credential format '${format}'.`) + } + } + + public async resolveAuthorizationRequest( + agentContext: AgentContext, + resolvedCredentialOffer: OpenId4VciResolvedCredentialOffer, + authCodeFlowOptions: OpenId4VciAuthCodeFlowOptions + ): Promise { + const { credentialOfferPayload, metadata, offeredCredentials } = resolvedCredentialOffer + const codeVerifier = ( + await Promise.allSettled([agentContext.wallet.generateNonce(), agentContext.wallet.generateNonce()]) + ).join() + const codeVerifierSha256 = Hasher.hash(codeVerifier, 'sha-256') + const codeChallenge = TypedArrayEncoder.toBase64URL(codeVerifierSha256) + + this.logger.debug('Converted code_verifier to code_challenge', { + codeVerifier: codeVerifier, + sha256: codeVerifierSha256.toString(), + base64Url: codeChallenge, + }) + + const authDetailsLocation = metadata.credentialIssuerMetadata.authorization_server + ? metadata.credentialIssuerMetadata.authorization_server + : undefined + const authDetails = offeredCredentials + .map((credential) => this.getAuthDetailsFromOfferedCredential(credential, authDetailsLocation)) + .filter((authDetail): authDetail is AuthorizationDetails => authDetail !== undefined) + + const { clientId, redirectUri, scope } = authCodeFlowOptions + const authorizationRequestUri = await createAuthorizationRequestUri({ + clientId, + codeChallenge, + redirectUri, + credentialOffer: credentialOfferPayload, + codeChallengeMethod: CodeChallengeMethod.SHA256, + // TODO: Read HAIP SdJwtVc's should always be requested via scopes + // TODO: should we now always use scopes instead of authDetails? or both???? + scope: scope ?? [], + authDetails, + metadata, + }) + + return { + ...authCodeFlowOptions, + codeVerifier, + authorizationRequestUri, + } + } + + public async acceptCredentialOffer( + agentContext: AgentContext, + options: { + resolvedCredentialOffer: OpenId4VciResolvedCredentialOffer + acceptCredentialOfferOptions: OpenId4VciAcceptCredentialOfferOptions + resolvedAuthorizationRequestWithCode?: OpenId4VciResolvedAuthorizationRequestWithCode + } + ) { + const { resolvedCredentialOffer, acceptCredentialOfferOptions, resolvedAuthorizationRequestWithCode } = options + const { credentialOfferPayload, metadata, version, offeredCredentials } = resolvedCredentialOffer + + const { credentialsToRequest, userPin, credentialBindingResolver, verifyCredentialStatus } = + acceptCredentialOfferOptions + + if (credentialsToRequest?.length === 0) { + this.logger.warn(`Accepting 0 credential offers. Returning`) + return [] + } + + this.logger.info(`Accepting the following credential offers '${credentialsToRequest}'`) + + const supportedJwaSignatureAlgorithms = getSupportedJwaSignatureAlgorithms(agentContext) + + const allowedProofOfPossessionSigAlgs = acceptCredentialOfferOptions.allowedProofOfPossessionSignatureAlgorithms + const possibleProofOfPossessionSigAlgs = allowedProofOfPossessionSigAlgs + ? allowedProofOfPossessionSigAlgs.filter((algorithm) => supportedJwaSignatureAlgorithms.includes(algorithm)) + : supportedJwaSignatureAlgorithms + + if (possibleProofOfPossessionSigAlgs.length === 0) { + throw new CredoError( + [ + `No possible proof of possession signature algorithm found.`, + `Signature algorithms supported by the Agent '${supportedJwaSignatureAlgorithms.join(', ')}'`, + `Allowed Signature algorithms '${allowedProofOfPossessionSigAlgs?.join(', ')}'`, + ].join('\n') + ) + } + + // acquire the access token + let accessTokenResponse: OpenIDResponse + + const accessTokenClient = new AccessTokenClient() + if (resolvedAuthorizationRequestWithCode) { + const { code, codeVerifier, redirectUri } = resolvedAuthorizationRequestWithCode + accessTokenResponse = await accessTokenClient.acquireAccessToken({ + metadata: metadata, + credentialOffer: { credential_offer: credentialOfferPayload }, + pin: userPin, + code, + codeVerifier, + redirectUri, + }) + } else { + accessTokenResponse = await accessTokenClient.acquireAccessToken({ + metadata: metadata, + credentialOffer: { credential_offer: credentialOfferPayload }, + pin: userPin, + }) + } + + if (!accessTokenResponse.successBody) { + throw new CredoError( + `could not acquire access token from '${metadata.issuer}'. ${accessTokenResponse.errorBody?.error}: ${accessTokenResponse.errorBody?.error_description}` + ) + } + + this.logger.debug('Requested OpenId4VCI Access Token.') + + const accessToken = accessTokenResponse.successBody + const receivedCredentials: Array = [] + let newCNonce: string | undefined + + const credentialsSupportedToRequest = + credentialsToRequest + ?.map((id) => offeredCredentials.find((credential) => credential.id === id)) + .filter((c, i): c is OpenId4VciCredentialSupportedWithId => { + if (!c) { + const offeredCredentialIds = offeredCredentials.map((c) => c.id).join(', ') + throw new CredoError( + `Credential to request '${credentialsToRequest[i]}' is not present in offered credentials. Offered credentials are ${offeredCredentialIds}` + ) + } + + return true + }) ?? offeredCredentials + + for (const offeredCredential of credentialsSupportedToRequest) { + // Get all options for the credential request (such as which kid to use, the signature algorithm, etc) + const { credentialBinding, signatureAlgorithm } = await this.getCredentialRequestOptions(agentContext, { + possibleProofOfPossessionSignatureAlgorithms: possibleProofOfPossessionSigAlgs, + offeredCredential, + credentialBindingResolver, + }) + + // Create the proof of possession + const proofOfPossessionBuilder = ProofOfPossessionBuilder.fromAccessTokenResponse({ + accessTokenResponse: accessToken, + callbacks: { signCallback: this.proofOfPossessionSignCallback(agentContext) }, + version, + }) + .withEndpointMetadata(metadata) + .withAlg(signatureAlgorithm) + + if (credentialBinding.method === 'did') { + proofOfPossessionBuilder.withClientId(parseDid(credentialBinding.didUrl).did).withKid(credentialBinding.didUrl) + } else if (credentialBinding.method === 'jwk') { + proofOfPossessionBuilder.withJWK(credentialBinding.jwk.toJson()) + } + + if (newCNonce) proofOfPossessionBuilder.withAccessTokenNonce(newCNonce) + + const proofOfPossession = await proofOfPossessionBuilder.build() + this.logger.debug('Generated JWS', proofOfPossession) + + // Acquire the credential + const credentialRequestBuilder = new CredentialRequestClientBuilder() + credentialRequestBuilder + .withVersion(version) + .withCredentialEndpoint(metadata.credential_endpoint) + .withTokenFromResponse(accessToken) + + const credentialRequestClient = credentialRequestBuilder.build() + const credentialResponse = await credentialRequestClient.acquireCredentialsUsingProof({ + proofInput: proofOfPossession, + credentialTypes: getTypesFromCredentialSupported(offeredCredential), + format: offeredCredential.format, + }) + + newCNonce = credentialResponse.successBody?.c_nonce + + // Create credential, but we don't store it yet (only after the user has accepted the credential) + const credential = await this.handleCredentialResponse(agentContext, credentialResponse, { + verifyCredentialStatus: verifyCredentialStatus ?? false, + }) + + this.logger.debug('Full credential', credential) + receivedCredentials.push(credential) + } + + return receivedCredentials + } + + /** + * Get the options for the credential request. Internally this will resolve the proof of possession + * requirements, and based on that it will call the proofOfPossessionVerificationMethodResolver to + * allow the caller to select the correct verification method based on the requirements for the proof + * of possession. + */ + private async getCredentialRequestOptions( + agentContext: AgentContext, + options: { + credentialBindingResolver: OpenId4VciCredentialBindingResolver + possibleProofOfPossessionSignatureAlgorithms: JwaSignatureAlgorithm[] + offeredCredential: OpenId4VciCredentialSupportedWithId + } + ) { + const { signatureAlgorithm, supportedDidMethods, supportsAllDidMethods, supportsJwk } = + this.getProofOfPossessionRequirements(agentContext, { + credentialToRequest: options.offeredCredential, + possibleProofOfPossessionSignatureAlgorithms: options.possibleProofOfPossessionSignatureAlgorithms, + }) + + const JwkClass = getJwkClassFromJwaSignatureAlgorithm(signatureAlgorithm) + if (!JwkClass) { + throw new CredoError(`Could not determine JWK key type of the JWA signature algorithm '${signatureAlgorithm}'`) + } + + const supportedVerificationMethods = getSupportedVerificationMethodTypesFromKeyType(JwkClass.keyType) + + const format = options.offeredCredential.format as OpenId4VciSupportedCredentialFormats + + // Now we need to determine how the credential will be bound to us + const credentialBinding = await options.credentialBindingResolver({ + credentialFormat: format, + signatureAlgorithm, + supportedVerificationMethods, + keyType: JwkClass.keyType, + supportedCredentialId: options.offeredCredential.id, + supportsAllDidMethods, + supportedDidMethods, + supportsJwk, + }) + + // Make sure the issuer of proof of possession is valid according to openid issuer metadata + if ( + credentialBinding.method === 'did' && + !supportsAllDidMethods && + // If supportedDidMethods is undefined, it means the issuer didn't include the binding methods in the metadata + // The user can still select a verification method, but we can't validate it + supportedDidMethods !== undefined && + !supportedDidMethods.find((supportedDidMethod) => credentialBinding.didUrl.startsWith(supportedDidMethod)) + ) { + const { method } = parseDid(credentialBinding.didUrl) + const supportedDidMethodsString = supportedDidMethods.join(', ') + throw new CredoError( + `Resolved credential binding for proof of possession uses did method '${method}', but issuer only supports '${supportedDidMethodsString}'` + ) + } else if (credentialBinding.method === 'jwk' && !supportsJwk) { + throw new CredoError( + `Resolved credential binding for proof of possession uses jwk, but openid issuer does not support 'jwk' cryptographic binding method` + ) + } + + // FIXME: we don't have the verification method here + // Make sure the verification method uses a supported verification method type + // if (!supportedVerificationMethods.includes(verificationMethod.type)) { + // const supportedVerificationMethodsString = supportedVerificationMethods.join(', ') + // throw new CredoError( + // `Verification method uses verification method type '${verificationMethod.type}', but only '${supportedVerificationMethodsString}' verification methods are supported for key type '${JwkClass.keyType}'` + // ) + // } + + return { credentialBinding, signatureAlgorithm } + } + + /** + * Get the requirements for creating the proof of possession. Based on the allowed + * credential formats, the allowed proof of possession signature algorithms, and the + * credential type, this method will select the best credential format and signature + * algorithm to use, based on the order of preference. + */ + private getProofOfPossessionRequirements( + agentContext: AgentContext, + options: { + credentialToRequest: OpenId4VciCredentialSupportedWithId + possibleProofOfPossessionSignatureAlgorithms: JwaSignatureAlgorithm[] + } + ): OpenId4VciProofOfPossessionRequirements { + const { credentialToRequest } = options + + if ( + !openId4VciSupportedCredentialFormats.includes(credentialToRequest.format as OpenId4VciSupportedCredentialFormats) + ) { + throw new CredoError( + [ + `Requested credential with format '${credentialToRequest.format}',`, + `for the credential with id '${credentialToRequest.id},`, + `but the wallet only supports the following formats '${openId4VciSupportedCredentialFormats.join(', ')}'`, + ].join('\n') + ) + } + + // For each of the supported algs, find the key types, then find the proof types + const signatureSuiteRegistry = agentContext.dependencyManager.resolve(SignatureSuiteRegistry) + + let signatureAlgorithm: JwaSignatureAlgorithm | undefined + + const issuerSupportedCryptographicSuites = credentialToRequest.cryptographic_suites_supported + const issuerSupportedBindingMethods = credentialToRequest.cryptographic_binding_methods_supported + + // If undefined, it means the issuer didn't include the cryptographic suites in the metadata + // We just guess that the first one is supported + if (issuerSupportedCryptographicSuites === undefined) { + signatureAlgorithm = options.possibleProofOfPossessionSignatureAlgorithms[0] + } else { + switch (credentialToRequest.format) { + case OpenId4VciCredentialFormatProfile.JwtVcJson: + case OpenId4VciCredentialFormatProfile.JwtVcJsonLd: + case OpenId4VciCredentialFormatProfile.SdJwtVc: + signatureAlgorithm = options.possibleProofOfPossessionSignatureAlgorithms.find((signatureAlgorithm) => + issuerSupportedCryptographicSuites.includes(signatureAlgorithm) + ) + break + case OpenId4VciCredentialFormatProfile.LdpVc: + signatureAlgorithm = options.possibleProofOfPossessionSignatureAlgorithms.find((signatureAlgorithm) => { + const JwkClass = getJwkClassFromJwaSignatureAlgorithm(signatureAlgorithm) + if (!JwkClass) return false + + const matchingSuite = signatureSuiteRegistry.getAllByKeyType(JwkClass.keyType) + if (matchingSuite.length === 0) return false + + return issuerSupportedCryptographicSuites.includes(matchingSuite[0].proofType) + }) + break + default: + throw new CredoError(`Unsupported credential format.`) + } + } + + if (!signatureAlgorithm) { + throw new CredoError( + `Could not establish signature algorithm for format ${credentialToRequest.format} and id ${credentialToRequest.id}` + ) + } + + const supportsAllDidMethods = issuerSupportedBindingMethods?.includes('did') ?? false + const supportedDidMethods = issuerSupportedBindingMethods?.filter((method) => method.startsWith('did:')) + const supportsJwk = issuerSupportedBindingMethods?.includes('jwk') ?? false + + return { + signatureAlgorithm, + supportedDidMethods, + supportsAllDidMethods, + supportsJwk, + } + } + + private async handleCredentialResponse( + agentContext: AgentContext, + credentialResponse: OpenIDResponse, + options: { verifyCredentialStatus: boolean } + ): Promise { + const { verifyCredentialStatus } = options + this.logger.debug('Credential request response', credentialResponse) + + if (!credentialResponse.successBody || !credentialResponse.successBody.credential) { + throw new CredoError( + `Did not receive a successful credential response. ${credentialResponse.errorBody?.error}: ${credentialResponse.errorBody?.error_description}` + ) + } + + const format = credentialResponse.successBody.format + if (format === OpenId4VciCredentialFormatProfile.SdJwtVc) { + if (typeof credentialResponse.successBody.credential !== 'string') + throw new CredoError( + `Received a credential of format ${ + OpenId4VciCredentialFormatProfile.SdJwtVc + }, but the credential is not a string. ${JSON.stringify(credentialResponse.successBody.credential)}` + ) + + const sdJwtVcApi = agentContext.dependencyManager.resolve(SdJwtVcApi) + const { verification, sdJwtVc } = await sdJwtVcApi.verify({ + compactSdJwtVc: credentialResponse.successBody.credential, + }) + + if (!verification.isValid) { + agentContext.config.logger.error('Failed to validate credential', { verification }) + throw new CredoError(`Failed to validate sd-jwt-vc credential. Results = ${JSON.stringify(verification)}`) + } + + return sdJwtVc + } else if ( + format === OpenId4VciCredentialFormatProfile.JwtVcJson || + format === OpenId4VciCredentialFormatProfile.JwtVcJsonLd + ) { + const credential = W3cJwtVerifiableCredential.fromSerializedJwt( + credentialResponse.successBody.credential as string + ) + const result = await this.w3cCredentialService.verifyCredential(agentContext, { + credential, + verifyCredentialStatus, + }) + if (!result.isValid) { + agentContext.config.logger.error('Failed to validate credential', { result }) + throw new CredoError(`Failed to validate credential, error = ${result.error?.message ?? 'Unknown'}`) + } + + return credential + } else if (format === OpenId4VciCredentialFormatProfile.LdpVc) { + const credential = W3cJsonLdVerifiableCredential.fromJson( + credentialResponse.successBody.credential as Record + ) + const result = await this.w3cCredentialService.verifyCredential(agentContext, { + credential, + verifyCredentialStatus, + }) + if (!result.isValid) { + agentContext.config.logger.error('Failed to validate credential', { result }) + throw new CredoError(`Failed to validate credential, error = ${result.error?.message ?? 'Unknown'}`) + } + + return credential + } + + throw new CredoError(`Unsupported credential format ${credentialResponse.successBody.format}`) + } + + private proofOfPossessionSignCallback(agentContext: AgentContext) { + return async (jwt: Jwt, kid?: string) => { + if (!jwt.header) throw new CredoError('No header present on JWT') + if (!jwt.payload) throw new CredoError('No payload present on JWT') + if (kid && jwt.header.jwk) { + throw new CredoError('Both KID and JWK are present in the callback. Only one can be present') + } + + let key: Key + + if (kid) { + if (!kid.startsWith('did:')) { + throw new CredoError(`kid '${kid}' is not a DID. Only dids are supported for kid`) + } else if (!kid.includes('#')) { + throw new CredoError( + `kid '${kid}' does not contain a fragment. kid MUST point to a specific key in the did document.` + ) + } + + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const didDocument = await didsApi.resolveDidDocument(kid) + const verificationMethod = didDocument.dereferenceKey(kid, ['authentication']) + + key = getKeyFromVerificationMethod(verificationMethod) + } else if (jwt.header.jwk) { + key = getJwkFromJson(jwt.header.jwk as JwkJson).key + } else { + throw new CredoError('No KID or JWK is present in the callback') + } + + const jwk = getJwkFromKey(key) + if (!jwk.supportsSignatureAlgorithm(jwt.header.alg)) { + throw new CredoError(`key type '${jwk.keyType}', does not support the JWS signature alg '${jwt.header.alg}'`) + } + + // We don't support these properties, remove them, so we can pass all other header properties to the JWS service + if (jwt.header.x5c) throw new CredoError('x5c is not supported') + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { x5c: _x5c, ...supportedHeaderOptions } = jwt.header + + const jws = await this.jwsService.createJwsCompact(agentContext, { + key, + payload: JsonEncoder.toBuffer(jwt.payload), + protectedHeaderOptions: { + ...supportedHeaderOptions, + // only pass jwk if it was present in the header + jwk: jwt.header.jwk ? jwk : undefined, + }, + }) + + return jws + } + } +} + +// NOTE: this is also defined in the sphereon lib, but we use +// this custom method to get PAR working and because we don't +// use the oid4vci client in sphereon's lib +// Once PAR is supported in the sphereon lib, we should to try remove this +// and use the one from the sphereon lib +async function createAuthorizationRequestUri(options: { + credentialOffer: OpenId4VciCredentialOfferPayload + metadata: OpenId4VciResolvedCredentialOffer['metadata'] + clientId: string + codeChallenge: string + codeChallengeMethod: CodeChallengeMethod + authDetails?: AuthorizationDetails | AuthorizationDetails[] + redirectUri: string + scope?: string[] +}) { + const { scope, authDetails, metadata, clientId, codeChallenge, codeChallengeMethod, redirectUri } = options + let nonEmptyScope = !scope || scope.length === 0 ? undefined : scope + const nonEmptyAuthDetails = !authDetails || authDetails.length === 0 ? undefined : authDetails + + // Scope and authorization_details can be used in the same authorization request + // https://datatracker.ietf.org/doc/html/draft-ietf-oauth-rar-23#name-relationship-to-scope-param + if (!nonEmptyScope && !nonEmptyAuthDetails) { + throw new CredoError(`Please provide a 'scope' or 'authDetails' via the options.`) + } + + // Authorization servers supporting PAR SHOULD include the URL of their pushed authorization request endpoint in their authorization server metadata document + // Note that the presence of pushed_authorization_request_endpoint is sufficient for a client to determine that it may use the PAR flow. + const parEndpoint = metadata.credentialIssuerMetadata.pushed_authorization_request_endpoint + + const authorizationEndpoint = metadata.credentialIssuerMetadata?.authorization_endpoint + + if (!authorizationEndpoint && !parEndpoint) { + throw new CredoError( + "Server metadata does not contain an 'authorization_endpoint' which is required for the 'Authorization Code Flow'" + ) + } + + // add 'openid' scope if not present + if (nonEmptyScope && !nonEmptyScope?.includes('openid')) { + nonEmptyScope = ['openid', ...nonEmptyScope] + } + + const queryObj: Record = { + client_id: clientId, + response_type: ResponseType.AUTH_CODE, + code_challenge_method: codeChallengeMethod, + code_challenge: codeChallenge, + redirect_uri: redirectUri, + } + + if (nonEmptyScope) queryObj['scope'] = nonEmptyScope.join(' ') + + if (nonEmptyAuthDetails) + queryObj['authorization_details'] = JSON.stringify(handleAuthorizationDetails(nonEmptyAuthDetails, metadata)) + + const issuerState = options.credentialOffer.grants?.authorization_code?.issuer_state + if (issuerState) queryObj['issuer_state'] = issuerState + + if (parEndpoint) { + const body = new URLSearchParams(queryObj) + const response = await formPost(parEndpoint, body) + if (!response.successBody) { + throw new CredoError(`Could not acquire the authorization request uri from '${parEndpoint}'`) + } + return convertJsonToURI( + { request_uri: response.successBody.request_uri, client_id: clientId, response_type: ResponseType.AUTH_CODE }, + { + baseUrl: authorizationEndpoint, + uriTypeProperties: ['request_uri', 'client_id', 'response_type'], + mode: JsonURIMode.X_FORM_WWW_URLENCODED, + } + ) + } else { + return convertJsonToURI(queryObj, { + baseUrl: authorizationEndpoint, + uriTypeProperties: ['redirect_uri', 'scope', 'authorization_details', 'issuer_state'], + mode: JsonURIMode.X_FORM_WWW_URLENCODED, + }) + } +} diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderServiceOptions.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderServiceOptions.ts new file mode 100644 index 0000000000..129040fd8b --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4VciHolderServiceOptions.ts @@ -0,0 +1,191 @@ +import type { + OpenId4VcCredentialHolderBinding, + OpenId4VciCredentialOfferPayload, + OpenId4VciCredentialSupportedWithId, + OpenId4VciIssuerMetadata, +} from '../shared' +import type { JwaSignatureAlgorithm, KeyType } from '@credo-ts/core' +import type { AuthorizationServerMetadata, EndpointMetadataResult, OpenId4VCIVersion } from '@sphereon/oid4vci-common' + +import { OpenId4VciCredentialFormatProfile } from '../shared/models/OpenId4VciCredentialFormatProfile' + +export type OpenId4VciSupportedCredentialFormats = + | OpenId4VciCredentialFormatProfile.JwtVcJson + | OpenId4VciCredentialFormatProfile.JwtVcJsonLd + | OpenId4VciCredentialFormatProfile.SdJwtVc + | OpenId4VciCredentialFormatProfile.LdpVc + +export const openId4VciSupportedCredentialFormats: OpenId4VciSupportedCredentialFormats[] = [ + OpenId4VciCredentialFormatProfile.JwtVcJson, + OpenId4VciCredentialFormatProfile.JwtVcJsonLd, + OpenId4VciCredentialFormatProfile.SdJwtVc, + OpenId4VciCredentialFormatProfile.LdpVc, +] + +export interface OpenId4VciResolvedCredentialOffer { + metadata: EndpointMetadataResult & { + credentialIssuerMetadata: Partial & OpenId4VciIssuerMetadata + } + credentialOfferPayload: OpenId4VciCredentialOfferPayload + offeredCredentials: OpenId4VciCredentialSupportedWithId[] + version: OpenId4VCIVersion +} + +export interface OpenId4VciResolvedAuthorizationRequest extends OpenId4VciAuthCodeFlowOptions { + codeVerifier: string + authorizationRequestUri: string +} + +export interface OpenId4VciResolvedAuthorizationRequestWithCode extends OpenId4VciResolvedAuthorizationRequest { + code: string +} + +/** + * Options that are used to accept a credential offer for both the pre-authorized code flow and authorization code flow. + */ +export interface OpenId4VciAcceptCredentialOfferOptions { + /** + * String value containing a user PIN. This value MUST be present if user_pin_required was set to true in the Credential Offer. + * This parameter MUST only be used, if the grant_type is urn:ietf:params:oauth:grant-type:pre-authorized_code. + */ + userPin?: string + + /** + * This is the list of credentials that will be requested from the issuer. + * Should be a list of ids of the credentials that are included in the credential offer. + * If not provided all offered credentials will be requested. + */ + credentialsToRequest?: string[] + + verifyCredentialStatus?: boolean + + /** + * A list of allowed proof of possession signature algorithms in order of preference. + * + * Note that the signature algorithms must be supported by the wallet implementation. + * Signature algorithms that are not supported by the wallet will be ignored. + * + * The proof of possession (pop) signature algorithm is used in the credential request + * to bind the credential to a did. In most cases the JWA signature algorithm + * that is used in the pop will determine the cryptographic suite that is used + * for signing the credential, but this not a requirement for the spec. E.g. if the + * pop uses EdDsa, the credential will most commonly also use EdDsa, or Ed25519Signature2018/2020. + */ + allowedProofOfPossessionSignatureAlgorithms?: JwaSignatureAlgorithm[] + + /** + * A function that should resolve key material for binding the to-be-issued credential + * to the holder based on the options passed. This key material will be used for signing + * the proof of possession included in the credential request. + * + * This method will be called once for each of the credentials that are included + * in the credential offer. + * + * Based on the credential format, JWA signature algorithm, verification method types + * and binding methods (did methods, jwk), the resolver must return an object + * conformant to the `CredentialHolderBinding` interface, which will be used + * for the proof of possession signature. + */ + credentialBindingResolver: OpenId4VciCredentialBindingResolver +} + +/** + * Options that are used for the authorization code flow. + * Extends the pre-authorized code flow options. + */ +export interface OpenId4VciAuthCodeFlowOptions { + clientId: string + redirectUri: string + scope?: string[] +} + +export interface OpenId4VciCredentialBindingOptions { + /** + * The credential format that will be requested from the issuer. + * E.g. `jwt_vc` or `ldp_vc`. + */ + credentialFormat: OpenId4VciSupportedCredentialFormats + + /** + * The JWA Signature Algorithm that will be used in the proof of possession. + * This is based on the `allowedProofOfPossessionSignatureAlgorithms` passed + * to the request credential method, and the supported signature algorithms. + */ + signatureAlgorithm: JwaSignatureAlgorithm + + /** + * This is a list of verification methods types that are supported + * for creating the proof of possession signature. The returned + * verification method type must be of one of these types. + */ + supportedVerificationMethods: string[] + + /** + * The key type that will be used to create the proof of possession signature. + * This is related to the verification method and the signature algorithm, and + * is added for convenience. + */ + keyType: KeyType + + /** + * The credential type that will be requested from the issuer. This is + * based on the credential types that are included the credential offer. + * + * If the offered credential is an inline credential offer, the value + * will be `undefined`. + */ + supportedCredentialId?: string + + /** + * Whether the issuer supports the `did` cryptographic binding method, + * indicating they support all did methods. In most cases, they do not + * support all did methods, and it means we have to make an assumption + * about the did methods they support. + * + * If this value is `false`, the `supportedDidMethods` property will + * contain a list of supported did methods. + */ + supportsAllDidMethods: boolean + + /** + * A list of supported did methods. This is only used if the `supportsAllDidMethods` + * property is `false`. When this array is populated, the returned verification method + * MUST be based on one of these did methods. + * + * The did methods are returned in the format `did:`, e.g. `did:web`. + * + * The value is undefined in the case the supported did methods could not be extracted. + * This is the case when an inline credential was used, or when the issuer didn't include + * the supported did methods in the issuer metadata. + * + * NOTE: an empty array (no did methods supported) has a different meaning from the value + * being undefined (the supported did methods could not be extracted). If `supportsAllDidMethods` + * is true, the value of this property MUST be ignored. + */ + supportedDidMethods?: string[] + + /** + * Whether the issuer supports the `jwk` cryptographic binding method, + * indicating they support proof of possession signatures bound to a jwk. + */ + supportsJwk: boolean +} + +/** + * The proof of possession verification method resolver is a function that can be passed by the + * user of the framework and allows them to determine which verification method should be used + * for the proof of possession signature. + */ +export type OpenId4VciCredentialBindingResolver = ( + options: OpenId4VciCredentialBindingOptions +) => Promise | OpenId4VcCredentialHolderBinding + +/** + * @internal + */ +export interface OpenId4VciProofOfPossessionRequirements { + signatureAlgorithm: JwaSignatureAlgorithm + supportedDidMethods?: string[] + supportsAllDidMethods: boolean + supportsJwk: boolean +} diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderService.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderService.ts new file mode 100644 index 0000000000..a415aad3b0 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderService.ts @@ -0,0 +1,309 @@ +import type { + OpenId4VcSiopAcceptAuthorizationRequestOptions, + OpenId4VcSiopResolvedAuthorizationRequest, +} from './OpenId4vcSiopHolderServiceOptions' +import type { OpenId4VcJwtIssuer } from '../shared' +import type { AgentContext, VerifiablePresentation } from '@credo-ts/core' +import type { VerifiedAuthorizationRequest, PresentationExchangeResponseOpts } from '@sphereon/did-auth-siop' + +import { + Hasher, + W3cJwtVerifiablePresentation, + parseDid, + CredoError, + DidsApi, + injectable, + W3cJsonLdVerifiablePresentation, + asArray, + DifPresentationExchangeService, + DifPresentationExchangeSubmissionLocation, +} from '@credo-ts/core' +import { + CheckLinkedDomain, + OP, + ResponseIss, + ResponseMode, + SupportedVersion, + VPTokenLocation, + VerificationMode, +} from '@sphereon/did-auth-siop' + +import { getSphereonVerifiablePresentation } from '../shared/transform' +import { getSphereonDidResolver, getSphereonSuppliedSignatureFromJwtIssuer } from '../shared/utils' + +@injectable() +export class OpenId4VcSiopHolderService { + public constructor(private presentationExchangeService: DifPresentationExchangeService) {} + + public async resolveAuthorizationRequest( + agentContext: AgentContext, + requestJwtOrUri: string + ): Promise { + const openidProvider = await this.getOpenIdProvider(agentContext, {}) + + // parsing happens automatically in verifyAuthorizationRequest + const verifiedAuthorizationRequest = await openidProvider.verifyAuthorizationRequest(requestJwtOrUri, { + verification: { + // FIXME: we want custom verification, but not supported currently + // https://github.com/Sphereon-Opensource/SIOP-OID4VP/issues/55 + mode: VerificationMode.INTERNAL, + resolveOpts: { resolver: getSphereonDidResolver(agentContext), noUniversalResolverFallback: true }, + }, + }) + + agentContext.config.logger.debug( + `verified SIOP Authorization Request for issuer '${verifiedAuthorizationRequest.issuer}'` + ) + agentContext.config.logger.debug(`requestJwtOrUri '${requestJwtOrUri}'`) + + if ( + verifiedAuthorizationRequest.presentationDefinitions && + verifiedAuthorizationRequest.presentationDefinitions.length > 1 + ) { + throw new CredoError('Only a single presentation definition is supported.') + } + + const presentationDefinition = verifiedAuthorizationRequest.presentationDefinitions?.[0]?.definition + + return { + authorizationRequest: verifiedAuthorizationRequest, + + // Parameters related to DIF Presentation Exchange + presentationExchange: presentationDefinition + ? { + definition: presentationDefinition, + credentialsForRequest: await this.presentationExchangeService.getCredentialsForRequest( + agentContext, + presentationDefinition + ), + } + : undefined, + } + } + + public async acceptAuthorizationRequest( + agentContext: AgentContext, + options: OpenId4VcSiopAcceptAuthorizationRequestOptions + ) { + const { authorizationRequest, presentationExchange } = options + let openIdTokenIssuer = options.openIdTokenIssuer + let presentationExchangeOptions: PresentationExchangeResponseOpts | undefined = undefined + + // Handle presentation exchange part + if (authorizationRequest.presentationDefinitions && authorizationRequest.presentationDefinitions.length > 0) { + if (!presentationExchange) { + throw new CredoError( + 'Authorization request included presentation definition. `presentationExchange` MUST be supplied to accept authorization requests.' + ) + } + + const nonce = await authorizationRequest.authorizationRequest.getMergedProperty('nonce') + if (!nonce) { + throw new CredoError("Unable to extract 'nonce' from authorization request") + } + + const clientId = await authorizationRequest.authorizationRequest.getMergedProperty('client_id') + if (!clientId) { + throw new CredoError("Unable to extract 'client_id' from authorization request") + } + + const { verifiablePresentations, presentationSubmission } = + await this.presentationExchangeService.createPresentation(agentContext, { + credentialsForInputDescriptor: presentationExchange.credentials, + presentationDefinition: authorizationRequest.presentationDefinitions[0].definition, + challenge: nonce, + domain: clientId, + presentationSubmissionLocation: DifPresentationExchangeSubmissionLocation.EXTERNAL, + }) + + presentationExchangeOptions = { + verifiablePresentations: verifiablePresentations.map((vp) => getSphereonVerifiablePresentation(vp)), + presentationSubmission, + vpTokenLocation: VPTokenLocation.AUTHORIZATION_RESPONSE, + } + + if (!openIdTokenIssuer) { + openIdTokenIssuer = this.getOpenIdTokenIssuerFromVerifiablePresentation(verifiablePresentations[0]) + } + } else if (options.presentationExchange) { + throw new CredoError( + '`presentationExchange` was supplied, but no presentation definition was found in the presentation request.' + ) + } + + if (!openIdTokenIssuer) { + throw new CredoError( + 'Unable to create authorization response. openIdTokenIssuer MUST be supplied when no presentation is active.' + ) + } + + this.assertValidTokenIssuer(authorizationRequest, openIdTokenIssuer) + const openidProvider = await this.getOpenIdProvider(agentContext, { + openIdTokenIssuer, + }) + + const suppliedSignature = await getSphereonSuppliedSignatureFromJwtIssuer(agentContext, openIdTokenIssuer) + const authorizationResponseWithCorrelationId = await openidProvider.createAuthorizationResponse( + authorizationRequest, + { + signature: suppliedSignature, + issuer: suppliedSignature.did, + verification: { + resolveOpts: { resolver: getSphereonDidResolver(agentContext), noUniversalResolverFallback: true }, + mode: VerificationMode.INTERNAL, + }, + presentationExchange: presentationExchangeOptions, + // https://openid.net/specs/openid-connect-self-issued-v2-1_0.html#name-aud-of-a-request-object + audience: authorizationRequest.authorizationRequestPayload.client_id, + } + ) + + const response = await openidProvider.submitAuthorizationResponse(authorizationResponseWithCorrelationId) + let responseDetails: string | Record | undefined = undefined + try { + responseDetails = await response.text() + if (responseDetails.includes('{')) { + responseDetails = JSON.parse(responseDetails) + } + } catch (error) { + // no-op + } + + return { + serverResponse: { + status: response.status, + body: responseDetails, + }, + submittedResponse: authorizationResponseWithCorrelationId.response.payload, + } + } + + private async getOpenIdProvider( + agentContext: AgentContext, + options: { + openIdTokenIssuer?: OpenId4VcJwtIssuer + } = {} + ) { + const { openIdTokenIssuer } = options + + const builder = OP.builder() + .withExpiresIn(6000) + .withIssuer(ResponseIss.SELF_ISSUED_V2) + .withResponseMode(ResponseMode.POST) + .withSupportedVersions([SupportedVersion.SIOPv2_D11, SupportedVersion.SIOPv2_D12_OID4VP_D18]) + .withCustomResolver(getSphereonDidResolver(agentContext)) + .withCheckLinkedDomain(CheckLinkedDomain.NEVER) + .withHasher(Hasher.hash) + + if (openIdTokenIssuer) { + const suppliedSignature = await getSphereonSuppliedSignatureFromJwtIssuer(agentContext, openIdTokenIssuer) + builder.withSignature(suppliedSignature) + } + + // Add did methods + const supportedDidMethods = agentContext.dependencyManager.resolve(DidsApi).supportedResolverMethods + for (const supportedDidMethod of supportedDidMethods) { + builder.addDidMethod(supportedDidMethod) + } + + const openidProvider = builder.build() + + return openidProvider + } + + private getOpenIdTokenIssuerFromVerifiablePresentation( + verifiablePresentation: VerifiablePresentation + ): OpenId4VcJwtIssuer { + let openIdTokenIssuer: OpenId4VcJwtIssuer + + if (verifiablePresentation instanceof W3cJsonLdVerifiablePresentation) { + const [firstProof] = asArray(verifiablePresentation.proof) + if (!firstProof) throw new CredoError('Verifiable presentation does not contain a proof') + + if (!firstProof.verificationMethod.startsWith('did:')) { + throw new CredoError( + 'Verifiable presentation proof verificationMethod is not a did. Unable to extract openIdTokenIssuer from verifiable presentation' + ) + } + + openIdTokenIssuer = { + method: 'did', + didUrl: firstProof.verificationMethod, + } + } else if (verifiablePresentation instanceof W3cJwtVerifiablePresentation) { + const kid = verifiablePresentation.jwt.header.kid + + if (!kid) throw new CredoError('Verifiable Presentation does not contain a kid in the jwt header') + if (kid.startsWith('#') && verifiablePresentation.presentation.holderId) { + openIdTokenIssuer = { + didUrl: `${verifiablePresentation.presentation.holderId}${kid}`, + method: 'did', + } + } else if (kid.startsWith('did:')) { + openIdTokenIssuer = { + didUrl: kid, + method: 'did', + } + } else { + throw new CredoError( + "JWT W3C Verifiable presentation does not include did in JWT header 'kid'. Unable to extract openIdTokenIssuer from verifiable presentation" + ) + } + } else { + const cnf = verifiablePresentation.payload.cnf + // FIXME: SD-JWT VC should have better payload typing, so this doesn't become so ugly + if ( + !cnf || + typeof cnf !== 'object' || + !('kid' in cnf) || + typeof cnf.kid !== 'string' || + !cnf.kid.startsWith('did:') || + !cnf.kid.includes('#') + ) { + throw new CredoError( + "SD-JWT Verifiable presentation has no 'cnf' claim or does not include 'cnf' claim where 'kid' is a didUrl pointing to a key. Unable to extract openIdTokenIssuer from verifiable presentation" + ) + } + + openIdTokenIssuer = { + didUrl: cnf.kid, + method: 'did', + } + } + + return openIdTokenIssuer + } + + private assertValidTokenIssuer( + authorizationRequest: VerifiedAuthorizationRequest, + openIdTokenIssuer: OpenId4VcJwtIssuer + ) { + // TODO: jwk thumbprint support + const subjectSyntaxTypesSupported = authorizationRequest.registrationMetadataPayload.subject_syntax_types_supported + if (!subjectSyntaxTypesSupported) { + throw new CredoError( + 'subject_syntax_types_supported is not supplied in the registration metadata. subject_syntax_types is REQUIRED.' + ) + } + + let allowedSubjectSyntaxTypes: string[] = [] + if (openIdTokenIssuer.method === 'did') { + const parsedDid = parseDid(openIdTokenIssuer.didUrl) + + // Either did: or did (for all did methods) is allowed + allowedSubjectSyntaxTypes = [`did:${parsedDid.method}`, 'did'] + } else { + throw new CredoError("Only 'did' is supported as openIdTokenIssuer at the moment") + } + + // At least one of the allowed subject syntax types must be supported by the RP + if (!allowedSubjectSyntaxTypes.some((allowed) => subjectSyntaxTypesSupported.includes(allowed))) { + throw new CredoError( + [ + 'The provided openIdTokenIssuer is not supported by the relying party.', + `Supported subject syntax types: '${subjectSyntaxTypesSupported.join(', ')}'`, + ].join('\n') + ) + } + } +} diff --git a/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.ts b/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.ts new file mode 100644 index 0000000000..c59a9dd53f --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/OpenId4vcSiopHolderServiceOptions.ts @@ -0,0 +1,58 @@ +import type { + OpenId4VcJwtIssuer, + OpenId4VcSiopVerifiedAuthorizationRequest, + OpenId4VcSiopAuthorizationResponsePayload, +} from '../shared' +import type { + DifPexCredentialsForRequest, + DifPexInputDescriptorToCredentials, + DifPresentationExchangeDefinition, +} from '@credo-ts/core' + +export interface OpenId4VcSiopResolvedAuthorizationRequest { + /** + * Parameters related to DIF Presentation Exchange. Only defined when + * the request included + */ + presentationExchange?: { + definition: DifPresentationExchangeDefinition + credentialsForRequest: DifPexCredentialsForRequest + } + + /** + * The verified authorization request. + */ + authorizationRequest: OpenId4VcSiopVerifiedAuthorizationRequest +} + +export interface OpenId4VcSiopAcceptAuthorizationRequestOptions { + /** + * Parameters related to DIF Presentation Exchange. MUST be present when the resolved + * authorization request included a `presentationExchange` parameter. + */ + presentationExchange?: { + credentials: DifPexInputDescriptorToCredentials + } + + /** + * The issuer of the ID Token. + * + * REQUIRED when presentation exchange is not used. + * + * In case presentation exchange is used, and `openIdTokenIssuer` is not provided, the issuer of the ID Token + * will be extracted from the signer of the first verifiable presentation. + */ + openIdTokenIssuer?: OpenId4VcJwtIssuer + + /** + * The verified authorization request. + */ + authorizationRequest: OpenId4VcSiopVerifiedAuthorizationRequest +} + +// FIXME: rethink properties +export interface OpenId4VcSiopAuthorizationResponseSubmission { + ok: boolean + status: number + submittedResponse: OpenId4VcSiopAuthorizationResponsePayload +} diff --git a/packages/openid4vc-client/src/__tests__/OpenId4VcClientModule.test.ts b/packages/openid4vc/src/openid4vc-holder/__tests__/OpenId4VcHolderModule.test.ts similarity index 52% rename from packages/openid4vc-client/src/__tests__/OpenId4VcClientModule.test.ts rename to packages/openid4vc/src/openid4vc-holder/__tests__/OpenId4VcHolderModule.test.ts index 6c21e23d43..cd56d78cf0 100644 --- a/packages/openid4vc-client/src/__tests__/OpenId4VcClientModule.test.ts +++ b/packages/openid4vc/src/openid4vc-holder/__tests__/OpenId4VcHolderModule.test.ts @@ -1,8 +1,8 @@ import type { DependencyManager } from '@credo-ts/core' -import { OpenId4VcClientApi } from '../OpenId4VcClientApi' -import { OpenId4VcClientModule } from '../OpenId4VcClientModule' -import { OpenId4VcClientService } from '../OpenId4VcClientService' +import { OpenId4VcHolderModule } from '../OpenId4VcHolderModule' +import { OpenId4VciHolderService } from '../OpenId4VciHolderService' +import { OpenId4VcSiopHolderService } from '../OpenId4vcSiopHolderService' const dependencyManager = { registerInstance: jest.fn(), @@ -11,15 +11,13 @@ const dependencyManager = { resolve: jest.fn().mockReturnValue({ logger: { warn: jest.fn() } }), } as unknown as DependencyManager -describe('OpenId4VcClientModule', () => { +describe('OpenId4VcHolderModule', () => { test('registers dependencies on the dependency manager', () => { - const openId4VcClientModule = new OpenId4VcClientModule() + const openId4VcClientModule = new OpenId4VcHolderModule() openId4VcClientModule.register(dependencyManager) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(OpenId4VcClientApi) - - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OpenId4VcClientService) + expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) + expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OpenId4VciHolderService) + expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OpenId4VcSiopHolderService) }) }) diff --git a/packages/openid4vc/src/openid4vc-holder/__tests__/fixtures.ts b/packages/openid4vc/src/openid4vc-holder/__tests__/fixtures.ts new file mode 100644 index 0000000000..ea84c90eb3 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/__tests__/fixtures.ts @@ -0,0 +1,342 @@ +export const matrrLaunchpadDraft11JwtVcJson = { + credentialOffer: + 'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Flaunchpad.vii.electron.mattrlabs.io%22%2C%22credentials%22%3A%5B%22613ecbbb-0a4c-4041-bb78-c64943139d5f%22%5D%2C%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22Jd6TUmLJct1DNyJpKKmt0i85scznBoJrEe_y_SlMW0j%22%7D%7D%7D', + getMetadataResponse: { + issuer: 'https://launchpad.vii.electron.mattrlabs.io', + authorization_endpoint: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/authorize', + token_endpoint: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/token', + jwks_uri: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/jwks', + token_endpoint_auth_methods_supported: [ + 'none', + 'client_secret_basic', + 'client_secret_jwt', + 'client_secret_post', + 'private_key_jwt', + ], + code_challenge_methods_supported: ['S256'], + grant_types_supported: ['authorization_code', 'urn:ietf:params:oauth:grant-type:pre-authorized_code'], + response_modes_supported: ['form_post', 'fragment', 'query'], + response_types_supported: ['code id_token', 'code', 'id_token', 'none'], + scopes_supported: ['OpenBadgeCredential', 'Passport'], + token_endpoint_auth_signing_alg_values_supported: ['HS256', 'RS256', 'PS256', 'ES256', 'EdDSA'], + credential_endpoint: 'https://launchpad.vii.electron.mattrlabs.io/oidc/v1/auth/credential', + credentials_supported: [ + { + id: 'd2662472-891c-413d-b3c6-e2f0109001c5', + format: 'ldp_vc', + types: ['VerifiableCredential', 'OpenBadgeCredential'], + cryptographic_binding_methods_supported: ['did:key'], + cryptographic_suites_supported: ['Ed25519Signature2018'], + display: [ + { + name: 'Example University Degree', + description: 'JFF Plugfest 3 OpenBadge Credential', + background_color: '#464c49', + logo: {}, + }, + ], + }, + { + id: 'b4c4cdf5-ccc9-4945-8c19-9334558653b2', + format: 'ldp_vc', + types: ['VerifiableCredential', 'Passport'], + cryptographic_binding_methods_supported: ['did:key'], + cryptographic_suites_supported: ['Ed25519Signature2018'], + display: [ + { + name: 'Passport', + description: 'Passport of the Kingdom of Kākāpō', + background_color: '#171717', + logo: { url: 'https://static.mattr.global/credential-assets/government-of-kakapo/web/logo.svg' }, + }, + ], + }, + { + id: '613ecbbb-0a4c-4041-bb78-c64943139d5f', + format: 'jwt_vc_json', + types: ['VerifiableCredential', 'OpenBadgeCredential'], + cryptographic_binding_methods_supported: ['did:key'], + cryptographic_suites_supported: ['EdDSA'], + display: [ + { + name: 'Example University Degree', + description: 'JFF Plugfest 3 OpenBadge Credential', + background_color: '#464c49', + logo: {}, + }, + ], + }, + { + id: 'c3db5513-ae2b-46e9-8a0d-fbfd0ce52b6a', + format: 'jwt_vc_json', + types: ['VerifiableCredential', 'Passport'], + cryptographic_binding_methods_supported: ['did:key'], + cryptographic_suites_supported: ['EdDSA'], + display: [ + { + name: 'Passport', + description: 'Passport of the Kingdom of Kākāpō', + background_color: '#171717', + logo: { url: 'https://static.mattr.global/credential-assets/government-of-kakapo/web/logo.svg' }, + }, + ], + }, + ], + }, + + wellKnownDid: { + id: 'did:web:launchpad.vii.electron.mattrlabs.io', + '@context': 'https://w3.org/ns/did/v1', + // Uses deprecated publicKey, but the did:web resolver transforms + // it to the newer verificationMethod + publicKey: [ + { + id: 'did:web:launchpad.vii.electron.mattrlabs.io#Ck99k8Rd75', + type: 'Ed25519VerificationKey2018', + controller: 'did:web:launchpad.vii.electron.mattrlabs.io', + publicKeyBase58: 'Ck99k8Rd75V3THNexmMYYA6McqUJi9QgcPh4B1BBUTX7', + }, + ], + keyAgreement: [ + { + id: 'did:web:launchpad.vii.electron.mattrlabs.io#Dd3FUiBvRy', + type: 'X25519KeyAgreementKey2019', + controller: 'did:web:launchpad.vii.electron.mattrlabs.io', + publicKeyBase58: 'Dd3FUiBvRyBcAbcywjGy99BtPaV2DXnvjbYPCu8MYs68', + }, + ], + authentication: ['did:web:launchpad.vii.electron.mattrlabs.io#Ck99k8Rd75'], + assertionMethod: ['did:web:launchpad.vii.electron.mattrlabs.io#Ck99k8Rd75'], + capabilityDelegation: ['did:web:launchpad.vii.electron.mattrlabs.io#Ck99k8Rd75'], + capabilityInvocation: ['did:web:launchpad.vii.electron.mattrlabs.io#Ck99k8Rd75'], + }, + + acquireAccessTokenResponse: { + access_token: 'i3iOTQe5TOskOOUnkIDX29M8AuygT7Lfv3MkaHprL4p', + expires_in: 3600, + scope: 'OpenBadgeCredential', + token_type: 'Bearer', + }, + + credentialResponse: { + credential: + 'eyJhbGciOiJFZERTQSIsImtpZCI6ImRpZDp3ZWI6bGF1bmNocGFkLnZpaS5lbGVjdHJvbi5tYXR0cmxhYnMuaW8jQ2s5OWs4UmQ3NSJ9.eyJpc3MiOiJkaWQ6d2ViOmxhdW5jaHBhZC52aWkuZWxlY3Ryb24ubWF0dHJsYWJzLmlvIiwic3ViIjoiZGlkOmtleTp6Nk1rcEdSNGdzNFJjM1pwaDR2ajh3Um5qbkF4Z0FQU3hjUjhNQVZLdXRXc3BRemMiLCJuYmYiOjE3MDU4NDAzMDksImV4cCI6MTczNzQ2MjcwOSwidmMiOnsibmFtZSI6IkV4YW1wbGUgVW5pdmVyc2l0eSBEZWdyZWUiLCJkZXNjcmlwdGlvbiI6IkpGRiBQbHVnZmVzdCAzIE9wZW5CYWRnZSBDcmVkZW50aWFsIiwiY3JlZGVudGlhbEJyYW5kaW5nIjp7ImJhY2tncm91bmRDb2xvciI6IiM0NjRjNDkifSwiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL21hdHRyLmdsb2JhbC9jb250ZXh0cy92Yy1leHRlbnNpb25zL3YyIiwiaHR0cHM6Ly9wdXJsLmltc2dsb2JhbC5vcmcvc3BlYy9vYi92M3AwL2NvbnRleHQtMy4wLjIuanNvbiIsImh0dHBzOi8vcHVybC5pbXNnbG9iYWwub3JnL3NwZWMvb2IvdjNwMC9leHRlbnNpb25zLmpzb24iLCJodHRwczovL3czaWQub3JnL3ZjLXJldm9jYXRpb24tbGlzdC0yMDIwL3YxIiwiaHR0cHM6Ly93M2lkLm9yZy92Yy1yZXZvY2F0aW9uLWxpc3QtMjAyMC92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDprZXk6ejZNa3BHUjRnczRSYzNacGg0dmo4d1Juam5BeGdBUFN4Y1I4TUFWS3V0V3NwUXpjIiwidHlwZSI6WyJBY2hpZXZlbWVudFN1YmplY3QiXSwiYWNoaWV2ZW1lbnQiOnsiaWQiOiJodHRwczovL2V4YW1wbGUuY29tL2FjaGlldmVtZW50cy8yMXN0LWNlbnR1cnktc2tpbGxzL3RlYW13b3JrIiwibmFtZSI6IlRlYW13b3JrIiwidHlwZSI6WyJBY2hpZXZlbWVudCJdLCJpbWFnZSI6eyJpZCI6Imh0dHBzOi8vdzNjLWNjZy5naXRodWIuaW8vdmMtZWQvcGx1Z2Zlc3QtMy0yMDIzL2ltYWdlcy9KRkYtVkMtRURVLVBMVUdGRVNUMy1iYWRnZS1pbWFnZS5wbmciLCJ0eXBlIjoiSW1hZ2UifSwiY3JpdGVyaWEiOnsibmFycmF0aXZlIjoiVGVhbSBtZW1iZXJzIGFyZSBub21pbmF0ZWQgZm9yIHRoaXMgYmFkZ2UgYnkgdGhlaXIgcGVlcnMgYW5kIHJlY29nbml6ZWQgdXBvbiByZXZpZXcgYnkgRXhhbXBsZSBDb3JwIG1hbmFnZW1lbnQuIn0sImRlc2NyaXB0aW9uIjoiVGhpcyBiYWRnZSByZWNvZ25pemVzIHRoZSBkZXZlbG9wbWVudCBvZiB0aGUgY2FwYWNpdHkgdG8gY29sbGFib3JhdGUgd2l0aGluIGEgZ3JvdXAgZW52aXJvbm1lbnQuIn19LCJpc3N1ZXIiOnsiaWQiOiJkaWQ6d2ViOmxhdW5jaHBhZC52aWkuZWxlY3Ryb24ubWF0dHJsYWJzLmlvIiwibmFtZSI6IkV4YW1wbGUgVW5pdmVyc2l0eSIsImljb25VcmwiOiJodHRwczovL3czYy1jY2cuZ2l0aHViLmlvL3ZjLWVkL3BsdWdmZXN0LTEtMjAyMi9pbWFnZXMvSkZGX0xvZ29Mb2NrdXAucG5nIiwiaW1hZ2UiOiJodHRwczovL3czYy1jY2cuZ2l0aHViLmlvL3ZjLWVkL3BsdWdmZXN0LTEtMjAyMi9pbWFnZXMvSkZGX0xvZ29Mb2NrdXAucG5nIn19fQ.u33C1y8qwlKQSIq5NjgjXq-fG_u5-bP87HAZPiaTtXhUzd5hxToyrEUb3GAEa4dkLY2TVQA1LtC6sNSUmGevBQ', + format: 'jwt_vc_json', + }, +} + +export const waltIdDraft11JwtVcJson = { + credentialOffer: + 'openid-credential-offer://?credential_offer=%7B%22credential_issuer%22%3A%22https%3A%2F%2Fissuer.portal.walt.id%22%2C%22credentials%22%3A%5B%22UniversityDegree%22%5D%2C%22grants%22%3A%7B%22authorization_code%22%3A%7B%22issuer_state%22%3A%22efc2f5dd-0f44-4f38-a902-3204e732c391%22%7D%2C%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%22eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiJlZmMyZjVkZC0wZjQ0LTRmMzgtYTkwMi0zMjA0ZTczMmMzOTEiLCJpc3MiOiJodHRwczovL2lzc3Vlci5wb3J0YWwud2FsdC5pZCIsImF1ZCI6IlRPS0VOIn0.OHzYTP_u6I95hHBmjF3RchydGidq3nsT0QHdgJ1AXyR5AFkrTfJwsW4FQIdOdda93uS7FOh_vSVGY0Qngzm7Ag%22%2C%22user_pin_required%22%3Afalse%7D%7D%7D', + getMetadataResponse: { + issuer: 'https://issuer.portal.walt.id', + authorization_endpoint: 'https://issuer.portal.walt.id/authorize', + pushed_authorization_request_endpoint: 'https://issuer.portal.walt.id/par', + token_endpoint: 'https://issuer.portal.walt.id/token', + jwks_uri: 'https://issuer.portal.walt.id/jwks', + scopes_supported: ['openid'], + response_modes_supported: ['query', 'fragment'], + grant_types_supported: ['authorization_code', 'urn:ietf:params:oauth:grant-type:pre-authorized_code'], + subject_types_supported: ['public'], + credential_issuer: 'https://issuer.portal.walt.id/.well-known/openid-credential-issuer', + credential_endpoint: 'https://issuer.portal.walt.id/credential', + credentials_supported: [ + { + format: 'jwt_vc_json', + id: 'BankId', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'BankId'], + }, + { + format: 'jwt_vc_json', + id: 'KycChecksCredential', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'VerifiableAttestation', 'KycChecksCredential'], + }, + { + format: 'jwt_vc_json', + id: 'KycDataCredential', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'VerifiableAttestation', 'KycDataCredential'], + }, + { + format: 'jwt_vc_json', + id: 'PassportCh', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableId', 'PassportCh'], + }, + { + format: 'jwt_vc_json', + id: 'PND91Credential', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'PND91Credential'], + }, + { + format: 'jwt_vc_json', + id: 'MortgageEligibility', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableId', 'MortgageEligibility'], + }, + { + format: 'jwt_vc_json', + id: 'PortableDocumentA1', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'VerifiableAttestation', 'PortableDocumentA1'], + }, + { + format: 'jwt_vc_json', + id: 'OpenBadgeCredential', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'OpenBadgeCredential'], + }, + { + format: 'jwt_vc_json', + id: 'VaccinationCertificate', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'VerifiableAttestation', 'VaccinationCertificate'], + }, + { + format: 'jwt_vc_json', + id: 'WalletHolderCredential', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'WalletHolderCredential'], + }, + { + format: 'jwt_vc_json', + id: 'UniversityDegree', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'UniversityDegree'], + }, + { + format: 'jwt_vc_json', + id: 'VerifiableId', + cryptographic_binding_methods_supported: ['did'], + cryptographic_suites_supported: ['EdDSA', 'ES256', 'ES256K', 'RSA'], + types: ['VerifiableCredential', 'VerifiableAttestation', 'VerifiableId'], + }, + ], + batch_credential_endpoint: 'https://issuer.portal.walt.id/batch_credential', + deferred_credential_endpoint: 'https://issuer.portal.walt.id/credential_deferred', + }, + + acquireAccessTokenResponse: { + access_token: + 'eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiJjMDQyMmUxMy1kNTU0LTQwMmUtOTQ0OS0yZjA0ZjAyNjMzNTMiLCJpc3MiOiJodHRwczovL2lzc3Vlci5wb3J0YWwud2FsdC5pZCIsImF1ZCI6IkFDQ0VTUyJ9.pkNF05uUy72QAoZwdf1Uz1XRc4aGs1hhnim-x1qIeMe17TMUYV2D6BOATQtDItxnnhQz2MBfqUSQKYi7CFirDA', + token_type: 'bearer', + c_nonce: 'd4364dac-f026-4380-a4c3-2bfe2d2df52a', + c_nonce_expires_in: 27, + }, + + authorizationCode: + 'eyJhbGciOiJFZERTQSJ9.eyJzdWIiOiJkZDYyOGQxYy1kYzg4LTQ2OGItYjI5Yi05ODQwMzFlNzg3OWEiLCJpc3MiOiJodHRwczovL2lzc3Vlci5wb3J0YWwud2FsdC5pZCIsImF1ZCI6IlRPS0VOIn0.86LfW1y7QwNObIhJej40E4Ea8PGjBbIeq1KBkOWOLNnOs5rRvtDkazA52npsKrBKqfoqCPmOHcVAvPZPWJhKAA', + + par: { + request_uri: 'urn:ietf:params:oauth:request_uri:738f2ac2-18ac-4162-b0a8-5e0e6ba2270b', + expires_in: 'PT3M46.132011234S', + }, + + credentialResponse: { + credential: + 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCIsImtpZCI6ImRpZDpqd2s6ZXlKcmRIa2lPaUpQUzFBaUxDSmpjbllpT2lKRlpESTFOVEU1SWl3aWEybGtJam9pUTBaUkxVNXlZVFY1Ym5sQ2MyWjRkM2szWVU1bU9HUjFRVVZWUTAxc1RVbHlVa2x5UkdjMlJFbDVOQ0lzSW5naU9pSm9OVzVpZHpaWU9VcHRTVEJDZG5WUk5VMHdTbGhtZWs4NGN6SmxSV0pRWkZZeU9YZHpTRlJNT1hCckluMCJ9.eyJpc3MiOiJkaWQ6andrOmV5SnJkSGtpT2lKUFMxQWlMQ0pqY25ZaU9pSkZaREkxTlRFNUlpd2lhMmxrSWpvaVEwWlJMVTV5WVRWNWJubENjMlo0ZDNrM1lVNW1PR1IxUVVWVlEwMXNUVWx5VWtseVJHYzJSRWw1TkNJc0luZ2lPaUpvTlc1aWR6WllPVXB0U1RCQ2RuVlJOVTB3U2xobWVrODRjekpsUldKUVpGWXlPWGR6U0ZSTU9YQnJJbjAiLCJzdWIiOiJkaWQ6a2V5Ono2TWtwR1I0Z3M0UmMzWnBoNHZqOHdSbmpuQXhnQVBTeGNSOE1BVkt1dFdzcFF6YyN6Nk1rcEdSNGdzNFJjM1pwaDR2ajh3Um5qbkF4Z0FQU3hjUjhNQVZLdXRXc3BRemMiLCJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL2V4YW1wbGVzL3YxIl0sImlkIjoidXJuOnV1aWQ6NmU2ODVlOGUtNmRmNS00NzhkLTlkNWQtNDk2ZTcxMDJkYmFhIiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIlVuaXZlcnNpdHlEZWdyZWUiXSwiaXNzdWVyIjp7ImlkIjoiZGlkOmp3azpleUpyZEhraU9pSlBTMUFpTENKamNuWWlPaUpGWkRJMU5URTVJaXdpYTJsa0lqb2lRMFpSTFU1eVlUVjVibmxDYzJaNGQzazNZVTVtT0dSMVFVVlZRMDFzVFVseVVrbHlSR2MyUkVsNU5DSXNJbmdpT2lKb05XNWlkelpZT1VwdFNUQkNkblZSTlUwd1NsaG1lazg0Y3pKbFJXSlFaRll5T1hkelNGUk1PWEJySW4wIn0sImlzc3VhbmNlRGF0ZSI6IjIwMjQtMDEtMjFUMTI6NDU6NDYuOTU1MjU0MDg3WiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmtleTp6Nk1rcEdSNGdzNFJjM1pwaDR2ajh3Um5qbkF4Z0FQU3hjUjhNQVZLdXRXc3BRemMjejZNa3BHUjRnczRSYzNacGg0dmo4d1Juam5BeGdBUFN4Y1I4TUFWS3V0V3NwUXpjIiwiZGVncmVlIjp7InR5cGUiOiJCYWNoZWxvckRlZ3JlZSIsIm5hbWUiOiJCYWNoZWxvciBvZiBTY2llbmNlIGFuZCBBcnRzIn19fSwianRpIjoidXJuOnV1aWQ6NmU2ODVlOGUtNmRmNS00NzhkLTlkNWQtNDk2ZTcxMDJkYmFhIiwiaWF0IjoxNzA1ODQxMTQ2LCJuYmYiOjE3MDU4NDEwNTZ9.sEudi9lL4YSvMdfjRaeDoRl2_p6dpfuxw_qkPXeBx8FRIQ41t-fyH_S_CDTVYH7wwL-RDbVMK1cza2FQH65hCg', + format: 'jwt_vc_json', + }, +} + +export const animoOpenIdPlaygroundDraft11SdJwtVc = { + credentialOffer: + 'openid-credential-offer://?credential_offer=%7B%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%221076398228999891821960009%22%2C%22user_pin_required%22%3Afalse%7D%7D%2C%22credentials%22%3A%5B%22AnimoOpenId4VcPlaygroundSdJwtVcJwk%22%5D%2C%22credential_issuer%22%3A%22https%3A%2F%2Fopenid4vc.animo.id%2Foid4vci%2F0bbfb1c0-9f45-478c-a139-08f6ed610a37%22%7D', + getMetadataResponse: { + credential_issuer: 'https://openid4vc.animo.id/oid4vci/0bbfb1c0-9f45-478c-a139-08f6ed610a37', + token_endpoint: 'https://openid4vc.animo.id/oid4vci/0bbfb1c0-9f45-478c-a139-08f6ed610a37/token', + credential_endpoint: 'https://openid4vc.animo.id/oid4vci/0bbfb1c0-9f45-478c-a139-08f6ed610a37/credential', + credentials_supported: [ + { + id: 'AnimoOpenId4VcPlaygroundSdJwtVcDid', + format: 'vc+sd-jwt', + vct: 'AnimoOpenId4VcPlayground', + cryptographic_binding_methods_supported: ['did:key', 'did:jwk'], + cryptographic_suites_supported: ['EdDSA'], + display: [ + { + name: 'Animo OpenID4VC Playground - SD-JWT-VC (did holder binding)', + description: "Issued using Animo's OpenID4VC Playground", + background_color: '#FFFFFF', + locale: 'en', + text_color: '#E17471', + }, + ], + }, + { + id: 'AnimoOpenId4VcPlaygroundSdJwtVcJwk', + format: 'vc+sd-jwt', + vct: 'AnimoOpenId4VcPlayground', + cryptographic_binding_methods_supported: ['jwk'], + cryptographic_suites_supported: ['EdDSA'], + display: [ + { + name: 'Animo OpenID4VC Playground - SD-JWT-VC (jwk holder binding)', + description: "Issued using Animo's OpenID4VC Playground", + background_color: '#FFFFFF', + locale: 'en', + text_color: '#E17471', + }, + ], + }, + { + id: 'AnimoOpenId4VcPlaygroundJwtVc', + format: 'jwt_vc_json', + types: ['AnimoOpenId4VcPlayground'], + cryptographic_binding_methods_supported: ['did:key', 'did:jwk'], + cryptographic_suites_supported: ['EdDSA'], + display: [ + { + name: 'Animo OpenID4VC Playground - JWT VC', + description: "Issued using Animo's OpenID4VC Playground", + background_color: '#FFFFFF', + locale: 'en', + text_color: '#E17471', + }, + ], + }, + ], + display: [ + { + background_color: '#FFFFFF', + description: 'Animo OpenID4VC Playground', + name: 'Animo OpenID4VC Playground', + locale: 'en', + logo: { alt_text: 'Animo logo', url: 'https://i.imgur.com/8B37E4a.png' }, + text_color: '#E17471', + }, + ], + }, + + acquireAccessTokenResponse: { + access_token: + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im5fQ05IM3c1dWpQaDNsTmVaR05Ta0hiT2pSTnNudkJpNXIzcXhINGZwd1UifX0.eyJpc3MiOiJodHRwczovL29wZW5pZDR2Yy5hbmltby5pZC9vaWQ0dmNpLzBiYmZiMWMwLTlmNDUtNDc4Yy1hMTM5LTA4ZjZlZDYxMGEzNyIsImV4cCI6MTgwMDAwLCJpYXQiOjE3MDU4NDM1NzM1ODh9.3JC_R4zXK0GLMG6MS7ClVWm9bK-9v7mA2iS_0hqYdmZRwXJI3ME6TAslPZNNdxCTp5ZYzzsFuLd2L3l7kULmBQ', + token_type: 'bearer', + expires_in: 180000, + c_nonce: '725150697872293881791236', + c_nonce_expires_in: 300000, + authorization_pending: false, + }, + + credentialResponse: { + credential: + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1raDVITlBDQ0pXWm42V1JMalJQdHR5dllaQnNrWlVkU0pmVGlad2NVU2llcXgifQ.eyJ2Y3QiOiJBbmltb09wZW5JZDRWY1BsYXlncm91bmQiLCJwbGF5Z3JvdW5kIjp7ImZyYW1ld29yayI6IkFyaWVzIEZyYW1ld29yayBKYXZhU2NyaXB0IiwiY3JlYXRlZEJ5IjoiQW5pbW8gU29sdXRpb25zIiwiX3NkIjpbImZZM0ZqUHpZSEZOcHlZZnRnVl9kX25DMlRHSVh4UnZocE00VHdrMk1yMDQiLCJwTnNqdmZJeVBZOEQwTks1c1l0alR2Nkc2R0FNVDNLTjdaZDNVNDAwZ1pZIl19LCJjbmYiOnsiandrIjp7Imt0eSI6Ik9LUCIsImNydiI6IkVkMjU1MTkiLCJ4Ijoia2MydGxwaGNadzFBSUt5a3pNNnBjY2k2UXNLQW9jWXpGTC01RmUzNmg2RSJ9fSwiaXNzIjoiZGlkOmtleTp6Nk1raDVITlBDQ0pXWm42V1JMalJQdHR5dllaQnNrWlVkU0pmVGlad2NVU2llcXgiLCJpYXQiOjE3MDU4NDM1NzQsIl9zZF9hbGciOiJzaGEtMjU2In0.2iAjaCFcuiHXTfQsrxXo6BghtwzqTrfDmhmarAAJAhY8r9yKXY3d10JY1dry2KnaEYWpq2R786thjdA5BXlPAQ~WyI5MzM3MTM0NzU4NDM3MjYyODY3NTE4NzkiLCJsYW5ndWFnZSIsIlR5cGVTY3JpcHQiXQ~WyIxMTQ3MDA5ODk2Nzc2MDYzOTc1MDUwOTMxIiwidmVyc2lvbiIsIjEuMCJd~', + format: 'vc+sd-jwt', + c_nonce: '98b487cb-f6e5-4f9b-b963-ad69b8fe5e29', + c_nonce_expires_in: 300000, + }, +} diff --git a/packages/openid4vc/src/openid4vc-holder/__tests__/openid4vci-holder.e2e.test.ts b/packages/openid4vc/src/openid4vc-holder/__tests__/openid4vci-holder.e2e.test.ts new file mode 100644 index 0000000000..a2a7614cf9 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/__tests__/openid4vci-holder.e2e.test.ts @@ -0,0 +1,295 @@ +import type { Key, SdJwtVc } from '@credo-ts/core' + +import { + getJwkFromKey, + Agent, + DidKey, + JwaSignatureAlgorithm, + KeyType, + TypedArrayEncoder, + W3cJwtVerifiableCredential, +} from '@credo-ts/core' +import nock, { cleanAll, enableNetConnect } from 'nock' + +import { AskarModule } from '../../../../askar/src' +import { askarModuleConfig } from '../../../../askar/tests/helpers' +import { agentDependencies } from '../../../../node/src' +import { OpenId4VcHolderModule } from '../OpenId4VcHolderModule' + +import { animoOpenIdPlaygroundDraft11SdJwtVc, matrrLaunchpadDraft11JwtVcJson, waltIdDraft11JwtVcJson } from './fixtures' + +const holder = new Agent({ + config: { + label: 'OpenId4VcHolder Test28', + walletConfig: { id: 'openid4vc-holder-test27', key: 'openid4vc-holder-test27' }, + }, + dependencies: agentDependencies, + modules: { + openId4VcHolder: new OpenId4VcHolderModule(), + askar: new AskarModule(askarModuleConfig), + }, +}) + +describe('OpenId4VcHolder', () => { + let holderKey: Key + let holderDid: string + let holderVerificationMethod: string + + beforeEach(async () => { + await holder.initialize() + + holderKey = await holder.wallet.createKey({ + keyType: KeyType.Ed25519, + privateKey: TypedArrayEncoder.fromString('96213c3d7fc8d4d6754c7a0fd969598e'), + }) + const holderDidKey = new DidKey(holderKey) + holderDid = holderDidKey.did + holderVerificationMethod = `${holderDidKey.did}#${holderDidKey.key.fingerprint}` + }) + + afterEach(async () => { + await holder.shutdown() + await holder.wallet.delete() + }) + + describe('[DRAFT 11]: Pre-authorized flow', () => { + afterEach(() => { + cleanAll() + enableNetConnect() + }) + + it('Should successfully receive credential from MATTR launchpad using the pre-authorized flow using a did:key Ed25519 subject and jwt_vc_json credential', async () => { + const fixture = matrrLaunchpadDraft11JwtVcJson + + /** + * Below we're setting up some mock HTTP responses. + * These responses are based on the openid-initiate-issuance URI above + * */ + // setup temporary redirect mock + nock('https://launchpad.mattrlabs.com').get('/.well-known/openid-credential-issuer').reply(307, undefined, { + Location: 'https://launchpad.vii.electron.mattrlabs.io/.well-known/openid-credential-issuer', + }) + + // setup server metadata response + nock('https://launchpad.vii.electron.mattrlabs.io') + .get('/.well-known/did.json') + .reply(200, fixture.wellKnownDid) + + .get('/.well-known/openid-configuration') + .reply(404) + + .get('/.well-known/oauth-authorization-server') + .reply(404) + + .get('/.well-known/openid-credential-issuer') + .reply(200, fixture.getMetadataResponse) + + // setup access token response + .post('/oidc/v1/auth/token') + .reply(200, fixture.acquireAccessTokenResponse) + + // setup credential request response + .post('/oidc/v1/auth/credential') + .reply(200, fixture.credentialResponse) + + .get('/.well-known/did.json') + .reply(200, fixture.wellKnownDid) + + const resolved = await holder.modules.openId4VcHolder.resolveCredentialOffer(fixture.credentialOffer) + const credentials = await holder.modules.openId4VcHolder.acceptCredentialOfferUsingPreAuthorizedCode(resolved, { + verifyCredentialStatus: false, + // We only allow EdDSa, as we've created a did with keyType ed25519. If we create + // or determine the did dynamically we could use any signature algorithm + allowedProofOfPossessionSignatureAlgorithms: [JwaSignatureAlgorithm.EdDSA], + credentialsToRequest: resolved.offeredCredentials.filter((c) => c.format === 'jwt_vc_json').map((m) => m.id), + credentialBindingResolver: () => ({ method: 'did', didUrl: holderVerificationMethod }), + }) + + expect(credentials).toHaveLength(1) + const w3cCredential = credentials[0] as W3cJwtVerifiableCredential + expect(w3cCredential).toBeInstanceOf(W3cJwtVerifiableCredential) + + expect(w3cCredential.credential.type).toEqual(['VerifiableCredential', 'OpenBadgeCredential']) + expect(w3cCredential.credential.credentialSubjectIds[0]).toEqual(holderDid) + }) + + it('Should successfully receive credential from walt.id using the pre-authorized flow using a did:key Ed25519 subject and jwt_vc_json credential', async () => { + const fixture = waltIdDraft11JwtVcJson + + // setup server metadata response + nock('https://issuer.portal.walt.id') + // openid configuration is same as issuer metadata for walt.id + .get('/.well-known/openid-configuration') + .reply(200, fixture.getMetadataResponse) + + .get('/.well-known/oauth-authorization-server') + .reply(404) + + .get('/.well-known/openid-credential-issuer') + .reply(200, fixture.getMetadataResponse) + + // setup access token response + .post('/token') + .reply(200, fixture.acquireAccessTokenResponse) + + // setup credential request response + .post('/credential') + .reply(200, fixture.credentialResponse) + + const resolved = await holder.modules.openId4VcHolder.resolveCredentialOffer(fixture.credentialOffer) + + await expect(() => + holder.modules.openId4VcHolder.acceptCredentialOfferUsingPreAuthorizedCode(resolved, { + verifyCredentialStatus: false, + // We only allow EdDSa, as we've created a did with keyType ed25519. If we create + // or determine the did dynamically we could use any signature algorithm + allowedProofOfPossessionSignatureAlgorithms: [JwaSignatureAlgorithm.EdDSA], + credentialsToRequest: resolved.offeredCredentials.filter((c) => c.format === 'jwt_vc_json').map((m) => m.id), + credentialBindingResolver: () => ({ method: 'did', didUrl: holderVerificationMethod }), + }) + ) + // FIXME: walt.id issues jwt where nbf and issuanceDate do not match + .rejects.toThrowError('JWT nbf and vc.issuanceDate do not match') + }) + + it('Should successfully receive credential from animo openid4vc playground using the pre-authorized flow using a jwk EdDSA subject and vc+sd-jwt credential', async () => { + const fixture = animoOpenIdPlaygroundDraft11SdJwtVc + + // setup server metadata response + nock('https://openid4vc.animo.id/oid4vci/0bbfb1c0-9f45-478c-a139-08f6ed610a37') + .get('/.well-known/openid-configuration') + .reply(404) + + .get('/.well-known/oauth-authorization-server') + .reply(404) + + .get('/.well-known/openid-credential-issuer') + .reply(200, fixture.getMetadataResponse) + + // setup access token response + .post('/token') + .reply(200, fixture.acquireAccessTokenResponse) + + // setup credential request response + .post('/credential') + .reply(200, fixture.credentialResponse) + + const resolved = await holder.modules.openId4VcHolder.resolveCredentialOffer(fixture.credentialOffer) + + const credentials = await holder.modules.openId4VcHolder.acceptCredentialOfferUsingPreAuthorizedCode(resolved, { + verifyCredentialStatus: false, + // We only allow EdDSa, as we've created a did with keyType ed25519. If we create + // or determine the did dynamically we could use any signature algorithm + allowedProofOfPossessionSignatureAlgorithms: [JwaSignatureAlgorithm.EdDSA], + credentialsToRequest: resolved.offeredCredentials.filter((c) => c.format === 'vc+sd-jwt').map((m) => m.id), + credentialBindingResolver: () => ({ method: 'jwk', jwk: getJwkFromKey(holderKey) }), + }) + + expect(credentials).toHaveLength(1) + const credential = credentials[0] as SdJwtVc + expect(credential).toEqual({ + compact: + 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1raDVITlBDQ0pXWm42V1JMalJQdHR5dllaQnNrWlVkU0pmVGlad2NVU2llcXgifQ.eyJ2Y3QiOiJBbmltb09wZW5JZDRWY1BsYXlncm91bmQiLCJwbGF5Z3JvdW5kIjp7ImZyYW1ld29yayI6IkFyaWVzIEZyYW1ld29yayBKYXZhU2NyaXB0IiwiY3JlYXRlZEJ5IjoiQW5pbW8gU29sdXRpb25zIiwiX3NkIjpbImZZM0ZqUHpZSEZOcHlZZnRnVl9kX25DMlRHSVh4UnZocE00VHdrMk1yMDQiLCJwTnNqdmZJeVBZOEQwTks1c1l0alR2Nkc2R0FNVDNLTjdaZDNVNDAwZ1pZIl19LCJjbmYiOnsiandrIjp7Imt0eSI6Ik9LUCIsImNydiI6IkVkMjU1MTkiLCJ4Ijoia2MydGxwaGNadzFBSUt5a3pNNnBjY2k2UXNLQW9jWXpGTC01RmUzNmg2RSJ9fSwiaXNzIjoiZGlkOmtleTp6Nk1raDVITlBDQ0pXWm42V1JMalJQdHR5dllaQnNrWlVkU0pmVGlad2NVU2llcXgiLCJpYXQiOjE3MDU4NDM1NzQsIl9zZF9hbGciOiJzaGEtMjU2In0.2iAjaCFcuiHXTfQsrxXo6BghtwzqTrfDmhmarAAJAhY8r9yKXY3d10JY1dry2KnaEYWpq2R786thjdA5BXlPAQ~WyI5MzM3MTM0NzU4NDM3MjYyODY3NTE4NzkiLCJsYW5ndWFnZSIsIlR5cGVTY3JpcHQiXQ~WyIxMTQ3MDA5ODk2Nzc2MDYzOTc1MDUwOTMxIiwidmVyc2lvbiIsIjEuMCJd~', + header: { + alg: 'EdDSA', + kid: '#z6Mkh5HNPCCJWZn6WRLjRPttyvYZBskZUdSJfTiZwcUSieqx', + typ: 'vc+sd-jwt', + }, + payload: { + _sd_alg: 'sha-256', + cnf: { + jwk: { + crv: 'Ed25519', + kty: 'OKP', + x: 'kc2tlphcZw1AIKykzM6pcci6QsKAocYzFL-5Fe36h6E', + }, + }, + iat: 1705843574, + iss: 'did:key:z6Mkh5HNPCCJWZn6WRLjRPttyvYZBskZUdSJfTiZwcUSieqx', + playground: { + _sd: ['fY3FjPzYHFNpyYftgV_d_nC2TGIXxRvhpM4Twk2Mr04', 'pNsjvfIyPY8D0NK5sYtjTv6G6GAMT3KN7Zd3U400gZY'], + createdBy: 'Animo Solutions', + framework: 'Aries Framework JavaScript', + }, + vct: 'AnimoOpenId4VcPlayground', + }, + prettyClaims: { + cnf: { + jwk: { + crv: 'Ed25519', + kty: 'OKP', + x: 'kc2tlphcZw1AIKykzM6pcci6QsKAocYzFL-5Fe36h6E', + }, + }, + iat: 1705843574, + iss: 'did:key:z6Mkh5HNPCCJWZn6WRLjRPttyvYZBskZUdSJfTiZwcUSieqx', + playground: { + createdBy: 'Animo Solutions', + framework: 'Aries Framework JavaScript', + language: 'TypeScript', + version: '1.0', + }, + vct: 'AnimoOpenId4VcPlayground', + }, + }) + }) + }) + + describe('[DRAFT 11]: Authorization flow', () => { + afterAll(() => { + cleanAll() + enableNetConnect() + }) + + it('Should successfully receive credential from walt.id using the authorized flow using a did:key Ed25519 subject and jwt_vc_json credential', async () => { + const fixture = waltIdDraft11JwtVcJson + + // setup temporary redirect mock + nock('https://issuer.portal.walt.id') + .get('/.well-known/openid-credential-issuer') + .reply(200, fixture.getMetadataResponse) + .get('/.well-known/openid-configuration') + .reply(200, fixture.getMetadataResponse) + .get('/.well-known/oauth-authorization-server') + .reply(404) + .post('/par') + .reply(200, fixture.par) + // setup access token response + .post('/token') + .reply(200, fixture.acquireAccessTokenResponse) + // setup credential request response + .post('/credential') + .reply(200, fixture.credentialResponse) + + .get('/.well-known/oauth-authorization-server') + .reply(404) + + const resolved = await holder.modules.openId4VcHolder.resolveCredentialOffer(fixture.credentialOffer) + + const resolvedAuthorizationRequest = await holder.modules.openId4VcHolder.resolveIssuanceAuthorizationRequest( + resolved, + { + clientId: 'test-client', + redirectUri: 'http://example.com', + scope: ['openid', 'UniversityDegree'], + } + ) + + await expect( + holder.modules.openId4VcHolder.acceptCredentialOfferUsingAuthorizationCode( + resolved, + resolvedAuthorizationRequest, + fixture.authorizationCode, + { + allowedProofOfPossessionSignatureAlgorithms: [JwaSignatureAlgorithm.EdDSA], + credentialBindingResolver: () => ({ method: 'did', didUrl: holderVerificationMethod }), + verifyCredentialStatus: false, + } + ) + ) + // FIXME: credential returned by walt.id has nbf and issuanceDate that do not match + // but we know that we at least received the credential if we got to this error + .rejects.toThrowError('JWT nbf and vc.issuanceDate do not match') + }) + }) +}) diff --git a/packages/openid4vc/src/openid4vc-holder/__tests__/openid4vp-holder.e2e.test.ts b/packages/openid4vc/src/openid4vc-holder/__tests__/openid4vp-holder.e2e.test.ts new file mode 100644 index 0000000000..8b511cc99a --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/__tests__/openid4vp-holder.e2e.test.ts @@ -0,0 +1,110 @@ +import type { AgentType } from '../../../tests/utils' +import type { OpenId4VcVerifierRecord } from '../../openid4vc-verifier/repository' +import type { Express } from 'express' +import type { Server } from 'http' + +import express from 'express' + +import { OpenId4VcHolderModule } from '..' +import { AskarModule } from '../../../../askar/src' +import { askarModuleConfig } from '../../../../askar/tests/helpers' +import { createAgentFromModules } from '../../../tests/utils' +import { OpenId4VcVerifierModule } from '../../openid4vc-verifier' + +const port = 3121 +const verificationEndpointPath = '/proofResponse' +const verifierBaseUrl = `http://localhost:${port}` + +const holderModules = { + openId4VcHolder: new OpenId4VcHolderModule(), + askar: new AskarModule(askarModuleConfig), +} + +const verifierModules = { + openId4VcVerifier: new OpenId4VcVerifierModule({ + baseUrl: verifierBaseUrl, + endpoints: { + authorization: { + endpointPath: verificationEndpointPath, + }, + }, + }), + askar: new AskarModule(askarModuleConfig), +} + +describe('OpenId4VcHolder | OpenID4VP', () => { + let openIdVerifier: OpenId4VcVerifierRecord + let verifier: AgentType + let holder: AgentType + let verifierApp: Express + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let verifierServer: Server + + beforeEach(async () => { + verifier = await createAgentFromModules('verifier', verifierModules, '96213c3d7fc8d4d6754c7a0fd969598f') + openIdVerifier = await verifier.agent.modules.openId4VcVerifier.createVerifier() + holder = await createAgentFromModules('holder', holderModules, '96213c3d7fc8d4d6754c7a0fd969598e') + verifierApp = express() + + verifierApp.use('/', verifier.agent.modules.openId4VcVerifier.config.router) + verifierServer = verifierApp.listen(port) + }) + + afterEach(async () => { + verifierServer?.close() + await holder.agent.shutdown() + await holder.agent.wallet.delete() + await verifier.agent.shutdown() + await verifier.agent.wallet.delete() + }) + + it('siop authorization request without presentation exchange', async () => { + const { authorizationRequestUri } = await verifier.agent.modules.openId4VcVerifier.createAuthorizationRequest({ + requestSigner: { + method: 'did', + didUrl: verifier.kid, + }, + verifierId: openIdVerifier.verifierId, + }) + + const resolvedAuthorizationRequest = await holder.agent.modules.openId4VcHolder.resolveSiopAuthorizationRequest( + authorizationRequestUri + ) + + const { submittedResponse, serverResponse } = + await holder.agent.modules.openId4VcHolder.acceptSiopAuthorizationRequest({ + authorizationRequest: resolvedAuthorizationRequest.authorizationRequest, + // When no VP is created, we need to provide the did we want to use for authentication + openIdTokenIssuer: { + method: 'did', + didUrl: holder.kid, + }, + }) + + expect(serverResponse).toEqual({ + status: 200, + body: '', + }) + + expect(submittedResponse).toMatchObject({ + expires_in: 6000, + id_token: expect.any(String), + state: expect.any(String), + }) + + const { idToken, presentationExchange } = + await verifier.agent.modules.openId4VcVerifier.verifyAuthorizationResponse({ + authorizationResponse: submittedResponse, + verifierId: openIdVerifier.verifierId, + }) + + expect(presentationExchange).toBeUndefined() + expect(idToken).toMatchObject({ + payload: { + state: expect.any(String), + nonce: expect.any(String), + }, + }) + }) +}) diff --git a/packages/openid4vc/src/openid4vc-holder/index.ts b/packages/openid4vc/src/openid4vc-holder/index.ts new file mode 100644 index 0000000000..2b7a8d1d5b --- /dev/null +++ b/packages/openid4vc/src/openid4vc-holder/index.ts @@ -0,0 +1,6 @@ +export * from './OpenId4VcHolderApi' +export * from './OpenId4VcHolderModule' +export * from './OpenId4VciHolderService' +export * from './OpenId4VciHolderServiceOptions' +export * from './OpenId4vcSiopHolderService' +export * from './OpenId4vcSiopHolderServiceOptions' diff --git a/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerApi.ts b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerApi.ts new file mode 100644 index 0000000000..4709b9384c --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerApi.ts @@ -0,0 +1,104 @@ +import type { + OpenId4VciCreateCredentialResponseOptions, + OpenId4VciCreateCredentialOfferOptions, + OpenId4VciCreateIssuerOptions, +} from './OpenId4VcIssuerServiceOptions' +import type { OpenId4VcIssuerRecordProps } from './repository' +import type { OpenId4VciCredentialOfferPayload } from '../shared' + +import { injectable, AgentContext } from '@credo-ts/core' + +import { OpenId4VcIssuerModuleConfig } from './OpenId4VcIssuerModuleConfig' +import { OpenId4VcIssuerService } from './OpenId4VcIssuerService' + +/** + * @public + * This class represents the API for interacting with the OpenID4VC Issuer service. + * It provides methods for creating a credential offer, creating a response to a credential issuance request, + * and retrieving a credential offer from a URI. + */ +@injectable() +export class OpenId4VcIssuerApi { + public constructor( + public readonly config: OpenId4VcIssuerModuleConfig, + private agentContext: AgentContext, + private openId4VcIssuerService: OpenId4VcIssuerService + ) {} + + public async getAllIssuers() { + return this.openId4VcIssuerService.getAllIssuers(this.agentContext) + } + + public async getByIssuerId(issuerId: string) { + return this.openId4VcIssuerService.getByIssuerId(this.agentContext, issuerId) + } + + /** + * Creates an issuer and stores the corresponding issuer metadata. Multiple issuers can be created, to allow different sets of + * credentials to be issued with each issuer. + */ + public async createIssuer(options: OpenId4VciCreateIssuerOptions) { + return this.openId4VcIssuerService.createIssuer(this.agentContext, options) + } + + /** + * Rotate the key used for signing access tokens for the issuer with the given issuerId. + */ + public async rotateAccessTokenSigningKey(issuerId: string) { + const issuer = await this.openId4VcIssuerService.getByIssuerId(this.agentContext, issuerId) + return this.openId4VcIssuerService.rotateAccessTokenSigningKey(this.agentContext, issuer) + } + + public async getIssuerMetadata(issuerId: string) { + const issuer = await this.openId4VcIssuerService.getByIssuerId(this.agentContext, issuerId) + return this.openId4VcIssuerService.getIssuerMetadata(this.agentContext, issuer) + } + + public async updateIssuerMetadata( + options: Pick + ) { + const issuer = await this.openId4VcIssuerService.getByIssuerId(this.agentContext, options.issuerId) + + issuer.credentialsSupported = options.credentialsSupported + issuer.display = options.display + + return this.openId4VcIssuerService.updateIssuer(this.agentContext, issuer) + } + + /** + * Creates a credential offer. Either the preAuthorizedCodeFlowConfig or the authorizationCodeFlowConfig must be provided. + * + * @returns Object containing the payload of the credential offer and the credential offer request, which can be sent to the wallet. + */ + public async createCredentialOffer(options: OpenId4VciCreateCredentialOfferOptions & { issuerId: string }) { + const { issuerId, ...rest } = options + const issuer = await this.openId4VcIssuerService.getByIssuerId(this.agentContext, issuerId) + return await this.openId4VcIssuerService.createCredentialOffer(this.agentContext, { ...rest, issuer }) + } + + /** + * This function retrieves the credential offer referenced by the given URI. + * Retrieving a credential offer from a URI is possible after a credential offer was created with + * @see createCredentialOffer and the credentialOfferUri option. + * + * @throws if no credential offer can found for the given URI. + * @param uri - The URI referencing the credential offer. + * @returns The credential offer payload associated with the given URI. + */ + public async getCredentialOfferFromUri(uri: string): Promise { + return await this.openId4VcIssuerService.getCredentialOfferFromUri(this.agentContext, uri) + } + + /** + * This function creates a response which can be send to the holder after receiving a credential issuance request. + * + * @param options.credentialRequest - The credential request, for which to create a response. + * @param options.credential - The credential to be issued. + * @param options.verificationMethod - The verification method used for signing the credential. + */ + public async createCredentialResponse(options: OpenId4VciCreateCredentialResponseOptions & { issuerId: string }) { + const { issuerId, ...rest } = options + const issuer = await this.openId4VcIssuerService.getByIssuerId(this.agentContext, issuerId) + return await this.openId4VcIssuerService.createCredentialResponse(this.agentContext, { ...rest, issuer }) + } +} diff --git a/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerModule.ts b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerModule.ts new file mode 100644 index 0000000000..b4a52a2600 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerModule.ts @@ -0,0 +1,130 @@ +import type { OpenId4VcIssuerModuleConfigOptions } from './OpenId4VcIssuerModuleConfig' +import type { OpenId4VcIssuanceRequest } from './router' +import type { AgentContext, DependencyManager, Module } from '@credo-ts/core' + +import { AgentConfig } from '@credo-ts/core' + +import { getAgentContextForActorId, getRequestContext, importExpress } from '../shared/router' + +import { OpenId4VcIssuerApi } from './OpenId4VcIssuerApi' +import { OpenId4VcIssuerModuleConfig } from './OpenId4VcIssuerModuleConfig' +import { OpenId4VcIssuerService } from './OpenId4VcIssuerService' +import { OpenId4VcIssuerRepository } from './repository/OpenId4VcIssuerRepository' +import { configureAccessTokenEndpoint, configureCredentialEndpoint, configureIssuerMetadataEndpoint } from './router' + +/** + * @public + */ +export class OpenId4VcIssuerModule implements Module { + public readonly api = OpenId4VcIssuerApi + public readonly config: OpenId4VcIssuerModuleConfig + + public constructor(options: OpenId4VcIssuerModuleConfigOptions) { + this.config = new OpenId4VcIssuerModuleConfig(options) + } + + /** + * Registers the dependencies of the question answer module on the dependency manager. + */ + public register(dependencyManager: DependencyManager) { + // Warn about experimental module + dependencyManager + .resolve(AgentConfig) + .logger.warn( + "The '@credo-ts/openid4vc' Issuer module is experimental and could have unexpected breaking changes. When using this module, make sure to use strict versions for all @credo-ts packages." + ) + + // Register config + dependencyManager.registerInstance(OpenId4VcIssuerModuleConfig, this.config) + + // Services + dependencyManager.registerSingleton(OpenId4VcIssuerService) + + // Repository + dependencyManager.registerSingleton(OpenId4VcIssuerRepository) + } + + public async initialize(rootAgentContext: AgentContext): Promise { + this.configureRouter(rootAgentContext) + } + + /** + * Registers the endpoints on the router passed to this module. + */ + private configureRouter(rootAgentContext: AgentContext) { + const { Router, json, urlencoded } = importExpress() + + // TODO: it is currently not possible to initialize an agent + // shut it down, and then start it again, as the + // express router is configured with a specific `AgentContext` instance + // and dependency manager. One option is to always create a new router + // but then users cannot pass their own router implementation. + // We need to find a proper way to fix this. + + // We use separate context router and endpoint router. Context router handles the linking of the request + // to a specific agent context. Endpoint router only knows about a single context + const endpointRouter = Router() + const contextRouter = this.config.router + + // parse application/x-www-form-urlencoded + contextRouter.use(urlencoded({ extended: false })) + // parse application/json + contextRouter.use(json()) + + contextRouter.param('issuerId', async (req: OpenId4VcIssuanceRequest, _res, next, issuerId: string) => { + if (!issuerId) { + rootAgentContext.config.logger.debug('No issuerId provided for incoming oid4vci request, returning 404') + _res.status(404).send('Not found') + } + + let agentContext: AgentContext | undefined = undefined + + try { + // FIXME: should we create combined openId actor record? + agentContext = await getAgentContextForActorId(rootAgentContext, issuerId) + const issuerApi = agentContext.dependencyManager.resolve(OpenId4VcIssuerApi) + const issuer = await issuerApi.getByIssuerId(issuerId) + + req.requestContext = { + agentContext, + issuer, + } + } catch (error) { + agentContext?.config.logger.error( + 'Failed to correlate incoming oid4vci request to existing tenant and issuer', + { + error, + } + ) + // If the opening failed + await agentContext?.endSession() + + return _res.status(404).send('Not found') + } + + next() + }) + + contextRouter.use('/:issuerId', endpointRouter) + + // Configure endpoints + configureIssuerMetadataEndpoint(endpointRouter) + configureAccessTokenEndpoint(endpointRouter, this.config.accessTokenEndpoint) + configureCredentialEndpoint(endpointRouter, this.config.credentialEndpoint) + + // First one will be called for all requests (when next is called) + contextRouter.use(async (req: OpenId4VcIssuanceRequest, _res: unknown, next) => { + const { agentContext } = getRequestContext(req) + await agentContext.endSession() + next() + }) + + // This one will be called for all errors that are thrown + // eslint-disable-next-line @typescript-eslint/no-explicit-any + contextRouter.use(async (_error: unknown, req: OpenId4VcIssuanceRequest, _res: unknown, next: any) => { + const { agentContext } = getRequestContext(req) + await agentContext.endSession() + next() + }) + } +} diff --git a/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerModuleConfig.ts b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerModuleConfig.ts new file mode 100644 index 0000000000..d2204fb1d3 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerModuleConfig.ts @@ -0,0 +1,119 @@ +import type { OpenId4VciAccessTokenEndpointConfig, OpenId4VciCredentialEndpointConfig } from './router' +import type { AgentContext, Optional } from '@credo-ts/core' +import type { CNonceState, CredentialOfferSession, IStateManager, URIState } from '@sphereon/oid4vci-common' +import type { Router } from 'express' + +import { MemoryStates } from '@sphereon/oid4vci-issuer' + +import { importExpress } from '../shared/router' + +const DEFAULT_C_NONCE_EXPIRES_IN = 5 * 60 * 1000 // 5 minutes +const DEFAULT_TOKEN_EXPIRES_IN = 3 * 60 * 1000 // 3 minutes +const DEFAULT_PRE_AUTH_CODE_EXPIRES_IN = 3 * 60 * 1000 // 3 minutes + +export interface OpenId4VcIssuerModuleConfigOptions { + /** + * Base url at which the issuer endpoints will be hosted. All endpoints will be exposed with + * this path as prefix. + */ + baseUrl: string + + /** + * Express router on which the openid4vci endpoints will be registered. If + * no router is provided, a new one will be created. + * + * NOTE: you must manually register the router on your express app and + * expose this on a public url that is reachable when `baseUrl` is called. + */ + router?: Router + + endpoints: { + credential: Optional + accessToken?: Optional< + OpenId4VciAccessTokenEndpointConfig, + 'cNonceExpiresInSeconds' | 'endpointPath' | 'preAuthorizedCodeExpirationInSeconds' | 'tokenExpiresInSeconds' + > + } +} + +export class OpenId4VcIssuerModuleConfig { + private options: OpenId4VcIssuerModuleConfigOptions + public readonly router: Router + + private credentialOfferSessionManagerMap: Map> + private uriStateManagerMap: Map> + private cNonceStateManagerMap: Map> + + public constructor(options: OpenId4VcIssuerModuleConfigOptions) { + this.uriStateManagerMap = new Map() + this.credentialOfferSessionManagerMap = new Map() + this.cNonceStateManagerMap = new Map() + this.options = options + + this.router = options.router ?? importExpress().Router() + } + + public get baseUrl() { + return this.options.baseUrl + } + + /** + * Get the credential endpoint config, with default values set + */ + public get credentialEndpoint(): OpenId4VciCredentialEndpointConfig { + // Use user supplied options, or return defaults. + const userOptions = this.options.endpoints.credential + + return { + ...userOptions, + endpointPath: userOptions.endpointPath ?? '/credential', + } + } + + /** + * Get the access token endpoint config, with default values set + */ + public get accessTokenEndpoint(): OpenId4VciAccessTokenEndpointConfig { + // Use user supplied options, or return defaults. + const userOptions = this.options.endpoints.accessToken ?? {} + + return { + ...userOptions, + endpointPath: userOptions.endpointPath ?? '/token', + cNonceExpiresInSeconds: userOptions.cNonceExpiresInSeconds ?? DEFAULT_C_NONCE_EXPIRES_IN, + preAuthorizedCodeExpirationInSeconds: + userOptions.preAuthorizedCodeExpirationInSeconds ?? DEFAULT_PRE_AUTH_CODE_EXPIRES_IN, + tokenExpiresInSeconds: userOptions.tokenExpiresInSeconds ?? DEFAULT_TOKEN_EXPIRES_IN, + } + } + + // FIXME: rework (no in-memory) + public getUriStateManager(agentContext: AgentContext) { + const value = this.uriStateManagerMap.get(agentContext.contextCorrelationId) + if (value) return value + + const newValue = new MemoryStates() + this.uriStateManagerMap.set(agentContext.contextCorrelationId, newValue) + return newValue + } + + // FIXME: rework (no in-memory) + public getCredentialOfferSessionStateManager(agentContext: AgentContext) { + const value = this.credentialOfferSessionManagerMap.get(agentContext.contextCorrelationId) + if (value) return value + + const newValue = new MemoryStates() + this.credentialOfferSessionManagerMap.set(agentContext.contextCorrelationId, newValue) + return newValue + } + + // FIXME: rework (no in-memory) + public getCNonceStateManager(agentContext: AgentContext) { + const value = this.cNonceStateManagerMap.get(agentContext.contextCorrelationId) + if (value) return value + + const newValue = new MemoryStates() + this.cNonceStateManagerMap.set(agentContext.contextCorrelationId, newValue) + return newValue + } +} diff --git a/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerService.ts b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerService.ts new file mode 100644 index 0000000000..7232609c32 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerService.ts @@ -0,0 +1,529 @@ +import type { + OpenId4VciCreateCredentialResponseOptions, + OpenId4VciAuthorizationCodeFlowConfig, + OpenId4VciCreateCredentialOfferOptions, + OpenId4VciCreateIssuerOptions, + OpenId4VciPreAuthorizedCodeFlowConfig, + OpenId4VcIssuerMetadata, + OpenId4VciSignSdJwtCredential, + OpenId4VciSignW3cCredential, +} from './OpenId4VcIssuerServiceOptions' +import type { + OpenId4VcCredentialHolderBinding, + OpenId4VciCredentialOfferPayload, + OpenId4VciCredentialRequest, + OpenId4VciCredentialSupported, +} from '../shared' +import type { AgentContext, DidDocument } from '@credo-ts/core' +import type { Grant, JWTVerifyCallback } from '@sphereon/oid4vci-common' +import type { + CredentialDataSupplier, + CredentialDataSupplierArgs, + CredentialIssuanceInput, + CredentialSignerCallback, +} from '@sphereon/oid4vci-issuer' +import type { ICredential } from '@sphereon/ssi-types' + +import { + SdJwtVcApi, + CredoError, + ClaimFormat, + DidsApi, + equalsIgnoreOrder, + getJwkFromJson, + getJwkFromKey, + getKeyFromVerificationMethod, + injectable, + joinUriParts, + JsonEncoder, + JsonTransformer, + JwsService, + Jwt, + KeyType, + utils, + W3cCredentialService, +} from '@credo-ts/core' +import { IssueStatus } from '@sphereon/oid4vci-common' +import { VcIssuerBuilder } from '@sphereon/oid4vci-issuer' + +import { getOfferedCredentials, OpenId4VciCredentialFormatProfile } from '../shared' +import { storeActorIdForContextCorrelationId } from '../shared/router' +import { getSphereonVerifiableCredential } from '../shared/transform' +import { getProofTypeFromKey } from '../shared/utils' + +import { OpenId4VcIssuerModuleConfig } from './OpenId4VcIssuerModuleConfig' +import { OpenId4VcIssuerRepository, OpenId4VcIssuerRecord } from './repository' + +const w3cOpenId4VcFormats = [ + OpenId4VciCredentialFormatProfile.JwtVcJson, + OpenId4VciCredentialFormatProfile.JwtVcJsonLd, + OpenId4VciCredentialFormatProfile.LdpVc, +] + +/** + * @internal + */ +@injectable() +export class OpenId4VcIssuerService { + private w3cCredentialService: W3cCredentialService + private jwsService: JwsService + private openId4VcIssuerConfig: OpenId4VcIssuerModuleConfig + private openId4VcIssuerRepository: OpenId4VcIssuerRepository + + public constructor( + w3cCredentialService: W3cCredentialService, + jwsService: JwsService, + openId4VcIssuerConfig: OpenId4VcIssuerModuleConfig, + openId4VcIssuerRepository: OpenId4VcIssuerRepository + ) { + this.w3cCredentialService = w3cCredentialService + this.jwsService = jwsService + this.openId4VcIssuerConfig = openId4VcIssuerConfig + this.openId4VcIssuerRepository = openId4VcIssuerRepository + } + + public getIssuerMetadata(agentContext: AgentContext, issuerRecord: OpenId4VcIssuerRecord): OpenId4VcIssuerMetadata { + const config = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig) + const issuerUrl = joinUriParts(config.baseUrl, [issuerRecord.issuerId]) + + const issuerMetadata = { + issuerUrl, + tokenEndpoint: joinUriParts(issuerUrl, [config.accessTokenEndpoint.endpointPath]), + credentialEndpoint: joinUriParts(issuerUrl, [config.credentialEndpoint.endpointPath]), + credentialsSupported: issuerRecord.credentialsSupported, + issuerDisplay: issuerRecord.display, + } satisfies OpenId4VcIssuerMetadata + + return issuerMetadata + } + + public async createCredentialOffer( + agentContext: AgentContext, + options: OpenId4VciCreateCredentialOfferOptions & { issuer: OpenId4VcIssuerRecord } + ) { + const { preAuthorizedCodeFlowConfig, authorizationCodeFlowConfig, issuer, offeredCredentials } = options + + const vcIssuer = this.getVcIssuer(agentContext, issuer) + + // this checks if the structure of the credentials is correct + // it throws an error if a offered credential cannot be found in the credentialsSupported + getOfferedCredentials(options.offeredCredentials, vcIssuer.issuerMetadata.credentials_supported) + + const { uri, session } = await vcIssuer.createCredentialOfferURI({ + grants: await this.getGrantsFromConfig(agentContext, preAuthorizedCodeFlowConfig, authorizationCodeFlowConfig), + credentials: offeredCredentials, + // TODO: support hosting of credential offers within AFJ + credentialOfferUri: options.hostedCredentialOfferUrl, + baseUri: options.baseUri, + }) + + const credentialOfferPayload: OpenId4VciCredentialOfferPayload = session.credentialOffer.credential_offer + return { + credentialOfferPayload, + credentialOffer: uri, + } + } + + public async getCredentialOfferFromUri(agentContext: AgentContext, uri: string) { + const { credentialOfferSessionId, credentialOfferSession } = await this.getCredentialOfferSessionFromUri( + agentContext, + uri + ) + + credentialOfferSession.lastUpdatedAt = +new Date() + credentialOfferSession.status = IssueStatus.OFFER_URI_RETRIEVED + await this.openId4VcIssuerConfig + .getCredentialOfferSessionStateManager(agentContext) + .set(credentialOfferSessionId, credentialOfferSession) + + return credentialOfferSession.credentialOffer.credential_offer + } + + public async createCredentialResponse( + agentContext: AgentContext, + options: OpenId4VciCreateCredentialResponseOptions & { issuer: OpenId4VcIssuerRecord } + ) { + const { credentialRequest, issuer } = options + if (!credentialRequest.proof) throw new CredoError('No proof defined in the credentialRequest.') + + const vcIssuer = this.getVcIssuer(agentContext, issuer) + const issueCredentialResponse = await vcIssuer.issueCredential({ + credentialRequest, + tokenExpiresIn: this.openId4VcIssuerConfig.accessTokenEndpoint.tokenExpiresInSeconds, + + // This can just be combined with signing callback right? + credentialDataSupplier: this.getCredentialDataSupplier(agentContext, options), + newCNonce: undefined, + responseCNonce: undefined, + }) + + if (!issueCredentialResponse.credential) { + throw new CredoError('No credential found in the issueCredentialResponse.') + } + + if (issueCredentialResponse.acceptance_token) { + throw new CredoError('Acceptance token not yet supported.') + } + + return issueCredentialResponse + } + + public async getAllIssuers(agentContext: AgentContext) { + return this.openId4VcIssuerRepository.getAll(agentContext) + } + + public async getByIssuerId(agentContext: AgentContext, issuerId: string) { + return this.openId4VcIssuerRepository.getByIssuerId(agentContext, issuerId) + } + + public async updateIssuer(agentContext: AgentContext, issuer: OpenId4VcIssuerRecord) { + return this.openId4VcIssuerRepository.update(agentContext, issuer) + } + + public async createIssuer(agentContext: AgentContext, options: OpenId4VciCreateIssuerOptions) { + // TODO: ideally we can store additional data with a key, such as: + // - createdAt + // - purpose + const accessTokenSignerKey = await agentContext.wallet.createKey({ + keyType: KeyType.Ed25519, + }) + const openId4VcIssuer = new OpenId4VcIssuerRecord({ + issuerId: options.issuerId ?? utils.uuid(), + display: options.display, + accessTokenPublicKeyFingerprint: accessTokenSignerKey.fingerprint, + credentialsSupported: options.credentialsSupported, + }) + + await this.openId4VcIssuerRepository.save(agentContext, openId4VcIssuer) + await storeActorIdForContextCorrelationId(agentContext, openId4VcIssuer.issuerId) + return openId4VcIssuer + } + + public async rotateAccessTokenSigningKey(agentContext: AgentContext, issuer: OpenId4VcIssuerRecord) { + const accessTokenSignerKey = await agentContext.wallet.createKey({ + keyType: KeyType.Ed25519, + }) + + // TODO: ideally we can remove the previous key + issuer.accessTokenPublicKeyFingerprint = accessTokenSignerKey.fingerprint + await this.openId4VcIssuerRepository.update(agentContext, issuer) + } + + private async getCredentialOfferSessionFromUri(agentContext: AgentContext, uri: string) { + const uriState = await this.openId4VcIssuerConfig.getUriStateManager(agentContext).get(uri) + if (!uriState) throw new CredoError(`Credential offer uri '${uri}' not found.`) + + const credentialOfferSessionId = uriState.preAuthorizedCode ?? uriState.issuerState + if (!credentialOfferSessionId) { + throw new CredoError(`Credential offer uri '${uri}' is not associated with a preAuthorizedCode or issuerState.`) + } + + const credentialOfferSession = await this.openId4VcIssuerConfig + .getCredentialOfferSessionStateManager(agentContext) + .get(credentialOfferSessionId) + if (!credentialOfferSession) + throw new CredoError(`Credential offer session for '${uri}' with id '${credentialOfferSessionId}' not found.`) + + return { credentialOfferSessionId, credentialOfferSession } + } + + private getJwtVerifyCallback = (agentContext: AgentContext): JWTVerifyCallback => { + return async (opts) => { + let didDocument = undefined as DidDocument | undefined + const { isValid, jws } = await this.jwsService.verifyJws(agentContext, { + jws: opts.jwt, + // Only handles kid as did resolution. JWK is handled by jws service + jwkResolver: async ({ protectedHeader: { kid } }) => { + if (!kid) throw new CredoError('Missing kid in protected header.') + if (!kid.startsWith('did:')) throw new CredoError('Only did is supported for kid identifier') + + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + didDocument = await didsApi.resolveDidDocument(kid) + const verificationMethod = didDocument.dereferenceKey(kid, ['authentication', 'assertionMethod']) + const key = getKeyFromVerificationMethod(verificationMethod) + return getJwkFromKey(key) + }, + }) + + if (!isValid) throw new CredoError('Could not verify JWT signature.') + + // TODO: the jws service should return some better decoded metadata also from the resolver + // as currently is less useful if you afterwards need properties from the JWS + const firstJws = jws.signatures[0] + const protectedHeader = JsonEncoder.fromBase64(firstJws.protected) + return { + jwt: { header: protectedHeader, payload: JsonEncoder.fromBase64(jws.payload) }, + kid: protectedHeader.kid, + jwk: protectedHeader.jwk ? getJwkFromJson(protectedHeader.jwk) : undefined, + did: didDocument?.id, + alg: protectedHeader.alg, + didDocument, + } + } + } + + private getVcIssuer(agentContext: AgentContext, issuer: OpenId4VcIssuerRecord) { + const issuerMetadata = this.getIssuerMetadata(agentContext, issuer) + + const builder = new VcIssuerBuilder() + .withCredentialIssuer(issuerMetadata.issuerUrl) + .withCredentialEndpoint(issuerMetadata.credentialEndpoint) + .withTokenEndpoint(issuerMetadata.tokenEndpoint) + .withCredentialsSupported(issuerMetadata.credentialsSupported) + .withCNonceStateManager(this.openId4VcIssuerConfig.getCNonceStateManager(agentContext)) + .withCredentialOfferStateManager(this.openId4VcIssuerConfig.getCredentialOfferSessionStateManager(agentContext)) + .withCredentialOfferURIStateManager(this.openId4VcIssuerConfig.getUriStateManager(agentContext)) + .withJWTVerifyCallback(this.getJwtVerifyCallback(agentContext)) + .withCredentialSignerCallback(() => { + throw new CredoError('Credential signer callback should be overwritten. This is a no-op') + }) + + if (issuerMetadata.authorizationServer) { + builder.withAuthorizationServer(issuerMetadata.authorizationServer) + } + + if (issuerMetadata.issuerDisplay) { + builder.withIssuerDisplay(issuerMetadata.issuerDisplay) + } + + return builder.build() + } + + private async getGrantsFromConfig( + agentContext: AgentContext, + preAuthorizedCodeFlowConfig?: OpenId4VciPreAuthorizedCodeFlowConfig, + authorizationCodeFlowConfig?: OpenId4VciAuthorizationCodeFlowConfig + ) { + if (!preAuthorizedCodeFlowConfig && !authorizationCodeFlowConfig) { + throw new CredoError(`Either preAuthorizedCodeFlowConfig or authorizationCodeFlowConfig must be provided.`) + } + + const grants: Grant = { + 'urn:ietf:params:oauth:grant-type:pre-authorized_code': preAuthorizedCodeFlowConfig && { + 'pre-authorized_code': + preAuthorizedCodeFlowConfig.preAuthorizedCode ?? (await agentContext.wallet.generateNonce()), + user_pin_required: preAuthorizedCodeFlowConfig.userPinRequired ?? false, + }, + + authorization_code: authorizationCodeFlowConfig && { + issuer_state: authorizationCodeFlowConfig.issuerState ?? (await agentContext.wallet.generateNonce()), + }, + } + + return grants + } + + private findOfferedCredentialsMatchingRequest( + credentialOffer: OpenId4VciCredentialOfferPayload, + credentialRequest: OpenId4VciCredentialRequest, + credentialsSupported: OpenId4VciCredentialSupported[] + ): OpenId4VciCredentialSupported[] { + const offeredCredentials = getOfferedCredentials(credentialOffer.credentials, credentialsSupported) + + return offeredCredentials.filter((offeredCredential) => { + if (offeredCredential.format !== credentialRequest.format) return false + + if ( + credentialRequest.format === OpenId4VciCredentialFormatProfile.JwtVcJson && + offeredCredential.format === credentialRequest.format + ) { + return equalsIgnoreOrder(offeredCredential.types, credentialRequest.types) + } else if ( + credentialRequest.format === OpenId4VciCredentialFormatProfile.JwtVcJsonLd && + offeredCredential.format === credentialRequest.format + ) { + return equalsIgnoreOrder(offeredCredential.types, credentialRequest.credential_definition.types) + } else if ( + credentialRequest.format === OpenId4VciCredentialFormatProfile.LdpVc && + offeredCredential.format === credentialRequest.format + ) { + return equalsIgnoreOrder(offeredCredential.types, credentialRequest.credential_definition.types) + } else if ( + credentialRequest.format === OpenId4VciCredentialFormatProfile.SdJwtVc && + offeredCredential.format === credentialRequest.format + ) { + return offeredCredential.vct === credentialRequest.vct + } + + return false + }) + } + + private getSdJwtVcCredentialSigningCallback = ( + agentContext: AgentContext, + options: OpenId4VciSignSdJwtCredential + ): CredentialSignerCallback => { + return async () => { + const sdJwtVcApi = agentContext.dependencyManager.resolve(SdJwtVcApi) + + const sdJwtVc = await sdJwtVcApi.sign(options) + return getSphereonVerifiableCredential(sdJwtVc) + } + } + + private getW3cCredentialSigningCallback = ( + agentContext: AgentContext, + options: OpenId4VciSignW3cCredential + ): CredentialSignerCallback => { + return async (opts) => { + const { jwtVerifyResult, format } = opts + const { kid, didDocument: holderDidDocument } = jwtVerifyResult + + if (!kid) throw new CredoError('Missing Kid. Cannot create the holder binding') + if (!holderDidDocument) throw new CredoError('Missing did document. Cannot create the holder binding.') + if (!format) throw new CredoError('Missing format. Cannot issue credential.') + + const formatMap: Record = { + [OpenId4VciCredentialFormatProfile.JwtVcJson]: ClaimFormat.JwtVc, + [OpenId4VciCredentialFormatProfile.JwtVcJsonLd]: ClaimFormat.JwtVc, + [OpenId4VciCredentialFormatProfile.LdpVc]: ClaimFormat.LdpVc, + } + const w3cServiceFormat = formatMap[format] + + // Set the binding on the first credential subject if not set yet + // on any subject + if (!options.credential.credentialSubjectIds.includes(holderDidDocument.id)) { + const credentialSubject = Array.isArray(options.credential.credentialSubject) + ? options.credential.credentialSubject[0] + : options.credential.credentialSubject + credentialSubject.id = holderDidDocument.id + } + + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const issuerDidDocument = await didsApi.resolveDidDocument(options.verificationMethod) + const verificationMethod = issuerDidDocument.dereferenceVerificationMethod(options.verificationMethod) + + if (w3cServiceFormat === ClaimFormat.JwtVc) { + const key = getKeyFromVerificationMethod(verificationMethod) + const alg = getJwkFromKey(key).supportedSignatureAlgorithms[0] + + if (!alg) { + throw new CredoError(`No supported JWA signature algorithms for key type ${key.keyType}`) + } + + const signed = await this.w3cCredentialService.signCredential(agentContext, { + format: w3cServiceFormat, + credential: options.credential, + verificationMethod: options.verificationMethod, + alg, + }) + + return getSphereonVerifiableCredential(signed) + } else { + const key = getKeyFromVerificationMethod(verificationMethod) + const proofType = getProofTypeFromKey(agentContext, key) + + const signed = await this.w3cCredentialService.signCredential(agentContext, { + format: w3cServiceFormat, + credential: options.credential, + verificationMethod: options.verificationMethod, + proofType: proofType, + }) + + return getSphereonVerifiableCredential(signed) + } + } + } + + private async getHolderBindingFromRequest(credentialRequest: OpenId4VciCredentialRequest) { + if (!credentialRequest.proof?.jwt) throw new CredoError('Received a credential request without a proof') + + const jwt = Jwt.fromSerializedJwt(credentialRequest.proof.jwt) + + if (jwt.header.kid) { + if (!jwt.header.kid.startsWith('did:')) { + throw new CredoError("Only did is supported for 'kid' identifier") + } else if (!jwt.header.kid.includes('#')) { + throw new CredoError( + `kid containing did MUST point to a specific key within the did document: ${jwt.header.kid}` + ) + } + + return { + method: 'did', + didUrl: jwt.header.kid, + } satisfies OpenId4VcCredentialHolderBinding + } else if (jwt.header.jwk) { + return { + method: 'jwk', + jwk: getJwkFromJson(jwt.header.jwk), + } satisfies OpenId4VcCredentialHolderBinding + } else { + throw new CredoError('Either kid or jwk must be present in credential request proof header') + } + } + + private getCredentialDataSupplier = ( + agentContext: AgentContext, + options: OpenId4VciCreateCredentialResponseOptions & { issuer: OpenId4VcIssuerRecord } + ): CredentialDataSupplier => { + return async (args: CredentialDataSupplierArgs) => { + const { credentialRequest, credentialOffer } = args + const issuerMetadata = this.getIssuerMetadata(agentContext, options.issuer) + + const offeredCredentialsMatchingRequest = this.findOfferedCredentialsMatchingRequest( + credentialOffer.credential_offer, + credentialRequest, + issuerMetadata.credentialsSupported + ) + + if (offeredCredentialsMatchingRequest.length === 0) { + throw new CredoError('No offered credentials match the credential request.') + } + + if (offeredCredentialsMatchingRequest.length > 1) { + agentContext.config.logger.debug( + 'Multiple credentials from credentials supported matching request, picking first one.' + ) + } + + const holderBinding = await this.getHolderBindingFromRequest(credentialRequest) + const mapper = + options.credentialRequestToCredentialMapper ?? + this.openId4VcIssuerConfig.credentialEndpoint.credentialRequestToCredentialMapper + const signOptions = await mapper({ + agentContext, + holderBinding, + + credentialOffer, + credentialRequest, + + credentialsSupported: offeredCredentialsMatchingRequest, + }) + + if (signOptions.format === ClaimFormat.JwtVc || signOptions.format === ClaimFormat.LdpVc) { + if (!w3cOpenId4VcFormats.includes(credentialRequest.format as OpenId4VciCredentialFormatProfile)) { + throw new CredoError( + `The credential to be issued does not match the request. Cannot issue a W3cCredential if the client expects a credential of format '${credentialRequest.format}'.` + ) + } + + return { + format: credentialRequest.format, + credential: JsonTransformer.toJSON(signOptions.credential) as ICredential, + signCallback: this.getW3cCredentialSigningCallback(agentContext, signOptions), + } + } else if (signOptions.format === ClaimFormat.SdJwtVc) { + if (credentialRequest.format !== OpenId4VciCredentialFormatProfile.SdJwtVc) { + throw new CredoError( + `Invalid credential format. Expected '${OpenId4VciCredentialFormatProfile.SdJwtVc}', received '${credentialRequest.format}'.` + ) + } + if (credentialRequest.vct !== signOptions.payload.vct) { + throw new CredoError( + `The types of the offered credentials do not match the types of the requested credential. Offered '${signOptions.payload.vct}' Requested '${credentialRequest.vct}'.` + ) + } + + return { + format: credentialRequest.format, + // NOTE: we don't use the credential value here as we pass the credential directly to the singer + credential: { ...signOptions.payload } as unknown as CredentialIssuanceInput, + signCallback: this.getSdJwtVcCredentialSigningCallback(agentContext, signOptions), + } + } else { + throw new CredoError(`Unsupported credential format`) + } + } + } +} diff --git a/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerServiceOptions.ts b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerServiceOptions.ts new file mode 100644 index 0000000000..407bad3a09 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/OpenId4VcIssuerServiceOptions.ts @@ -0,0 +1,120 @@ +import type { + OpenId4VcCredentialHolderBinding, + OpenId4VciCredentialOffer, + OpenId4VciCredentialRequest, + OpenId4VciCredentialSupported, + OpenId4VciCredentialSupportedWithId, + OpenId4VciIssuerMetadataDisplay, +} from '../shared' +import type { AgentContext, ClaimFormat, W3cCredential, SdJwtVcSignOptions } from '@credo-ts/core' + +export interface OpenId4VciPreAuthorizedCodeFlowConfig { + preAuthorizedCode?: string + userPinRequired?: boolean +} + +export type OpenId4VciAuthorizationCodeFlowConfig = { + issuerState?: string +} + +export type OpenId4VcIssuerMetadata = { + // The Credential Issuer's identifier. (URL using the https scheme) + issuerUrl: string + credentialEndpoint: string + tokenEndpoint: string + authorizationServer?: string + + issuerDisplay?: OpenId4VciIssuerMetadataDisplay[] + credentialsSupported: OpenId4VciCredentialSupported[] +} + +export interface OpenId4VciCreateCredentialOfferOptions { + // NOTE: v11 of OID4VCI supports both inline and referenced (to credentials_supported.id) credential offers. + // In draft 12 the inline credential offers have been removed and to make the migration to v12 easier + // we only support referenced credentials in an offer + offeredCredentials: string[] + + /** + * baseUri for the credential offer uri. By default `openid-credential-offer://` will be used + * if no value is provided. If a value is provided, make sure it contains the scheme as well as `://`. + */ + baseUri?: string + + preAuthorizedCodeFlowConfig?: OpenId4VciPreAuthorizedCodeFlowConfig + authorizationCodeFlowConfig?: OpenId4VciAuthorizationCodeFlowConfig + + /** + * You can provide a `hostedCredentialOfferUrl` if the created credential offer + * should points to a hosted credential offer in the `credential_offer_uri` field + * of the credential offer. + */ + hostedCredentialOfferUrl?: string +} + +export interface OpenId4VciCreateCredentialResponseOptions { + credentialRequest: OpenId4VciCredentialRequest + + /** + * You can optionally provide a credential request to credential mapper that will be + * dynamically invoked to return credential data based on the credential request. + * + * If not provided, the `credentialRequestToCredentialMapper` from the agent config + * will be used. + */ + credentialRequestToCredentialMapper?: OpenId4VciCredentialRequestToCredentialMapper +} + +// FIXME: Flows: +// - provide credential data at time of offer creation (NOT SUPPORTED) +// - provide credential data at time of calling createCredentialResponse (partially supported by passing in mapper to this method -> preferred as it gives you request data dynamically) +// - provide credential data dynamically using this method (SUPPORTED) +// mapper should get input data passed (which is supplied to offer or create response) like credentialDataSupplierInput in sphereon lib +export type OpenId4VciCredentialRequestToCredentialMapper = (options: { + agentContext: AgentContext + + /** + * The credential request received from the wallet + */ + credentialRequest: OpenId4VciCredentialRequest + + /** + * The offer associated with the credential request + */ + credentialOffer: OpenId4VciCredentialOffer + + /** + * Verified key binding material that should be included in the credential + * + * Can either be bound to did or a JWK (in case of for ex. SD-JWT) + */ + holderBinding: OpenId4VcCredentialHolderBinding + + /** + * The credentials supported entries from the issuer metadata that were offered + * and match the incoming request + * + * NOTE: in v12 this will probably become a single entry, as it will be matched on id + */ + credentialsSupported: OpenId4VciCredentialSupported[] +}) => Promise | OpenId4VciSignCredential + +export type OpenId4VciSignCredential = OpenId4VciSignSdJwtCredential | OpenId4VciSignW3cCredential +export interface OpenId4VciSignSdJwtCredential extends SdJwtVcSignOptions { + format: ClaimFormat.SdJwtVc | `${ClaimFormat.SdJwtVc}` +} + +export interface OpenId4VciSignW3cCredential { + format: ClaimFormat.JwtVc | `${ClaimFormat.JwtVc}` | ClaimFormat.LdpVc | `${ClaimFormat.LdpVc}` + verificationMethod: string + credential: W3cCredential +} + +export interface OpenId4VciCreateIssuerOptions { + /** + * Id of the issuer, not the id of the issuer record. Will be exposed publicly + */ + issuerId?: string + + credentialsSupported: OpenId4VciCredentialSupportedWithId[] + display?: OpenId4VciIssuerMetadataDisplay[] +} diff --git a/packages/openid4vc/src/openid4vc-issuer/__tests__/OpenId4VcIsserModule.test.ts b/packages/openid4vc/src/openid4vc-issuer/__tests__/OpenId4VcIsserModule.test.ts new file mode 100644 index 0000000000..dcd8d8c9ae --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/__tests__/OpenId4VcIsserModule.test.ts @@ -0,0 +1,50 @@ +import type { DependencyManager } from '@credo-ts/core' + +import { Router } from 'express' + +import { getAgentContext } from '../../../../core/tests' +import { OpenId4VcIssuerModule } from '../OpenId4VcIssuerModule' +import { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig' +import { OpenId4VcIssuerService } from '../OpenId4VcIssuerService' +import { OpenId4VcIssuerRepository } from '../repository/OpenId4VcIssuerRepository' + +const dependencyManager = { + registerInstance: jest.fn(), + registerSingleton: jest.fn(), + registerContextScoped: jest.fn(), + resolve: jest.fn().mockReturnValue({ logger: { warn: jest.fn() } }), +} as unknown as DependencyManager + +const agentContext = getAgentContext() + +describe('OpenId4VcIssuerModule', () => { + test('registers dependencies on the dependency manager', async () => { + const options = { + baseUrl: 'http://localhost:3000', + endpoints: { + credential: { + credentialRequestToCredentialMapper: () => { + throw new Error('Not implemented') + }, + }, + }, + router: Router(), + } as const + const openId4VcClientModule = new OpenId4VcIssuerModule(options) + openId4VcClientModule.register(dependencyManager) + + expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(1) + expect(dependencyManager.registerInstance).toHaveBeenCalledWith( + OpenId4VcIssuerModuleConfig, + new OpenId4VcIssuerModuleConfig(options) + ) + + expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) + expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OpenId4VcIssuerService) + expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OpenId4VcIssuerRepository) + + await openId4VcClientModule.initialize(agentContext) + + expect(openId4VcClientModule.config.router).toBeDefined() + }) +}) diff --git a/packages/openid4vc/src/openid4vc-issuer/__tests__/openid4vc-issuer.e2e.test.ts b/packages/openid4vc/src/openid4vc-issuer/__tests__/openid4vc-issuer.e2e.test.ts new file mode 100644 index 0000000000..68d5b15ae8 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/__tests__/openid4vc-issuer.e2e.test.ts @@ -0,0 +1,740 @@ +import type { OpenId4VciCredentialRequest, OpenId4VciCredentialSupportedWithId } from '../../shared' +import type { + OpenId4VcIssuerMetadata, + OpenId4VciCredentialRequestToCredentialMapper, +} from '../OpenId4VcIssuerServiceOptions' +import type { OpenId4VcIssuerRecord } from '../repository' +import type { + AgentContext, + KeyDidCreateOptions, + VerificationMethod, + W3cVerifiableCredential, + W3cVerifyCredentialResult, +} from '@credo-ts/core' +import type { OriginalVerifiableCredential as SphereonW3cVerifiableCredential } from '@sphereon/ssi-types' + +import { + SdJwtVcApi, + JwtPayload, + Agent, + CredoError, + DidKey, + DidsApi, + JsonTransformer, + JwsService, + KeyType, + TypedArrayEncoder, + W3cCredential, + W3cCredentialService, + W3cCredentialSubject, + W3cIssuer, + W3cJsonLdVerifiableCredential, + W3cJwtVerifiableCredential, + equalsIgnoreOrder, + getJwkFromKey, + getKeyFromVerificationMethod, + w3cDate, +} from '@credo-ts/core' + +import { AskarModule } from '../../../../askar/src' +import { askarModuleConfig } from '../../../../askar/tests/helpers' +import { agentDependencies } from '../../../../node/src' +import { OpenId4VciCredentialFormatProfile } from '../../shared' +import { OpenId4VcIssuerModule } from '../OpenId4VcIssuerModule' +import { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig' + +const openBadgeCredential = { + id: 'https://openid4vc-issuer.com/credentials/OpenBadgeCredential', + format: OpenId4VciCredentialFormatProfile.JwtVcJson, + types: ['VerifiableCredential', 'OpenBadgeCredential'], +} satisfies OpenId4VciCredentialSupportedWithId + +const universityDegreeCredential = { + id: 'https://openid4vc-issuer.com/credentials/UniversityDegreeCredential', + format: OpenId4VciCredentialFormatProfile.JwtVcJson, + types: ['VerifiableCredential', 'UniversityDegreeCredential'], +} satisfies OpenId4VciCredentialSupportedWithId + +const universityDegreeCredentialLd = { + id: 'https://openid4vc-issuer.com/credentials/UniversityDegreeCredentialLd', + format: OpenId4VciCredentialFormatProfile.JwtVcJsonLd, + '@context': [], + types: ['VerifiableCredential', 'UniversityDegreeCredential'], +} satisfies OpenId4VciCredentialSupportedWithId + +const universityDegreeCredentialSdJwt = { + id: 'https://openid4vc-issuer.com/credentials/UniversityDegreeCredentialSdJwt', + format: OpenId4VciCredentialFormatProfile.SdJwtVc, + vct: 'UniversityDegreeCredential', +} satisfies OpenId4VciCredentialSupportedWithId + +const modules = { + openId4VcIssuer: new OpenId4VcIssuerModule({ + baseUrl: 'https://openid4vc-issuer.com', + endpoints: { + credential: { + credentialRequestToCredentialMapper: () => { + throw new Error('Not implemented') + }, + }, + }, + }), + askar: new AskarModule(askarModuleConfig), +} + +const jwsService = new JwsService() + +const createCredentialRequest = async ( + agentContext: AgentContext, + options: { + issuerMetadata: OpenId4VcIssuerMetadata + credentialSupported: OpenId4VciCredentialSupportedWithId + nonce: string + kid: string + clientId?: string // use with the authorization code flow, + } +): Promise => { + const { credentialSupported, kid, nonce, issuerMetadata, clientId } = options + + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const didDocument = await didsApi.resolveDidDocument(kid) + if (!didDocument.verificationMethod) { + throw new CredoError(`No verification method found for kid ${kid}`) + } + + const verificationMethod = didDocument.dereferenceKey(kid, ['authentication', 'assertionMethod']) + const key = getKeyFromVerificationMethod(verificationMethod) + const jwk = getJwkFromKey(key) + + const jws = await jwsService.createJwsCompact(agentContext, { + protectedHeaderOptions: { alg: jwk.supportedSignatureAlgorithms[0], kid, typ: 'openid4vci-proof+jwt' }, + payload: new JwtPayload({ + iat: Math.floor(Date.now() / 1000), // unix time + iss: clientId, + aud: issuerMetadata.issuerUrl, + additionalClaims: { + nonce, + }, + }), + key, + }) + + if (credentialSupported.format === OpenId4VciCredentialFormatProfile.JwtVcJson) { + return { ...credentialSupported, proof: { jwt: jws, proof_type: 'jwt' } } + } else if ( + credentialSupported.format === OpenId4VciCredentialFormatProfile.JwtVcJsonLd || + credentialSupported.format === OpenId4VciCredentialFormatProfile.LdpVc + ) { + return { + format: credentialSupported.format, + credential_definition: { '@context': credentialSupported['@context'], types: credentialSupported.types }, + proof: { jwt: jws, proof_type: 'jwt' }, + } + } else if (credentialSupported.format === OpenId4VciCredentialFormatProfile.SdJwtVc) { + return { ...credentialSupported, proof: { jwt: jws, proof_type: 'jwt' } } + } + + throw new Error('Unsupported format') +} + +const issuer = new Agent({ + config: { + label: 'OpenId4VcIssuer Test323', + walletConfig: { + id: 'openid4vc-Issuer-test323', + key: 'openid4vc-Issuer-test323', + }, + }, + dependencies: agentDependencies, + modules, +}) + +const holder = new Agent({ + config: { + label: 'OpenId4VciIssuer(Holder) Test323', + walletConfig: { + id: 'openid4vc-Issuer(Holder)-test323', + key: 'openid4vc-Issuer(Holder)-test323', + }, + }, + dependencies: agentDependencies, + modules, +}) + +describe('OpenId4VcIssuer', () => { + let issuerVerificationMethod: VerificationMethod + let issuerDid: string + let openId4VcIssuer: OpenId4VcIssuerRecord + + let holderKid: string + let holderVerificationMethod: VerificationMethod + let holderDid: string + + beforeEach(async () => { + await issuer.initialize() + await holder.initialize() + + const holderDidCreateResult = await holder.dids.create({ + method: 'key', + options: { keyType: KeyType.Ed25519 }, + secret: { privateKey: TypedArrayEncoder.fromString('96213c3d7fc8d4d6754c7a0fd969598e') }, + }) + + holderDid = holderDidCreateResult.didState.did as string + const holderDidKey = DidKey.fromDid(holderDid) + holderKid = `${holderDid}#${holderDidKey.key.fingerprint}` + const _holderVerificationMethod = holderDidCreateResult.didState.didDocument?.dereferenceKey(holderKid, [ + 'authentication', + ]) + if (!_holderVerificationMethod) throw new Error('No verification method found') + holderVerificationMethod = _holderVerificationMethod + + const issuerDidCreateResult = await issuer.dids.create({ + method: 'key', + options: { keyType: KeyType.Ed25519 }, + secret: { privateKey: TypedArrayEncoder.fromString('96213c3d7fc8d4d6754c7a0fd969598f') }, + }) + + issuerDid = issuerDidCreateResult.didState.did as string + + const issuerDidKey = DidKey.fromDid(issuerDid) + const issuerKid = `${issuerDid}#${issuerDidKey.key.fingerprint}` + const _issuerVerificationMethod = issuerDidCreateResult.didState.didDocument?.dereferenceKey(issuerKid, [ + 'authentication', + ]) + if (!_issuerVerificationMethod) throw new Error('No verification method found') + issuerVerificationMethod = _issuerVerificationMethod + + openId4VcIssuer = await issuer.modules.openId4VcIssuer.createIssuer({ + credentialsSupported: [ + openBadgeCredential, + universityDegreeCredential, + universityDegreeCredentialLd, + universityDegreeCredentialSdJwt, + ], + }) + }) + + afterEach(async () => { + await issuer.shutdown() + await issuer.wallet.delete() + + await holder.shutdown() + await holder.wallet.delete() + }) + + // This method is available on the holder service, + // would be nice to reuse + async function handleCredentialResponse( + agentContext: AgentContext, + sphereonVerifiableCredential: SphereonW3cVerifiableCredential, + credentialSupported: OpenId4VciCredentialSupportedWithId + ) { + if (credentialSupported.format === 'vc+sd-jwt' && typeof sphereonVerifiableCredential === 'string') { + const api = agentContext.dependencyManager.resolve(SdJwtVcApi) + await api.verify({ compactSdJwtVc: sphereonVerifiableCredential }) + return + } + + const w3cCredentialService = holder.context.dependencyManager.resolve(W3cCredentialService) + + let result: W3cVerifyCredentialResult + let w3cVerifiableCredential: W3cVerifiableCredential + + if (typeof sphereonVerifiableCredential === 'string') { + if (credentialSupported.format !== 'jwt_vc_json' && credentialSupported.format !== 'jwt_vc_json-ld') { + throw new Error(`Invalid format. ${credentialSupported.format}`) + } + w3cVerifiableCredential = W3cJwtVerifiableCredential.fromSerializedJwt(sphereonVerifiableCredential) + result = await w3cCredentialService.verifyCredential(holder.context, { credential: w3cVerifiableCredential }) + } else if (credentialSupported.format === 'ldp_vc') { + if (credentialSupported.format !== 'ldp_vc') throw new Error('Invalid format') + // validate jwt credentials + + w3cVerifiableCredential = JsonTransformer.fromJSON(sphereonVerifiableCredential, W3cJsonLdVerifiableCredential) + result = await w3cCredentialService.verifyCredential(holder.context, { credential: w3cVerifiableCredential }) + } else { + throw new CredoError(`Unsupported credential format`) + } + + if (!result.isValid) { + holder.context.config.logger.error('Failed to validate credential', { result }) + throw new CredoError(`Failed to validate credential, error = ${result.error?.message ?? 'Unknown'}`) + } + + if (equalsIgnoreOrder(w3cVerifiableCredential.type, credentialSupported.types) === false) { + throw new Error('Invalid credential type') + } + return w3cVerifiableCredential + } + + it('pre authorized code flow (sd-jwt-vc)', async () => { + const cNonce = '1234' + const preAuthorizedCode = '1234567890' + + await issuer.modules.openId4VcIssuer.config + .getCNonceStateManager(issuer.context) + .set(cNonce, { cNonce: cNonce, createdAt: Date.now(), preAuthorizedCode }) + + const result = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + issuerId: openId4VcIssuer.issuerId, + offeredCredentials: [universityDegreeCredentialSdJwt.id], + preAuthorizedCodeFlowConfig: { + preAuthorizedCode, + userPinRequired: false, + }, + }) + + expect(result.credentialOfferPayload).toEqual({ + credential_issuer: `https://openid4vc-issuer.com/${openId4VcIssuer.issuerId}`, + credentials: ['https://openid4vc-issuer.com/credentials/UniversityDegreeCredentialSdJwt'], + grants: { + authorization_code: undefined, + 'urn:ietf:params:oauth:grant-type:pre-authorized_code': { + 'pre-authorized_code': '1234567890', + user_pin_required: false, + }, + }, + }) + + expect(result.credentialOffer).toEqual( + `openid-credential-offer://?credential_offer=%7B%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%221234567890%22%2C%22user_pin_required%22%3Afalse%7D%7D%2C%22credentials%22%3A%5B%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FUniversityDegreeCredentialSdJwt%22%5D%2C%22credential_issuer%22%3A%22https%3A%2F%2Fopenid4vc-issuer.com%2F${openId4VcIssuer.issuerId}%22%7D` + ) + + const issuerMetadata = await issuer.modules.openId4VcIssuer.getIssuerMetadata(openId4VcIssuer.issuerId) + const credentialRequest = await createCredentialRequest(holder.context, { + credentialSupported: universityDegreeCredentialSdJwt, + issuerMetadata, + kid: holderKid, + nonce: cNonce, + }) + + const issueCredentialResponse = await issuer.modules.openId4VcIssuer.createCredentialResponse({ + issuerId: openId4VcIssuer.issuerId, + credentialRequest, + + credentialRequestToCredentialMapper: () => ({ + format: 'vc+sd-jwt', + payload: { vct: 'UniversityDegreeCredential', university: 'innsbruck', degree: 'bachelor' }, + issuer: { method: 'did', didUrl: issuerVerificationMethod.id }, + holder: { method: 'did', didUrl: holderVerificationMethod.id }, + disclosureFrame: { university: true, degree: true }, + }), + }) + + const sphereonW3cCredential = issueCredentialResponse.credential + if (!sphereonW3cCredential) throw new Error('No credential found') + + expect(issueCredentialResponse).toEqual({ + c_nonce: expect.any(String), + c_nonce_expires_in: 300000, + credential: expect.any(String), + format: 'vc+sd-jwt', + }) + + await handleCredentialResponse(holder.context, sphereonW3cCredential, universityDegreeCredentialSdJwt) + }) + + it('pre authorized code flow (jwt-vc-json)', async () => { + const cNonce = '1234' + const preAuthorizedCode = '1234567890' + + await issuer.context.dependencyManager + .resolve(OpenId4VcIssuerModuleConfig) + .getCNonceStateManager(issuer.context) + .set(cNonce, { cNonce: cNonce, createdAt: Date.now(), preAuthorizedCode }) + + const result = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + issuerId: openId4VcIssuer.issuerId, + offeredCredentials: [openBadgeCredential.id], + preAuthorizedCodeFlowConfig: { + preAuthorizedCode, + userPinRequired: false, + }, + }) + + expect(result.credentialOffer).toEqual( + `openid-credential-offer://?credential_offer=%7B%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%221234567890%22%2C%22user_pin_required%22%3Afalse%7D%7D%2C%22credentials%22%3A%5B%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FOpenBadgeCredential%22%5D%2C%22credential_issuer%22%3A%22https%3A%2F%2Fopenid4vc-issuer.com%2F${openId4VcIssuer.issuerId}%22%7D` + ) + + const issuerMetadata = await issuer.modules.openId4VcIssuer.getIssuerMetadata(openId4VcIssuer.issuerId) + const issueCredentialResponse = await issuer.modules.openId4VcIssuer.createCredentialResponse({ + issuerId: openId4VcIssuer.issuerId, + credentialRequestToCredentialMapper: () => ({ + format: 'jwt_vc', + credential: new W3cCredential({ + type: openBadgeCredential.types, + issuer: new W3cIssuer({ id: issuerDid }), + credentialSubject: new W3cCredentialSubject({ id: holderDid }), + issuanceDate: w3cDate(Date.now()), + }), + verificationMethod: issuerVerificationMethod.id, + }), + credentialRequest: await createCredentialRequest(holder.context, { + credentialSupported: openBadgeCredential, + issuerMetadata, + kid: holderKid, + nonce: cNonce, + }), + }) + + const sphereonW3cCredential = issueCredentialResponse.credential + if (!sphereonW3cCredential) throw new Error('No credential found') + + expect(issueCredentialResponse).toEqual({ + c_nonce: expect.any(String), + c_nonce_expires_in: 300000, + credential: expect.any(String), + format: 'jwt_vc_json', + }) + + await handleCredentialResponse(holder.context, sphereonW3cCredential, openBadgeCredential) + }) + + it('credential id not in credential supported errors', async () => { + const cNonce = '1234' + const preAuthorizedCode = '1234567890' + + await issuer.context.dependencyManager + .resolve(OpenId4VcIssuerModuleConfig) + .getCNonceStateManager(issuer.context) + .set(cNonce, { cNonce: cNonce, createdAt: Date.now(), preAuthorizedCode }) + + await expect( + issuer.modules.openId4VcIssuer.createCredentialOffer({ + issuerId: openId4VcIssuer.issuerId, + offeredCredentials: ['invalid id'], + preAuthorizedCodeFlowConfig: { + preAuthorizedCode, + userPinRequired: false, + }, + }) + ).rejects.toThrowError( + "Offered credential 'invalid id' is not part of credentials_supported of the issuer metadata." + ) + }) + + it('issuing non offered credential errors', async () => { + const cNonce = '1234' + const preAuthorizedCode = '1234567890' + + await issuer.context.dependencyManager + .resolve(OpenId4VcIssuerModuleConfig) + .getCNonceStateManager(issuer.context) + .set(cNonce, { cNonce: cNonce, createdAt: Date.now(), preAuthorizedCode }) + + const result = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + issuerId: openId4VcIssuer.issuerId, + offeredCredentials: [openBadgeCredential.id], + preAuthorizedCodeFlowConfig: { + preAuthorizedCode, + userPinRequired: false, + }, + }) + + expect(result.credentialOffer).toEqual( + `openid-credential-offer://?credential_offer=%7B%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%221234567890%22%2C%22user_pin_required%22%3Afalse%7D%7D%2C%22credentials%22%3A%5B%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FOpenBadgeCredential%22%5D%2C%22credential_issuer%22%3A%22https%3A%2F%2Fopenid4vc-issuer.com%2F${openId4VcIssuer.issuerId}%22%7D` + ) + + const issuerMetadata = await issuer.modules.openId4VcIssuer.getIssuerMetadata(openId4VcIssuer.issuerId) + await expect( + issuer.modules.openId4VcIssuer.createCredentialResponse({ + issuerId: openId4VcIssuer.issuerId, + + credentialRequest: await createCredentialRequest(holder.context, { + credentialSupported: universityDegreeCredential, + issuerMetadata, + kid: holderKid, + nonce: cNonce, + }), + credentialRequestToCredentialMapper: () => { + throw new Error('Not implemented') + }, + }) + ).rejects.toThrowError('No offered credentials match the credential request.') + }) + + it('pre authorized code flow using multiple credentials_supported', async () => { + const cNonce = '1234' + const preAuthorizedCode = '1234567890' + + await issuer.context.dependencyManager + .resolve(OpenId4VcIssuerModuleConfig) + .getCNonceStateManager(issuer.context) + .set(cNonce, { cNonce: cNonce, createdAt: Date.now(), preAuthorizedCode }) + + const result = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + offeredCredentials: [openBadgeCredential.id, universityDegreeCredentialLd.id], + issuerId: openId4VcIssuer.issuerId, + preAuthorizedCodeFlowConfig: { + preAuthorizedCode, + userPinRequired: false, + }, + }) + + expect(result.credentialOffer).toEqual( + `openid-credential-offer://?credential_offer=%7B%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%221234567890%22%2C%22user_pin_required%22%3Afalse%7D%7D%2C%22credentials%22%3A%5B%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FOpenBadgeCredential%22%2C%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FUniversityDegreeCredentialLd%22%5D%2C%22credential_issuer%22%3A%22https%3A%2F%2Fopenid4vc-issuer.com%2F${openId4VcIssuer.issuerId}%22%7D` + ) + + const issuerMetadata = await issuer.modules.openId4VcIssuer.getIssuerMetadata(openId4VcIssuer.issuerId) + const issueCredentialResponse = await issuer.modules.openId4VcIssuer.createCredentialResponse({ + issuerId: openId4VcIssuer.issuerId, + credentialRequest: await createCredentialRequest(holder.context, { + credentialSupported: universityDegreeCredentialLd, + issuerMetadata, + kid: holderKid, + nonce: cNonce, + }), + credentialRequestToCredentialMapper: () => ({ + format: 'jwt_vc', + credential: new W3cCredential({ + type: universityDegreeCredentialLd.types, + issuer: new W3cIssuer({ id: issuerDid }), + credentialSubject: new W3cCredentialSubject({ id: holderDid }), + issuanceDate: w3cDate(Date.now()), + }), + verificationMethod: issuerVerificationMethod.id, + }), + }) + + const sphereonW3cCredential = issueCredentialResponse.credential + if (!sphereonW3cCredential) throw new Error('No credential found') + + expect(issueCredentialResponse).toEqual({ + c_nonce: expect.any(String), + c_nonce_expires_in: 300000, + credential: expect.any(String), + format: 'jwt_vc_json-ld', + }) + + await handleCredentialResponse(holder.context, sphereonW3cCredential, universityDegreeCredentialLd) + }) + + it('requesting non offered credential errors', async () => { + const cNonce = '1234' + const preAuthorizedCode = '1234567890' + + await issuer.context.dependencyManager + .resolve(OpenId4VcIssuerModuleConfig) + .getCNonceStateManager(issuer.context) + .set(cNonce, { cNonce: cNonce, createdAt: Date.now(), preAuthorizedCode }) + + const result = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + offeredCredentials: [openBadgeCredential.id], + issuerId: openId4VcIssuer.issuerId, + preAuthorizedCodeFlowConfig: { + preAuthorizedCode, + userPinRequired: false, + }, + }) + + expect(result.credentialOffer).toEqual( + `openid-credential-offer://?credential_offer=%7B%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%221234567890%22%2C%22user_pin_required%22%3Afalse%7D%7D%2C%22credentials%22%3A%5B%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FOpenBadgeCredential%22%5D%2C%22credential_issuer%22%3A%22https%3A%2F%2Fopenid4vc-issuer.com%2F${openId4VcIssuer.issuerId}%22%7D` + ) + + const issuerMetadata = await issuer.modules.openId4VcIssuer.getIssuerMetadata(openId4VcIssuer.issuerId) + await expect( + issuer.modules.openId4VcIssuer.createCredentialResponse({ + issuerId: openId4VcIssuer.issuerId, + credentialRequest: await createCredentialRequest(holder.context, { + credentialSupported: { + id: 'someid', + format: openBadgeCredential.format, + types: universityDegreeCredential.types, + }, + issuerMetadata, + kid: holderKid, + nonce: cNonce, + }), + credentialRequestToCredentialMapper: () => { + throw new Error('Not implemented') + }, + }) + ).rejects.toThrowError('No offered credentials match the credential request.') + }) + + it('authorization code flow', async () => { + const cNonce = '1234' + const issuerState = '1234567890' + + await issuer.context.dependencyManager + .resolve(OpenId4VcIssuerModuleConfig) + .getCNonceStateManager(issuer.context) + .set(cNonce, { cNonce: cNonce, createdAt: Date.now(), issuerState }) + + const result = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + offeredCredentials: [openBadgeCredential.id], + issuerId: openId4VcIssuer.issuerId, + authorizationCodeFlowConfig: { + issuerState, + }, + }) + + expect(result.credentialOffer).toEqual( + `openid-credential-offer://?credential_offer=%7B%22grants%22%3A%7B%22authorization_code%22%3A%7B%22issuer_state%22%3A%221234567890%22%7D%7D%2C%22credentials%22%3A%5B%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FOpenBadgeCredential%22%5D%2C%22credential_issuer%22%3A%22https%3A%2F%2Fopenid4vc-issuer.com%2F${openId4VcIssuer.issuerId}%22%7D` + ) + + const issuerMetadata = await issuer.modules.openId4VcIssuer.getIssuerMetadata(openId4VcIssuer.issuerId) + const issueCredentialResponse = await issuer.modules.openId4VcIssuer.createCredentialResponse({ + issuerId: openId4VcIssuer.issuerId, + credentialRequest: await createCredentialRequest(holder.context, { + credentialSupported: openBadgeCredential, + issuerMetadata, + kid: holderKid, + nonce: cNonce, + clientId: 'required', + }), + credentialRequestToCredentialMapper: () => ({ + format: 'jwt_vc', + credential: new W3cCredential({ + type: ['VerifiableCredential', 'OpenBadgeCredential'], + issuer: new W3cIssuer({ id: issuerDid }), + credentialSubject: new W3cCredentialSubject({ id: holderDid }), + issuanceDate: w3cDate(Date.now()), + }), + verificationMethod: issuerVerificationMethod.id, + }), + }) + + const sphereonW3cCredential = issueCredentialResponse.credential + if (!sphereonW3cCredential) throw new Error('No credential found') + + expect(issueCredentialResponse).toEqual({ + c_nonce: expect.any(String), + c_nonce_expires_in: 300000, + credential: expect.any(String), + format: 'jwt_vc_json', + }) + + await handleCredentialResponse(holder.context, sphereonW3cCredential, openBadgeCredential) + }) + + it('create credential offer and retrieve it from the uri (pre authorized flow)', async () => { + const preAuthorizedCode = '1234567890' + + const hostedCredentialOfferUrl = 'https://openid4vc-issuer.com/credential-offer-uri' + + const { credentialOffer, credentialOfferPayload } = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + issuerId: openId4VcIssuer.issuerId, + offeredCredentials: [openBadgeCredential.id], + hostedCredentialOfferUrl, + preAuthorizedCodeFlowConfig: { + preAuthorizedCode, + userPinRequired: false, + }, + }) + + expect(credentialOffer).toEqual(`openid-credential-offer://?credential_offer_uri=${hostedCredentialOfferUrl}`) + + const credentialOfferReceivedByUri = await issuer.modules.openId4VcIssuer.getCredentialOfferFromUri( + hostedCredentialOfferUrl + ) + + expect(credentialOfferPayload).toEqual(credentialOfferReceivedByUri) + }) + + it('create credential offer and retrieve it from the uri (authorizationCodeFlow)', async () => { + const hostedCredentialOfferUrl = 'https://openid4vc-issuer.com/credential-offer-uri' + + const { credentialOffer, credentialOfferPayload } = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + offeredCredentials: [openBadgeCredential.id], + issuerId: openId4VcIssuer.issuerId, + hostedCredentialOfferUrl, + authorizationCodeFlowConfig: { issuerState: '1234567890' }, + }) + + expect(credentialOffer).toEqual(`openid-credential-offer://?credential_offer_uri=${hostedCredentialOfferUrl}`) + + const credentialOfferReceivedByUri = await issuer.modules.openId4VcIssuer.getCredentialOfferFromUri( + hostedCredentialOfferUrl + ) + + expect(credentialOfferPayload).toEqual(credentialOfferReceivedByUri) + }) + + it('offer and request multiple credentials', async () => { + const cNonce = '1234' + const preAuthorizedCode = '1234567890' + + await issuer.context.dependencyManager + .resolve(OpenId4VcIssuerModuleConfig) + .getCNonceStateManager(issuer.context) + .set(cNonce, { cNonce: cNonce, createdAt: Date.now(), preAuthorizedCode }) + + const result = await issuer.modules.openId4VcIssuer.createCredentialOffer({ + offeredCredentials: [openBadgeCredential.id, universityDegreeCredential.id], + issuerId: openId4VcIssuer.issuerId, + preAuthorizedCodeFlowConfig: { + preAuthorizedCode, + userPinRequired: false, + }, + }) + + expect(result.credentialOffer).toEqual( + `openid-credential-offer://?credential_offer=%7B%22grants%22%3A%7B%22urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code%22%3A%7B%22pre-authorized_code%22%3A%221234567890%22%2C%22user_pin_required%22%3Afalse%7D%7D%2C%22credentials%22%3A%5B%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FOpenBadgeCredential%22%2C%22https%3A%2F%2Fopenid4vc-issuer.com%2Fcredentials%2FUniversityDegreeCredential%22%5D%2C%22credential_issuer%22%3A%22https%3A%2F%2Fopenid4vc-issuer.com%2F${openId4VcIssuer.issuerId}%22%7D` + ) + + const credentialRequestToCredentialMapper: OpenId4VciCredentialRequestToCredentialMapper = ({ + credentialsSupported, + }) => ({ + format: 'jwt_vc', + credential: new W3cCredential({ + type: + credentialsSupported[0].id === openBadgeCredential.id + ? openBadgeCredential.types + : universityDegreeCredential.types, + issuer: new W3cIssuer({ id: issuerDid }), + credentialSubject: new W3cCredentialSubject({ id: holderDid }), + issuanceDate: w3cDate(Date.now()), + }), + verificationMethod: issuerVerificationMethod.id, + }) + + const issuerMetadata = await issuer.modules.openId4VcIssuer.getIssuerMetadata(openId4VcIssuer.issuerId) + const issueCredentialResponse = await issuer.modules.openId4VcIssuer.createCredentialResponse({ + issuerId: openId4VcIssuer.issuerId, + credentialRequest: await createCredentialRequest(holder.context, { + credentialSupported: openBadgeCredential, + issuerMetadata, + kid: holderKid, + nonce: cNonce, + }), + credentialRequestToCredentialMapper, + }) + + const sphereonW3cCredential = issueCredentialResponse.credential + if (!sphereonW3cCredential) throw new Error('No credential found') + + expect(issueCredentialResponse).toEqual({ + c_nonce: expect.any(String), + c_nonce_expires_in: 300000, + credential: expect.any(String), + format: 'jwt_vc_json', + }) + + await handleCredentialResponse(holder.context, sphereonW3cCredential, openBadgeCredential) + + const issueCredentialResponse2 = await issuer.modules.openId4VcIssuer.createCredentialResponse({ + issuerId: openId4VcIssuer.issuerId, + credentialRequest: await createCredentialRequest(holder.context, { + credentialSupported: universityDegreeCredential, + issuerMetadata, + kid: holderKid, + nonce: issueCredentialResponse.c_nonce ?? cNonce, + }), + credentialRequestToCredentialMapper, + }) + + const sphereonW3cCredential2 = issueCredentialResponse2.credential + if (!sphereonW3cCredential2) throw new Error('No credential found') + + expect(issueCredentialResponse2).toEqual({ + c_nonce: expect.any(String), + c_nonce_expires_in: 300000, + credential: expect.any(String), + format: 'jwt_vc_json', + }) + + await handleCredentialResponse(holder.context, sphereonW3cCredential2, universityDegreeCredential) + }) +}) diff --git a/packages/openid4vc/src/openid4vc-issuer/index.ts b/packages/openid4vc/src/openid4vc-issuer/index.ts new file mode 100644 index 0000000000..ed7cf40ba0 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/index.ts @@ -0,0 +1,6 @@ +export * from './OpenId4VcIssuerApi' +export * from './OpenId4VcIssuerModule' +export * from './OpenId4VcIssuerService' +export * from './OpenId4VcIssuerModuleConfig' +export * from './OpenId4VcIssuerServiceOptions' +export { OpenId4VcIssuerRecord, OpenId4VcIssuerRecordProps, OpenId4VcIssuerRecordTags } from './repository' diff --git a/packages/openid4vc/src/openid4vc-issuer/repository/OpenId4VcIssuerRecord.ts b/packages/openid4vc/src/openid4vc-issuer/repository/OpenId4VcIssuerRecord.ts new file mode 100644 index 0000000000..244192dd52 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/repository/OpenId4VcIssuerRecord.ts @@ -0,0 +1,65 @@ +import type { OpenId4VciCredentialSupportedWithId, OpenId4VciIssuerMetadataDisplay } from '../../shared' +import type { RecordTags, TagsBase } from '@credo-ts/core' + +import { BaseRecord, utils } from '@credo-ts/core' + +export type OpenId4VcIssuerRecordTags = RecordTags + +export type DefaultOpenId4VcIssuerRecordTags = { + issuerId: string +} + +export interface OpenId4VcIssuerRecordProps { + id?: string + createdAt?: Date + tags?: TagsBase + + issuerId: string + + /** + * The fingerprint (multibase encoded) of the public key used to sign access tokens for + * this issuer. + */ + accessTokenPublicKeyFingerprint: string + + credentialsSupported: OpenId4VciCredentialSupportedWithId[] + display?: OpenId4VciIssuerMetadataDisplay[] +} + +/** + * For OID4VC you need to expos metadata files. Each issuer needs to host this metadata. This is not the case for DIDComm where we can just have one /didcomm endpoint. + * So we create a record per openid issuer/verifier that you want, and each tenant can create multiple issuers/verifiers which have different endpoints + * and metadata files + * */ +export class OpenId4VcIssuerRecord extends BaseRecord { + public static readonly type = 'OpenId4VcIssuerRecord' + public readonly type = OpenId4VcIssuerRecord.type + + public issuerId!: string + public accessTokenPublicKeyFingerprint!: string + + public credentialsSupported!: OpenId4VciCredentialSupportedWithId[] + public display?: OpenId4VciIssuerMetadataDisplay[] + + public constructor(props: OpenId4VcIssuerRecordProps) { + super() + + if (props) { + this.id = props.id ?? utils.uuid() + this.createdAt = props.createdAt ?? new Date() + this._tags = props.tags ?? {} + + this.issuerId = props.issuerId + this.accessTokenPublicKeyFingerprint = props.accessTokenPublicKeyFingerprint + this.credentialsSupported = props.credentialsSupported + this.display = props.display + } + } + + public getTags() { + return { + ...this._tags, + issuerId: this.issuerId, + } + } +} diff --git a/packages/openid4vc/src/openid4vc-issuer/repository/OpenId4VcIssuerRepository.ts b/packages/openid4vc/src/openid4vc-issuer/repository/OpenId4VcIssuerRepository.ts new file mode 100644 index 0000000000..50d5506df3 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/repository/OpenId4VcIssuerRepository.ts @@ -0,0 +1,23 @@ +import type { AgentContext } from '@credo-ts/core' + +import { Repository, StorageService, InjectionSymbols, EventEmitter, inject, injectable } from '@credo-ts/core' + +import { OpenId4VcIssuerRecord } from './OpenId4VcIssuerRecord' + +@injectable() +export class OpenId4VcIssuerRepository extends Repository { + public constructor( + @inject(InjectionSymbols.StorageService) storageService: StorageService, + eventEmitter: EventEmitter + ) { + super(OpenId4VcIssuerRecord, storageService, eventEmitter) + } + + public findByIssuerId(agentContext: AgentContext, issuerId: string) { + return this.findSingleByQuery(agentContext, { issuerId }) + } + + public getByIssuerId(agentContext: AgentContext, issuerId: string) { + return this.getSingleByQuery(agentContext, { issuerId }) + } +} diff --git a/packages/openid4vc/src/openid4vc-issuer/repository/index.ts b/packages/openid4vc/src/openid4vc-issuer/repository/index.ts new file mode 100644 index 0000000000..8b124ec167 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/repository/index.ts @@ -0,0 +1,2 @@ +export * from './OpenId4VcIssuerRecord' +export * from './OpenId4VcIssuerRepository' diff --git a/packages/openid4vc/src/openid4vc-issuer/router/accessTokenEndpoint.ts b/packages/openid4vc/src/openid4vc-issuer/router/accessTokenEndpoint.ts new file mode 100644 index 0000000000..1d4485edbd --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/router/accessTokenEndpoint.ts @@ -0,0 +1,154 @@ +import type { OpenId4VcIssuanceRequest } from './requestContext' +import type { AgentContext } from '@credo-ts/core' +import type { JWTSignerCallback } from '@sphereon/oid4vci-common' +import type { NextFunction, Response, Router } from 'express' + +import { getJwkFromKey, CredoError, JwsService, JwtPayload, getJwkClassFromKeyType, Key } from '@credo-ts/core' +import { + GrantTypes, + PRE_AUTHORIZED_CODE_REQUIRED_ERROR, + TokenError, + TokenErrorResponse, +} from '@sphereon/oid4vci-common' +import { assertValidAccessTokenRequest, createAccessTokenResponse } from '@sphereon/oid4vci-issuer' + +import { getRequestContext, sendErrorResponse } from '../../shared/router' +import { OpenId4VcIssuerModuleConfig } from '../OpenId4VcIssuerModuleConfig' +import { OpenId4VcIssuerService } from '../OpenId4VcIssuerService' + +export interface OpenId4VciAccessTokenEndpointConfig { + /** + * The path at which the token endpoint should be made available. Note that it will be + * hosted at a subpath to take into account multiple tenants and issuers. + * + * @default /token + */ + endpointPath: string + + /** + * The maximum amount of time in seconds that the pre-authorized code is valid. + * @default 360 (5 minutes) + */ + preAuthorizedCodeExpirationInSeconds: number + + /** + * The time after which the cNonce from the access token response will + * expire. + * + * @default 360 (5 minutes) + */ + cNonceExpiresInSeconds: number + + /** + * The time after which the token will expire. + * + * @default 360 (5 minutes) + */ + tokenExpiresInSeconds: number +} + +export function configureAccessTokenEndpoint(router: Router, config: OpenId4VciAccessTokenEndpointConfig) { + router.post( + config.endpointPath, + verifyTokenRequest({ preAuthorizedCodeExpirationInSeconds: config.preAuthorizedCodeExpirationInSeconds }), + handleTokenRequest(config) + ) +} + +function getJwtSignerCallback(agentContext: AgentContext, signerPublicKey: Key): JWTSignerCallback { + return async (jwt, _kid) => { + if (_kid) { + throw new CredoError('Kid should not be supplied externally.') + } + if (jwt.header.kid || jwt.header.jwk) { + throw new CredoError('kid or jwk should not be present in access token header before signing') + } + + const jwsService = agentContext.dependencyManager.resolve(JwsService) + + const alg = getJwkClassFromKeyType(signerPublicKey.keyType)?.supportedSignatureAlgorithms[0] + if (!alg) { + throw new CredoError(`No supported signature algorithms for key type: ${signerPublicKey.keyType}`) + } + + const jwk = getJwkFromKey(signerPublicKey) + const signedJwt = await jwsService.createJwsCompact(agentContext, { + protectedHeaderOptions: { ...jwt.header, jwk, alg }, + payload: new JwtPayload(jwt.payload), + key: signerPublicKey, + }) + + return signedJwt + } +} + +export function handleTokenRequest(config: OpenId4VciAccessTokenEndpointConfig) { + const { tokenExpiresInSeconds, cNonceExpiresInSeconds } = config + + return async (request: OpenId4VcIssuanceRequest, response: Response, next: NextFunction) => { + response.set({ 'Cache-Control': 'no-store', Pragma: 'no-cache' }) + + const requestContext = getRequestContext(request) + const { agentContext, issuer } = requestContext + + if (request.body.grant_type !== GrantTypes.PRE_AUTHORIZED_CODE) { + return response.status(400).json({ + error: TokenErrorResponse.invalid_request, + error_description: PRE_AUTHORIZED_CODE_REQUIRED_ERROR, + }) + } + + const openId4VcIssuerConfig = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig) + const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService) + const issuerMetadata = openId4VcIssuerService.getIssuerMetadata(agentContext, issuer) + const accessTokenSigningKey = Key.fromFingerprint(issuer.accessTokenPublicKeyFingerprint) + + try { + const accessTokenResponse = await createAccessTokenResponse(request.body, { + credentialOfferSessions: openId4VcIssuerConfig.getCredentialOfferSessionStateManager(agentContext), + tokenExpiresIn: tokenExpiresInSeconds, + accessTokenIssuer: issuerMetadata.issuerUrl, + cNonce: await agentContext.wallet.generateNonce(), + cNonceExpiresIn: cNonceExpiresInSeconds, + cNonces: openId4VcIssuerConfig.getCNonceStateManager(agentContext), + accessTokenSignerCallback: getJwtSignerCallback(agentContext, accessTokenSigningKey), + }) + response.status(200).json(accessTokenResponse) + } catch (error) { + sendErrorResponse(response, agentContext.config.logger, 400, TokenErrorResponse.invalid_request, error) + } + + // NOTE: if we don't call next, the agentContext session handler will NOT be called + next() + } +} + +export function verifyTokenRequest(options: { preAuthorizedCodeExpirationInSeconds: number }) { + return async (request: OpenId4VcIssuanceRequest, response: Response, next: NextFunction) => { + const { agentContext } = getRequestContext(request) + + try { + const openId4VcIssuerConfig = agentContext.dependencyManager.resolve(OpenId4VcIssuerModuleConfig) + await assertValidAccessTokenRequest(request.body, { + // we use seconds instead of milliseconds for consistency + expirationDuration: options.preAuthorizedCodeExpirationInSeconds * 1000, + credentialOfferSessions: openId4VcIssuerConfig.getCredentialOfferSessionStateManager(agentContext), + }) + } catch (error) { + if (error instanceof TokenError) { + sendErrorResponse( + response, + agentContext.config.logger, + error.statusCode, + error.responseError + error.getDescription(), + error + ) + } else { + sendErrorResponse(response, agentContext.config.logger, 400, TokenErrorResponse.invalid_request, error) + } + } + + // NOTE: if we don't call next, the agentContext session handler will NOT be called + next() + } +} diff --git a/packages/openid4vc/src/openid4vc-issuer/router/credentialEndpoint.ts b/packages/openid4vc/src/openid4vc-issuer/router/credentialEndpoint.ts new file mode 100644 index 0000000000..5986be4b1c --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/router/credentialEndpoint.ts @@ -0,0 +1,44 @@ +import type { OpenId4VcIssuanceRequest } from './requestContext' +import type { OpenId4VciCredentialRequest } from '../../shared' +import type { OpenId4VciCredentialRequestToCredentialMapper } from '../OpenId4VcIssuerServiceOptions' +import type { Router, Response } from 'express' + +import { getRequestContext, sendErrorResponse } from '../../shared/router' +import { OpenId4VcIssuerService } from '../OpenId4VcIssuerService' + +export interface OpenId4VciCredentialEndpointConfig { + /** + * The path at which the credential endpoint should be made available. Note that it will be + * hosted at a subpath to take into account multiple tenants and issuers. + * + * @default /credential + */ + endpointPath: string + + /** + * A function mapping a credential request to the credential to be issued. + */ + credentialRequestToCredentialMapper: OpenId4VciCredentialRequestToCredentialMapper +} + +export function configureCredentialEndpoint(router: Router, config: OpenId4VciCredentialEndpointConfig) { + router.post(config.endpointPath, async (request: OpenId4VcIssuanceRequest, response: Response, next) => { + const { agentContext, issuer } = getRequestContext(request) + + try { + const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService) + const credentialRequest = request.body as OpenId4VciCredentialRequest + const issueCredentialResponse = await openId4VcIssuerService.createCredentialResponse(agentContext, { + issuer, + credentialRequest, + }) + + response.json(issueCredentialResponse) + } catch (error) { + sendErrorResponse(response, agentContext.config.logger, 500, 'invalid_request', error) + } + + // NOTE: if we don't call next, the agentContext session handler will NOT be called + next() + }) +} diff --git a/packages/openid4vc/src/openid4vc-issuer/router/index.ts b/packages/openid4vc/src/openid4vc-issuer/router/index.ts new file mode 100644 index 0000000000..fc1bb807ee --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/router/index.ts @@ -0,0 +1,4 @@ +export { configureAccessTokenEndpoint, OpenId4VciAccessTokenEndpointConfig } from './accessTokenEndpoint' +export { configureCredentialEndpoint, OpenId4VciCredentialEndpointConfig } from './credentialEndpoint' +export { configureIssuerMetadataEndpoint } from './metadataEndpoint' +export { OpenId4VcIssuanceRequest } from './requestContext' diff --git a/packages/openid4vc/src/openid4vc-issuer/router/metadataEndpoint.ts b/packages/openid4vc/src/openid4vc-issuer/router/metadataEndpoint.ts new file mode 100644 index 0000000000..b3ecb4edc4 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/router/metadataEndpoint.ts @@ -0,0 +1,35 @@ +import type { OpenId4VcIssuanceRequest } from './requestContext' +import type { CredentialIssuerMetadata } from '@sphereon/oid4vci-common' +import type { Router, Response } from 'express' + +import { getRequestContext, sendErrorResponse } from '../../shared/router' +import { OpenId4VcIssuerService } from '../OpenId4VcIssuerService' + +export function configureIssuerMetadataEndpoint(router: Router) { + router.get( + '/.well-known/openid-credential-issuer', + (_request: OpenId4VcIssuanceRequest, response: Response, next) => { + const { agentContext, issuer } = getRequestContext(_request) + + try { + const openId4VcIssuerService = agentContext.dependencyManager.resolve(OpenId4VcIssuerService) + const issuerMetadata = openId4VcIssuerService.getIssuerMetadata(agentContext, issuer) + const transformedMetadata = { + credential_issuer: issuerMetadata.issuerUrl, + token_endpoint: issuerMetadata.tokenEndpoint, + credential_endpoint: issuerMetadata.credentialEndpoint, + authorization_server: issuerMetadata.authorizationServer, + credentials_supported: issuerMetadata.credentialsSupported, + display: issuerMetadata.issuerDisplay, + } satisfies CredentialIssuerMetadata + + response.status(200).json(transformedMetadata) + } catch (e) { + sendErrorResponse(response, agentContext.config.logger, 500, 'invalid_request', e) + } + + // NOTE: if we don't call next, the agentContext session handler will NOT be called + next() + } + ) +} diff --git a/packages/openid4vc/src/openid4vc-issuer/router/requestContext.ts b/packages/openid4vc/src/openid4vc-issuer/router/requestContext.ts new file mode 100644 index 0000000000..69e0caadb3 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-issuer/router/requestContext.ts @@ -0,0 +1,4 @@ +import type { OpenId4VcRequest } from '../../shared/router' +import type { OpenId4VcIssuerRecord } from '../repository' + +export type OpenId4VcIssuanceRequest = OpenId4VcRequest<{ issuer: OpenId4VcIssuerRecord }> diff --git a/packages/openid4vc/src/openid4vc-verifier/OpenId4VcSiopVerifierService.ts b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcSiopVerifierService.ts new file mode 100644 index 0000000000..a25921cf1d --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcSiopVerifierService.ts @@ -0,0 +1,363 @@ +import type { + OpenId4VcSiopCreateAuthorizationRequestOptions, + OpenId4VcSiopCreateAuthorizationRequestReturn, + OpenId4VcSiopCreateVerifierOptions, + OpenId4VcSiopVerifiedAuthorizationResponse, + OpenId4VcSiopVerifyAuthorizationResponseOptions, +} from './OpenId4VcSiopVerifierServiceOptions' +import type { OpenId4VcJwtIssuer } from '../shared' +import type { AgentContext, DifPresentationExchangeDefinition } from '@credo-ts/core' +import type { PresentationVerificationCallback, SigningAlgo } from '@sphereon/did-auth-siop' + +import { + CredoError, + DidsApi, + inject, + injectable, + InjectionSymbols, + joinUriParts, + JsonTransformer, + Logger, + SdJwtVcApi, + SignatureSuiteRegistry, + utils, + W3cCredentialService, + W3cJsonLdVerifiablePresentation, + Hasher, +} from '@credo-ts/core' +import { + AuthorizationResponse, + CheckLinkedDomain, + PassBy, + PropertyTarget, + ResponseIss, + ResponseMode, + ResponseType, + RevocationVerification, + RP, + SupportedVersion, + VerificationMode, +} from '@sphereon/did-auth-siop' + +import { storeActorIdForContextCorrelationId } from '../shared/router' +import { getVerifiablePresentationFromSphereonWrapped } from '../shared/transform' +import { + getSphereonDidResolver, + getSphereonSuppliedSignatureFromJwtIssuer, + getSupportedJwaSignatureAlgorithms, +} from '../shared/utils' + +import { OpenId4VcVerifierModuleConfig } from './OpenId4VcVerifierModuleConfig' +import { OpenId4VcVerifierRecord, OpenId4VcVerifierRepository } from './repository' + +/** + * @internal + */ +@injectable() +export class OpenId4VcSiopVerifierService { + public constructor( + @inject(InjectionSymbols.Logger) private logger: Logger, + private w3cCredentialService: W3cCredentialService, + private openId4VcVerifierRepository: OpenId4VcVerifierRepository, + private config: OpenId4VcVerifierModuleConfig + ) {} + + public async createAuthorizationRequest( + agentContext: AgentContext, + options: OpenId4VcSiopCreateAuthorizationRequestOptions & { verifier: OpenId4VcVerifierRecord } + ): Promise { + const nonce = await agentContext.wallet.generateNonce() + const state = await agentContext.wallet.generateNonce() + const correlationId = utils.uuid() + + const relyingParty = await this.getRelyingParty(agentContext, options.verifier, { + presentationDefinition: options.presentationExchange?.definition, + requestSigner: options.requestSigner, + }) + + const authorizationRequest = await relyingParty.createAuthorizationRequest({ + correlationId, + nonce, + state, + }) + + const authorizationRequestUri = await authorizationRequest.uri() + + return { + authorizationRequestUri: authorizationRequestUri.encodedUri, + authorizationRequestPayload: authorizationRequest.payload, + } + } + + public async verifyAuthorizationResponse( + agentContext: AgentContext, + options: OpenId4VcSiopVerifyAuthorizationResponseOptions & { verifier: OpenId4VcVerifierRecord } + ): Promise { + const authorizationResponse = await AuthorizationResponse.fromPayload(options.authorizationResponse).catch(() => { + throw new CredoError( + `Unable to parse authorization response payload. ${JSON.stringify(options.authorizationResponse)}` + ) + }) + + const responseNonce = await authorizationResponse.getMergedProperty('nonce', { + hasher: Hasher.hash, + }) + const responseState = await authorizationResponse.getMergedProperty('state', { + hasher: Hasher.hash, + }) + const sessionManager = this.config.getSessionManager(agentContext) + + const correlationId = responseNonce + ? await sessionManager.getCorrelationIdByNonce(responseNonce, false) + : responseState + ? await sessionManager.getCorrelationIdByState(responseState, false) + : undefined + + if (!correlationId) { + throw new CredoError(`Unable to find correlationId for nonce '${responseNonce}' or state '${responseState}'`) + } + + const requestSessionState = await sessionManager.getRequestStateByCorrelationId(correlationId) + if (!requestSessionState) { + throw new CredoError(`Unable to find request state for correlationId '${correlationId}'`) + } + + const requestClientId = await requestSessionState.request.getMergedProperty('client_id') + const requestNonce = await requestSessionState.request.getMergedProperty('nonce') + const requestState = await requestSessionState.request.getMergedProperty('state') + const presentationDefinitionsWithLocation = await requestSessionState.request.getPresentationDefinitions() + + if (!requestNonce || !requestClientId || !requestState) { + throw new CredoError( + `Unable to find nonce, state, or client_id in authorization request for correlationId '${correlationId}'` + ) + } + + const relyingParty = await this.getRelyingParty(agentContext, options.verifier, { + presentationDefinition: presentationDefinitionsWithLocation?.[0]?.definition, + clientId: requestClientId, + }) + + const response = await relyingParty.verifyAuthorizationResponse(authorizationResponse.payload, { + audience: requestClientId, + correlationId, + state: requestState, + presentationDefinitions: presentationDefinitionsWithLocation, + verification: { + presentationVerificationCallback: this.getPresentationVerificationCallback(agentContext, { + nonce: requestNonce, + audience: requestClientId, + }), + // FIXME: Supplied mode is not implemented. + // See https://github.com/Sphereon-Opensource/SIOP-OID4VP/issues/55 + mode: VerificationMode.INTERNAL, + resolveOpts: { noUniversalResolverFallback: true, resolver: getSphereonDidResolver(agentContext) }, + }, + }) + + const presentationExchange = response.oid4vpSubmission?.submissionData + ? { + submission: response.oid4vpSubmission.submissionData, + definition: response.oid4vpSubmission.presentationDefinitions[0]?.definition, + presentations: response.oid4vpSubmission?.presentations.map(getVerifiablePresentationFromSphereonWrapped), + } + : undefined + + const idToken = response.authorizationResponse.idToken + ? { + payload: await response.authorizationResponse.idToken.payload(), + } + : undefined + + // TODO: do we need to verify whether idToken or vpToken is present? + // Or is that properly handled by sphereon's library? + return { + // Parameters related to ID Token. + idToken, + + // Parameters related to DIF Presentation Exchange + presentationExchange, + } + } + + public async getAllVerifiers(agentContext: AgentContext) { + return this.openId4VcVerifierRepository.getAll(agentContext) + } + + public async getByVerifierId(agentContext: AgentContext, verifierId: string) { + return this.openId4VcVerifierRepository.getByVerifierId(agentContext, verifierId) + } + + public async updateVerifier(agentContext: AgentContext, verifier: OpenId4VcVerifierRecord) { + return this.openId4VcVerifierRepository.update(agentContext, verifier) + } + + public async createVerifier(agentContext: AgentContext, options?: OpenId4VcSiopCreateVerifierOptions) { + const openId4VcVerifier = new OpenId4VcVerifierRecord({ + verifierId: options?.verifierId ?? utils.uuid(), + }) + + await this.openId4VcVerifierRepository.save(agentContext, openId4VcVerifier) + await storeActorIdForContextCorrelationId(agentContext, openId4VcVerifier.verifierId) + return openId4VcVerifier + } + + private async getRelyingParty( + agentContext: AgentContext, + verifier: OpenId4VcVerifierRecord, + { + presentationDefinition, + requestSigner, + clientId, + }: { + presentationDefinition?: DifPresentationExchangeDefinition + requestSigner?: OpenId4VcJwtIssuer + clientId?: string + } + ) { + const authorizationResponseUrl = joinUriParts(this.config.baseUrl, [ + verifier.verifierId, + this.config.authorizationEndpoint.endpointPath, + ]) + + const signatureSuiteRegistry = agentContext.dependencyManager.resolve(SignatureSuiteRegistry) + + const supportedAlgs = getSupportedJwaSignatureAlgorithms(agentContext) as string[] + const supportedProofTypes = signatureSuiteRegistry.supportedProofTypes + + // Check: audience must be set to the issuer with dynamic disc otherwise self-issued.me/v2. + const builder = RP.builder() + + let _clientId = clientId + if (requestSigner) { + const suppliedSignature = await getSphereonSuppliedSignatureFromJwtIssuer(agentContext, requestSigner) + builder.withSignature(suppliedSignature) + + _clientId = suppliedSignature.did + } + + if (!_clientId) { + throw new CredoError("Either 'requestSigner' or 'clientId' must be provided.") + } + + // FIXME: we now manually remove did:peer, we should probably allow the user to configure this + const supportedDidMethods = agentContext.dependencyManager + .resolve(DidsApi) + .supportedResolverMethods.filter((m) => m !== 'peer') + + builder + .withRedirectUri(authorizationResponseUrl) + .withIssuer(ResponseIss.SELF_ISSUED_V2) + .withSupportedVersions([SupportedVersion.SIOPv2_D11, SupportedVersion.SIOPv2_D12_OID4VP_D18]) + // TODO: we should probably allow some dynamic values here + .withClientMetadata({ + client_id: _clientId, + passBy: PassBy.VALUE, + idTokenSigningAlgValuesSupported: supportedAlgs as SigningAlgo[], + responseTypesSupported: [ResponseType.VP_TOKEN, ResponseType.ID_TOKEN], + subject_syntax_types_supported: supportedDidMethods.map((m) => `did:${m}`), + vpFormatsSupported: { + jwt_vc: { + alg: supportedAlgs, + }, + jwt_vc_json: { + alg: supportedAlgs, + }, + jwt_vp: { + alg: supportedAlgs, + }, + ldp_vc: { + proof_type: supportedProofTypes, + }, + ldp_vp: { + proof_type: supportedProofTypes, + }, + 'vc+sd-jwt': { + kb_jwt_alg_values: supportedAlgs, + sd_jwt_alg_values: supportedAlgs, + }, + }, + }) + .withCustomResolver(getSphereonDidResolver(agentContext)) + .withResponseMode(ResponseMode.POST) + .withResponseType(presentationDefinition ? [ResponseType.ID_TOKEN, ResponseType.VP_TOKEN] : ResponseType.ID_TOKEN) + .withScope('openid') + .withHasher(Hasher.hash) + // TODO: support hosting requests within AFJ and passing it by reference + .withRequestBy(PassBy.VALUE) + .withCheckLinkedDomain(CheckLinkedDomain.NEVER) + // FIXME: should allow verification of revocation + // .withRevocationVerificationCallback() + .withRevocationVerification(RevocationVerification.NEVER) + .withSessionManager(this.config.getSessionManager(agentContext)) + .withEventEmitter(this.config.getEventEmitter(agentContext)) + + if (presentationDefinition) { + builder.withPresentationDefinition({ definition: presentationDefinition }, [PropertyTarget.REQUEST_OBJECT]) + } + + for (const supportedDidMethod of supportedDidMethods) { + builder.addDidMethod(supportedDidMethod) + } + + return builder.build() + } + + private getPresentationVerificationCallback( + agentContext: AgentContext, + options: { nonce: string; audience: string } + ): PresentationVerificationCallback { + return async (encodedPresentation, presentationSubmission) => { + this.logger.debug(`Presentation response`, JsonTransformer.toJSON(encodedPresentation)) + this.logger.debug(`Presentation submission`, presentationSubmission) + + if (!encodedPresentation) throw new CredoError('Did not receive a presentation for verification.') + + let isValid: boolean + + // TODO: it might be better here to look at the presentation submission to know + // If presentation includes a ~, we assume it's an SD-JWT-VC + if (typeof encodedPresentation === 'string' && encodedPresentation.includes('~')) { + const sdJwtVcApi = agentContext.dependencyManager.resolve(SdJwtVcApi) + + const verificationResult = await sdJwtVcApi.verify({ + compactSdJwtVc: encodedPresentation, + keyBinding: { + audience: options.audience, + nonce: options.nonce, + }, + }) + + isValid = verificationResult.verification.isValid + } else if (typeof encodedPresentation === 'string') { + const verificationResult = await this.w3cCredentialService.verifyPresentation(agentContext, { + presentation: encodedPresentation, + challenge: options.nonce, + domain: options.audience, + }) + + isValid = verificationResult.isValid + } else { + const verificationResult = await this.w3cCredentialService.verifyPresentation(agentContext, { + presentation: JsonTransformer.fromJSON(encodedPresentation, W3cJsonLdVerifiablePresentation), + challenge: options.nonce, + domain: options.audience, + }) + + isValid = verificationResult.isValid + } + + // FIXME: we throw an error here as there's a bug in sphereon library where they + // don't check the returned 'verified' property and only catch errors thrown. + // Once https://github.com/Sphereon-Opensource/SIOP-OID4VP/pull/70 is merged we + // can remove this. + if (!isValid) { + throw new CredoError('Presentation verification failed.') + } + + return { + verified: isValid, + } + } + } +} diff --git a/packages/openid4vc/src/openid4vc-verifier/OpenId4VcSiopVerifierServiceOptions.ts b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcSiopVerifierServiceOptions.ts new file mode 100644 index 0000000000..7725b7ddd1 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcSiopVerifierServiceOptions.ts @@ -0,0 +1,61 @@ +import type { + OpenId4VcJwtIssuer, + OpenId4VcSiopAuthorizationRequestPayload, + OpenId4VcSiopAuthorizationResponsePayload, + OpenId4VcSiopIdTokenPayload, +} from '../shared' +import type { + DifPresentationExchangeDefinition, + DifPresentationExchangeSubmission, + DifPresentationExchangeDefinitionV2, + VerifiablePresentation, +} from '@credo-ts/core' + +export interface OpenId4VcSiopCreateAuthorizationRequestOptions { + /** + * Signing information for the request JWT. This will be used to sign the request JWT + * and to set the client_id for registration of client_metadata. + */ + requestSigner: OpenId4VcJwtIssuer + + /** + * A DIF Presentation Definition (v2) can be provided to request a Verifiable Presentation using OpenID4VP. + */ + presentationExchange?: { + definition: DifPresentationExchangeDefinitionV2 + } +} + +export interface OpenId4VcSiopVerifyAuthorizationResponseOptions { + /** + * The authorization response received from the OpenID Provider (OP). + */ + authorizationResponse: OpenId4VcSiopAuthorizationResponsePayload +} + +export interface OpenId4VcSiopCreateAuthorizationRequestReturn { + authorizationRequestUri: string + authorizationRequestPayload: OpenId4VcSiopAuthorizationRequestPayload +} + +/** + * Either `idToken` and/or `presentationExchange` will be present, but not none. + */ +export interface OpenId4VcSiopVerifiedAuthorizationResponse { + idToken?: { + payload: OpenId4VcSiopIdTokenPayload + } + + presentationExchange?: { + submission: DifPresentationExchangeSubmission + definition: DifPresentationExchangeDefinition + presentations: Array + } +} + +export interface OpenId4VcSiopCreateVerifierOptions { + /** + * Id of the verifier, not the id of the verified record. Will be exposed publicly + */ + verifierId?: string +} diff --git a/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierApi.ts b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierApi.ts new file mode 100644 index 0000000000..e312d3b8a0 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierApi.ts @@ -0,0 +1,88 @@ +import type { + OpenId4VcSiopCreateAuthorizationRequestOptions, + OpenId4VcSiopVerifyAuthorizationResponseOptions, + OpenId4VcSiopCreateAuthorizationRequestReturn, + OpenId4VcSiopVerifiedAuthorizationResponse, + OpenId4VcSiopCreateVerifierOptions, +} from './OpenId4VcSiopVerifierServiceOptions' + +import { injectable, AgentContext } from '@credo-ts/core' + +import { OpenId4VcSiopVerifierService } from './OpenId4VcSiopVerifierService' +import { OpenId4VcVerifierModuleConfig } from './OpenId4VcVerifierModuleConfig' + +/** + * @public + */ +@injectable() +export class OpenId4VcVerifierApi { + public constructor( + public readonly config: OpenId4VcVerifierModuleConfig, + private agentContext: AgentContext, + private openId4VcSiopVerifierService: OpenId4VcSiopVerifierService + ) {} + + /** + * Retrieve all verifier records from storage + */ + public async getAllVerifiers() { + return this.openId4VcSiopVerifierService.getAllVerifiers(this.agentContext) + } + + /** + * Retrieve a verifier record from storage by its verified id + */ + public async getByVerifierId(verifierId: string) { + return this.openId4VcSiopVerifierService.getByVerifierId(this.agentContext, verifierId) + } + + /** + * Create a new verifier and store the new verifier record. + */ + public async createVerifier(options?: OpenId4VcSiopCreateVerifierOptions) { + return this.openId4VcSiopVerifierService.createVerifier(this.agentContext, options) + } + + /** + * Create an authorization request, acting as a Relying Party (RP). + * + * Currently two types of requests are supported: + * - SIOP Self-Issued ID Token request: request to a Self-Issued OP from an RP + * - SIOP Verifiable Presentation Request: request to a Self-Issued OP from an RP, requesting a Verifiable Presentation using OpenID4VP + * + * Other flows (non-SIOP) are not supported at the moment, but can be added in the future. + * + * See {@link OpenId4VcSiopCreateAuthorizationRequestOptions} for detailed documentation on the options. + */ + public async createAuthorizationRequest({ + verifierId, + ...otherOptions + }: OpenId4VcSiopCreateAuthorizationRequestOptions & { + verifierId: string + }): Promise { + const verifier = await this.getByVerifierId(verifierId) + return await this.openId4VcSiopVerifierService.createAuthorizationRequest(this.agentContext, { + ...otherOptions, + verifier, + }) + } + + /** + * Verifies an authorization response, acting as a Relying Party (RP). + * + * It validates the ID Token, VP Token and the signature(s) of the received Verifiable Presentation(s) + * as well as that the structure of the Verifiable Presentation matches the provided presentation definition. + */ + public async verifyAuthorizationResponse({ + verifierId, + ...otherOptions + }: OpenId4VcSiopVerifyAuthorizationResponseOptions & { + verifierId: string + }): Promise { + const verifier = await this.getByVerifierId(verifierId) + return await this.openId4VcSiopVerifierService.verifyAuthorizationResponse(this.agentContext, { + ...otherOptions, + verifier, + }) + } +} diff --git a/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierModule.ts b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierModule.ts new file mode 100644 index 0000000000..cf32b05ff5 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierModule.ts @@ -0,0 +1,127 @@ +import type { OpenId4VcVerifierModuleConfigOptions } from './OpenId4VcVerifierModuleConfig' +import type { OpenId4VcVerificationRequest } from './router' +import type { AgentContext, DependencyManager, Module } from '@credo-ts/core' +import type { NextFunction } from 'express' + +import { AgentConfig } from '@credo-ts/core' + +import { getAgentContextForActorId, getRequestContext, importExpress } from '../shared/router' + +import { OpenId4VcSiopVerifierService } from './OpenId4VcSiopVerifierService' +import { OpenId4VcVerifierApi } from './OpenId4VcVerifierApi' +import { OpenId4VcVerifierModuleConfig } from './OpenId4VcVerifierModuleConfig' +import { OpenId4VcVerifierRepository } from './repository' +import { configureAuthorizationEndpoint } from './router' + +/** + * @public + */ +export class OpenId4VcVerifierModule implements Module { + public readonly api = OpenId4VcVerifierApi + public readonly config: OpenId4VcVerifierModuleConfig + + public constructor(options: OpenId4VcVerifierModuleConfigOptions) { + this.config = new OpenId4VcVerifierModuleConfig(options) + } + + /** + * Registers the dependencies of the question answer module on the dependency manager. + */ + public register(dependencyManager: DependencyManager) { + // Warn about experimental module + const logger = dependencyManager.resolve(AgentConfig).logger + logger.warn( + "The '@credo-ts/openid4vc' Verifier module is experimental and could have unexpected breaking changes. When using this module, make sure to use strict versions for all @credo-ts packages." + ) + + // Register config + dependencyManager.registerInstance(OpenId4VcVerifierModuleConfig, this.config) + + // Services + dependencyManager.registerSingleton(OpenId4VcSiopVerifierService) + + // Repository + dependencyManager.registerSingleton(OpenId4VcVerifierRepository) + } + + public async initialize(rootAgentContext: AgentContext): Promise { + this.configureRouter(rootAgentContext) + } + + /** + * Registers the endpoints on the router passed to this module. + */ + private configureRouter(rootAgentContext: AgentContext) { + const { Router, json, urlencoded } = importExpress() + + // FIXME: it is currently not possible to initialize an agent + // shut it down, and then start it again, as the + // express router is configured with a specific `AgentContext` instance + // and dependency manager. One option is to always create a new router + // but then users cannot pass their own router implementation. + // We need to find a proper way to fix this. + + // We use separate context router and endpoint router. Context router handles the linking of the request + // to a specific agent context. Endpoint router only knows about a single context + const endpointRouter = Router() + const contextRouter = this.config.router + + // parse application/x-www-form-urlencoded + contextRouter.use(urlencoded({ extended: false })) + // parse application/json + contextRouter.use(json()) + + contextRouter.param('verifierId', async (req: OpenId4VcVerificationRequest, _res, next, verifierId: string) => { + if (!verifierId) { + rootAgentContext.config.logger.debug( + 'No verifierId provided for incoming authorization response, returning 404' + ) + _res.status(404).send('Not found') + } + + let agentContext: AgentContext | undefined = undefined + + try { + agentContext = await getAgentContextForActorId(rootAgentContext, verifierId) + const verifierApi = agentContext.dependencyManager.resolve(OpenId4VcVerifierApi) + const verifier = await verifierApi.getByVerifierId(verifierId) + + req.requestContext = { + agentContext, + verifier, + } + } catch (error) { + agentContext?.config.logger.error( + 'Failed to correlate incoming openid request to existing tenant and verifier', + { + error, + } + ) + // If the opening failed + await agentContext?.endSession() + return _res.status(404).send('Not found') + } + + next() + }) + + contextRouter.use('/:verifierId', endpointRouter) + + // Configure endpoints + configureAuthorizationEndpoint(endpointRouter, this.config.authorizationEndpoint) + + // First one will be called for all requests (when next is called) + contextRouter.use(async (req: OpenId4VcVerificationRequest, _res: unknown, next) => { + const { agentContext } = getRequestContext(req) + await agentContext.endSession() + next() + }) + + // This one will be called for all errors that are thrown + contextRouter.use(async (_error: unknown, req: OpenId4VcVerificationRequest, _res: unknown, next: NextFunction) => { + const { agentContext } = getRequestContext(req) + await agentContext.endSession() + next() + }) + } +} diff --git a/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierModuleConfig.ts b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierModuleConfig.ts new file mode 100644 index 0000000000..c2d2f6b4a0 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/OpenId4VcVerifierModuleConfig.ts @@ -0,0 +1,83 @@ +import type { OpenId4VcSiopAuthorizationEndpointConfig } from './router/authorizationEndpoint' +import type { Optional, AgentContext, AgentDependencies } from '@credo-ts/core' +import type { IRPSessionManager } from '@sphereon/did-auth-siop' +import type { Router } from 'express' + +import { InMemoryRPSessionManager } from '@sphereon/did-auth-siop' + +import { importExpress } from '../shared/router' + +export interface OpenId4VcVerifierModuleConfigOptions { + /** + * Base url at which the verifier endpoints will be hosted. All endpoints will be exposed with + * this path as prefix. + */ + baseUrl: string + + /** + * Express router on which the verifier endpoints will be registered. If + * no router is provided, a new one will be created. + * + * NOTE: you must manually register the router on your express app and + * expose this on a public url that is reachable when `baseUrl` is called. + */ + router?: Router + + endpoints?: { + authorization?: Optional + } +} + +export class OpenId4VcVerifierModuleConfig { + private options: OpenId4VcVerifierModuleConfigOptions + public readonly router: Router + + private eventEmitterMap: Map> + private sessionManagerMap: Map + + public constructor(options: OpenId4VcVerifierModuleConfigOptions) { + this.options = options + this.sessionManagerMap = new Map() + this.eventEmitterMap = new Map() + + this.router = options.router ?? importExpress().Router() + } + + public get baseUrl() { + return this.options.baseUrl + } + + public get authorizationEndpoint(): OpenId4VcSiopAuthorizationEndpointConfig { + // Use user supplied options, or return defaults. + const userOptions = this.options.endpoints?.authorization + + return { + ...userOptions, + endpointPath: userOptions?.endpointPath ?? '/authorize', + } + } + + // FIXME: rework (no in-memory) + public getSessionManager(agentContext: AgentContext) { + const val = this.sessionManagerMap.get(agentContext.contextCorrelationId) + if (val) return val + + const eventEmitter = this.getEventEmitter(agentContext) + + const newVal = new InMemoryRPSessionManager(eventEmitter) + this.sessionManagerMap.set(agentContext.contextCorrelationId, newVal) + return newVal + } + + // FIXME: rework (no-memory) + public getEventEmitter(agentContext: AgentContext) { + const EventEmitterClass = agentContext.config.agentDependencies.EventEmitterClass + + const val = this.eventEmitterMap.get(agentContext.contextCorrelationId) + if (val) return val + + const newVal = new EventEmitterClass() + this.eventEmitterMap.set(agentContext.contextCorrelationId, newVal) + return newVal + } +} diff --git a/packages/openid4vc/src/openid4vc-verifier/__tests__/OpenId4VcVerifierModule.test.ts b/packages/openid4vc/src/openid4vc-verifier/__tests__/OpenId4VcVerifierModule.test.ts new file mode 100644 index 0000000000..c24d50a557 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/__tests__/OpenId4VcVerifierModule.test.ts @@ -0,0 +1,42 @@ +import type { OpenId4VcVerifierModuleConfigOptions } from '../OpenId4VcVerifierModuleConfig' +import type { DependencyManager } from '@credo-ts/core' + +import { Router } from 'express' + +import { OpenId4VcSiopVerifierService } from '../OpenId4VcSiopVerifierService' +import { OpenId4VcVerifierModule } from '../OpenId4VcVerifierModule' +import { OpenId4VcVerifierModuleConfig } from '../OpenId4VcVerifierModuleConfig' +import { OpenId4VcVerifierRepository } from '../repository' + +const dependencyManager = { + registerInstance: jest.fn(), + registerSingleton: jest.fn(), + registerContextScoped: jest.fn(), + resolve: jest.fn().mockReturnValue({ logger: { warn: jest.fn() } }), +} as unknown as DependencyManager + +describe('OpenId4VcVerifierModule', () => { + test('registers dependencies on the dependency manager', () => { + const options = { + baseUrl: 'http://localhost:3000', + endpoints: { + authorization: { + endpointPath: '/hello', + }, + }, + router: Router(), + } satisfies OpenId4VcVerifierModuleConfigOptions + const openId4VcClientModule = new OpenId4VcVerifierModule(options) + openId4VcClientModule.register(dependencyManager) + + expect(dependencyManager.registerInstance).toHaveBeenCalledTimes(1) + expect(dependencyManager.registerInstance).toHaveBeenCalledWith( + OpenId4VcVerifierModuleConfig, + new OpenId4VcVerifierModuleConfig(options) + ) + + expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) + expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OpenId4VcSiopVerifierService) + expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(OpenId4VcVerifierRepository) + }) +}) diff --git a/packages/openid4vc/src/openid4vc-verifier/__tests__/openid4vc-verifier.e2e.test.ts b/packages/openid4vc/src/openid4vc-verifier/__tests__/openid4vc-verifier.e2e.test.ts new file mode 100644 index 0000000000..555f774ed6 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/__tests__/openid4vc-verifier.e2e.test.ts @@ -0,0 +1,71 @@ +import { Jwt } from '@credo-ts/core' +import { SigningAlgo } from '@sphereon/did-auth-siop' +import { cleanAll, enableNetConnect } from 'nock' + +import { AskarModule } from '../../../../askar/src' +import { askarModuleConfig } from '../../../../askar/tests/helpers' +import { createAgentFromModules, type AgentType } from '../../../tests/utils' +import { universityDegreePresentationDefinition } from '../../../tests/utilsVp' +import { OpenId4VcVerifierModule } from '../OpenId4VcVerifierModule' + +const modules = { + openId4VcVerifier: new OpenId4VcVerifierModule({ + baseUrl: 'http://redirect-uri', + }), + askar: new AskarModule(askarModuleConfig), +} + +describe('OpenId4VcVerifier', () => { + let verifier: AgentType + + beforeEach(async () => { + verifier = await createAgentFromModules('verifier', modules, '96213c3d7fc8d4d6754c7a0fd969598f') + }) + + afterEach(async () => { + await verifier.agent.shutdown() + await verifier.agent.wallet.delete() + }) + + describe('Verification', () => { + afterEach(() => { + cleanAll() + enableNetConnect() + }) + + it('check openid proof request format', async () => { + const openIdVerifier = await verifier.agent.modules.openId4VcVerifier.createVerifier() + const { authorizationRequestUri } = await verifier.agent.modules.openId4VcVerifier.createAuthorizationRequest({ + requestSigner: { + method: 'did', + didUrl: verifier.kid, + }, + verifierId: openIdVerifier.verifierId, + presentationExchange: { + definition: universityDegreePresentationDefinition, + }, + }) + + const base = `openid://?redirect_uri=http%3A%2F%2Fredirect-uri%2F${openIdVerifier.verifierId}%2Fauthorize&request=` + expect(authorizationRequestUri.startsWith(base)).toBe(true) + + const _jwt = authorizationRequestUri.substring(base.length) + const jwt = Jwt.fromSerializedJwt(_jwt) + + expect(jwt.header.kid).toEqual(verifier.kid) + expect(jwt.header.alg).toEqual(SigningAlgo.EDDSA) + expect(jwt.header.typ).toEqual('JWT') + expect(jwt.payload.additionalClaims.scope).toEqual('openid') + expect(jwt.payload.additionalClaims.client_id).toEqual(verifier.did) + expect(jwt.payload.additionalClaims.redirect_uri).toEqual( + `http://redirect-uri/${openIdVerifier.verifierId}/authorize` + ) + expect(jwt.payload.additionalClaims.response_mode).toEqual('post') + expect(jwt.payload.additionalClaims.nonce).toBeDefined() + expect(jwt.payload.additionalClaims.state).toBeDefined() + expect(jwt.payload.additionalClaims.response_type).toEqual('id_token vp_token') + expect(jwt.payload.iss).toEqual(verifier.did) + expect(jwt.payload.sub).toEqual(verifier.did) + }) + }) +}) diff --git a/packages/openid4vc/src/openid4vc-verifier/index.ts b/packages/openid4vc/src/openid4vc-verifier/index.ts new file mode 100644 index 0000000000..25a6548336 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/index.ts @@ -0,0 +1,6 @@ +export * from './OpenId4VcVerifierApi' +export * from './OpenId4VcVerifierModule' +export * from './OpenId4VcSiopVerifierService' +export * from './OpenId4VcSiopVerifierServiceOptions' +export * from './OpenId4VcVerifierModuleConfig' +export * from './repository' diff --git a/packages/openid4vc/src/openid4vc-verifier/repository/OpenId4VcVerifierRecord.ts b/packages/openid4vc/src/openid4vc-verifier/repository/OpenId4VcVerifierRecord.ts new file mode 100644 index 0000000000..a5c90f486c --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/repository/OpenId4VcVerifierRecord.ts @@ -0,0 +1,48 @@ +import type { RecordTags, TagsBase } from '@credo-ts/core' + +import { BaseRecord, utils } from '@credo-ts/core' + +export type OpenId4VcVerifierRecordTags = RecordTags + +export type DefaultOpenId4VcVerifierRecordTags = { + verifierId: string +} + +export interface OpenId4VcVerifierRecordProps { + id?: string + createdAt?: Date + tags?: TagsBase + + verifierId: string +} + +/** + * For OID4VC you need to expos metadata files. Each issuer needs to host this metadata. This is not the case for DIDComm where we can just have one /didcomm endpoint. + * So we create a record per openid issuer/verifier that you want, and each tenant can create multiple issuers/verifiers which have different endpoints + * and metadata files + * */ +export class OpenId4VcVerifierRecord extends BaseRecord { + public static readonly type = 'OpenId4VcVerifierRecord' + public readonly type = OpenId4VcVerifierRecord.type + + public verifierId!: string + + public constructor(props: OpenId4VcVerifierRecordProps) { + super() + + if (props) { + this.id = props.id ?? utils.uuid() + this.createdAt = props.createdAt ?? new Date() + this._tags = props.tags ?? {} + + this.verifierId = props.verifierId + } + } + + public getTags() { + return { + ...this._tags, + verifierId: this.verifierId, + } + } +} diff --git a/packages/openid4vc/src/openid4vc-verifier/repository/OpenId4VcVerifierRepository.ts b/packages/openid4vc/src/openid4vc-verifier/repository/OpenId4VcVerifierRepository.ts new file mode 100644 index 0000000000..a96a533ff1 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/repository/OpenId4VcVerifierRepository.ts @@ -0,0 +1,23 @@ +import type { AgentContext } from '@credo-ts/core' + +import { Repository, StorageService, InjectionSymbols, EventEmitter, inject, injectable } from '@credo-ts/core' + +import { OpenId4VcVerifierRecord } from './OpenId4VcVerifierRecord' + +@injectable() +export class OpenId4VcVerifierRepository extends Repository { + public constructor( + @inject(InjectionSymbols.StorageService) storageService: StorageService, + eventEmitter: EventEmitter + ) { + super(OpenId4VcVerifierRecord, storageService, eventEmitter) + } + + public findByVerifierId(agentContext: AgentContext, verifierId: string) { + return this.findSingleByQuery(agentContext, { verifierId }) + } + + public getByVerifierId(agentContext: AgentContext, verifierId: string) { + return this.getSingleByQuery(agentContext, { verifierId }) + } +} diff --git a/packages/openid4vc/src/openid4vc-verifier/repository/index.ts b/packages/openid4vc/src/openid4vc-verifier/repository/index.ts new file mode 100644 index 0000000000..09bef0307e --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/repository/index.ts @@ -0,0 +1,2 @@ +export * from './OpenId4VcVerifierRecord' +export * from './OpenId4VcVerifierRepository' diff --git a/packages/openid4vc/src/openid4vc-verifier/router/authorizationEndpoint.ts b/packages/openid4vc/src/openid4vc-verifier/router/authorizationEndpoint.ts new file mode 100644 index 0000000000..6bafb8236f --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/router/authorizationEndpoint.ts @@ -0,0 +1,42 @@ +import type { OpenId4VcVerificationRequest } from './requestContext' +import type { AuthorizationResponsePayload } from '@sphereon/did-auth-siop' +import type { Router, Response } from 'express' + +import { getRequestContext, sendErrorResponse } from '../../shared/router' +import { OpenId4VcSiopVerifierService } from '../OpenId4VcSiopVerifierService' + +export interface OpenId4VcSiopAuthorizationEndpointConfig { + /** + * The path at which the authorization endpoint should be made available. Note that it will be + * hosted at a subpath to take into account multiple tenants and verifiers. + * + * @default /authorize + */ + endpointPath: string +} + +export function configureAuthorizationEndpoint(router: Router, config: OpenId4VcSiopAuthorizationEndpointConfig) { + router.post(config.endpointPath, async (request: OpenId4VcVerificationRequest, response: Response, next) => { + const { agentContext, verifier } = getRequestContext(request) + + try { + const openId4VcVerifierService = agentContext.dependencyManager.resolve(OpenId4VcSiopVerifierService) + const isVpRequest = request.body.presentation_submission !== undefined + + const authorizationResponse: AuthorizationResponsePayload = request.body + if (isVpRequest) authorizationResponse.presentation_submission = JSON.parse(request.body.presentation_submission) + + // FIXME: we should emit an event here and in other places + await openId4VcVerifierService.verifyAuthorizationResponse(agentContext, { + authorizationResponse: request.body, + verifier, + }) + response.status(200).send() + } catch (error) { + sendErrorResponse(response, agentContext.config.logger, 500, 'invalid_request', error) + } + + // NOTE: if we don't call next, the agentContext session handler will NOT be called + next() + }) +} diff --git a/packages/openid4vc/src/openid4vc-verifier/router/index.ts b/packages/openid4vc/src/openid4vc-verifier/router/index.ts new file mode 100644 index 0000000000..8242556be4 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/router/index.ts @@ -0,0 +1,2 @@ +export { configureAuthorizationEndpoint } from './authorizationEndpoint' +export { OpenId4VcVerificationRequest } from './requestContext' diff --git a/packages/openid4vc/src/openid4vc-verifier/router/requestContext.ts b/packages/openid4vc/src/openid4vc-verifier/router/requestContext.ts new file mode 100644 index 0000000000..4dcb3964d8 --- /dev/null +++ b/packages/openid4vc/src/openid4vc-verifier/router/requestContext.ts @@ -0,0 +1,4 @@ +import type { OpenId4VcRequest } from '../../shared/router' +import type { OpenId4VcVerifierRecord } from '../repository' + +export type OpenId4VcVerificationRequest = OpenId4VcRequest<{ verifier: OpenId4VcVerifierRecord }> diff --git a/packages/openid4vc/src/shared/index.ts b/packages/openid4vc/src/shared/index.ts new file mode 100644 index 0000000000..8eacb927b2 --- /dev/null +++ b/packages/openid4vc/src/shared/index.ts @@ -0,0 +1,2 @@ +export * from './models' +export * from './issuerMetadataUtils' diff --git a/packages/openid4vc/src/shared/issuerMetadataUtils.ts b/packages/openid4vc/src/shared/issuerMetadataUtils.ts new file mode 100644 index 0000000000..f8986d1dc2 --- /dev/null +++ b/packages/openid4vc/src/shared/issuerMetadataUtils.ts @@ -0,0 +1,83 @@ +import type { OpenId4VciCredentialSupported, OpenId4VciCredentialSupportedWithId } from './models' +import type { AuthorizationDetails, CredentialOfferFormat, EndpointMetadataResult } from '@sphereon/oid4vci-common' + +import { CredoError } from '@credo-ts/core' + +/** + * Get all `types` from a `CredentialSupported` object. + * + * Depending on the format, the types may be nested, or have different a different name/type + */ +export function getTypesFromCredentialSupported(credentialSupported: OpenId4VciCredentialSupported) { + if ( + credentialSupported.format === 'jwt_vc_json-ld' || + credentialSupported.format === 'ldp_vc' || + credentialSupported.format === 'jwt_vc_json' || + credentialSupported.format === 'jwt_vc' + ) { + return credentialSupported.types + } else if (credentialSupported.format === 'vc+sd-jwt') { + return [credentialSupported.vct] + } + + throw Error(`Unable to extract types from credentials supported. Unknown format ${credentialSupported.format}`) +} + +/** + * Returns all entries from the credential offer with the associated metadata resolved. For 'id' entries, the associated `credentials_supported` object is resolved from the issuer metadata. + * For inline entries, an error is thrown. + */ +export function getOfferedCredentials( + offeredCredentials: Array, + allCredentialsSupported: OpenId4VciCredentialSupported[] +): OpenId4VciCredentialSupportedWithId[] { + const credentialsSupported: OpenId4VciCredentialSupportedWithId[] = [] + + for (const offeredCredential of offeredCredentials) { + // In draft 12 inline credential offers are removed. It's easier to already remove support now. + if (typeof offeredCredential !== 'string') { + throw new CredoError( + 'Only referenced credentials pointing to an id in credentials_supported issuer metadata are supported' + ) + } + + const foundSupportedCredential = allCredentialsSupported.find( + (supportedCredential): supportedCredential is OpenId4VciCredentialSupportedWithId => + supportedCredential.id !== undefined && supportedCredential.id === offeredCredential + ) + + // Make sure the issuer metadata includes the offered credential. + if (!foundSupportedCredential) { + throw new Error( + `Offered credential '${offeredCredential}' is not part of credentials_supported of the issuer metadata.` + ) + } + + credentialsSupported.push(foundSupportedCredential) + } + + return credentialsSupported +} + +// copied from sphereon as the method is only available on the client +export function handleAuthorizationDetails( + authorizationDetails: AuthorizationDetails | AuthorizationDetails[], + metadata: EndpointMetadataResult +): AuthorizationDetails | AuthorizationDetails[] | undefined { + if (Array.isArray(authorizationDetails)) { + return authorizationDetails.map((value) => handleLocations(value, metadata)) + } else { + return handleLocations(authorizationDetails, metadata) + } +} + +// copied from sphereon as the method is only available on the client +function handleLocations(authorizationDetails: AuthorizationDetails, metadata: EndpointMetadataResult) { + if (typeof authorizationDetails === 'string') return authorizationDetails + if (metadata.credentialIssuerMetadata?.authorization_server || metadata.authorization_endpoint) { + if (!authorizationDetails.locations) authorizationDetails.locations = [metadata.issuer] + else if (Array.isArray(authorizationDetails.locations)) authorizationDetails.locations.push(metadata.issuer) + else authorizationDetails.locations = [authorizationDetails.locations as string, metadata.issuer] + } + return authorizationDetails +} diff --git a/packages/openid4vc/src/shared/models/CredentialHolderBinding.ts b/packages/openid4vc/src/shared/models/CredentialHolderBinding.ts new file mode 100644 index 0000000000..2c174dab9e --- /dev/null +++ b/packages/openid4vc/src/shared/models/CredentialHolderBinding.ts @@ -0,0 +1,13 @@ +import type { Jwk } from '@credo-ts/core' + +export type OpenId4VcCredentialHolderDidBinding = { + method: 'did' + didUrl: string +} + +export type OpenId4VcCredentialHolderJwkBinding = { + method: 'jwk' + jwk: Jwk +} + +export type OpenId4VcCredentialHolderBinding = OpenId4VcCredentialHolderDidBinding | OpenId4VcCredentialHolderJwkBinding diff --git a/packages/openid4vc/src/shared/models/OpenId4VcJwtIssuer.ts b/packages/openid4vc/src/shared/models/OpenId4VcJwtIssuer.ts new file mode 100644 index 0000000000..5165628db1 --- /dev/null +++ b/packages/openid4vc/src/shared/models/OpenId4VcJwtIssuer.ts @@ -0,0 +1,13 @@ +interface OpenId4VcJwtIssuerDid { + method: 'did' + didUrl: string +} + +// TODO: enable once supported in sphereon lib +// See https://github.com/Sphereon-Opensource/SIOP-OID4VP/issues/67 +// interface OpenId4VcJwtIssuerJwk { +// method: 'jwk' +// jwk: Jwk +// } + +export type OpenId4VcJwtIssuer = OpenId4VcJwtIssuerDid diff --git a/packages/openid4vc/src/shared/models/OpenId4VciCredentialFormatProfile.ts b/packages/openid4vc/src/shared/models/OpenId4VciCredentialFormatProfile.ts new file mode 100644 index 0000000000..628e65c12e --- /dev/null +++ b/packages/openid4vc/src/shared/models/OpenId4VciCredentialFormatProfile.ts @@ -0,0 +1,6 @@ +export enum OpenId4VciCredentialFormatProfile { + JwtVcJson = 'jwt_vc_json', + JwtVcJsonLd = 'jwt_vc_json-ld', + LdpVc = 'ldp_vc', + SdJwtVc = 'vc+sd-jwt', +} diff --git a/packages/openid4vc/src/shared/models/index.ts b/packages/openid4vc/src/shared/models/index.ts new file mode 100644 index 0000000000..dc37fafeb8 --- /dev/null +++ b/packages/openid4vc/src/shared/models/index.ts @@ -0,0 +1,37 @@ +import type { + VerifiedAuthorizationRequest, + AuthorizationRequestPayload, + AuthorizationResponsePayload, + IDTokenPayload, +} from '@sphereon/did-auth-siop' +import type { + AssertedUniformCredentialOffer, + CredentialIssuerMetadata, + CredentialOfferPayloadV1_0_11, + CredentialRequestJwtVcJson, + CredentialRequestJwtVcJsonLdAndLdpVc, + CredentialRequestSdJwtVc, + CredentialSupported, + MetadataDisplay, + UniformCredentialRequest, +} from '@sphereon/oid4vci-common' + +export type OpenId4VciCredentialSupportedWithId = CredentialSupported & { id: string } +export type OpenId4VciCredentialSupported = CredentialSupported +export type OpenId4VciIssuerMetadata = CredentialIssuerMetadata +export type OpenId4VciIssuerMetadataDisplay = MetadataDisplay +export type OpenId4VciCredentialRequest = UniformCredentialRequest +export type OpenId4VciCredentialRequestJwtVcJson = CredentialRequestJwtVcJson +export type OpenId4VciCredentialRequestJwtVcJsonLdAndLdpVc = CredentialRequestJwtVcJsonLdAndLdpVc +export type OpenId4VciCredentialRequestSdJwtVc = CredentialRequestSdJwtVc +export type OpenId4VciCredentialOffer = AssertedUniformCredentialOffer +export type OpenId4VciCredentialOfferPayload = CredentialOfferPayloadV1_0_11 + +export type OpenId4VcSiopVerifiedAuthorizationRequest = VerifiedAuthorizationRequest +export type OpenId4VcSiopAuthorizationRequestPayload = AuthorizationRequestPayload +export type OpenId4VcSiopAuthorizationResponsePayload = AuthorizationResponsePayload +export type OpenId4VcSiopIdTokenPayload = IDTokenPayload + +export * from './OpenId4VcJwtIssuer' +export * from './CredentialHolderBinding' +export * from './OpenId4VciCredentialFormatProfile' diff --git a/packages/openid4vc/src/shared/router/context.ts b/packages/openid4vc/src/shared/router/context.ts new file mode 100644 index 0000000000..0bf538a69d --- /dev/null +++ b/packages/openid4vc/src/shared/router/context.ts @@ -0,0 +1,32 @@ +import type { AgentContext, Logger } from '@credo-ts/core' +import type { Response, Request } from 'express' + +import { CredoError } from '@credo-ts/core' + +export interface OpenId4VcRequest = Record> extends Request { + requestContext?: RC & OpenId4VcRequestContext +} + +export interface OpenId4VcRequestContext { + agentContext: AgentContext +} + +export function sendErrorResponse(response: Response, logger: Logger, code: number, message: string, error: unknown) { + const error_description = + error instanceof Error ? error.message : typeof error === 'string' ? error : 'An unknown error occurred.' + + const body = { error: message, error_description } + logger.warn(`[OID4VCI] Sending error response: ${JSON.stringify(body)}`, { + error, + }) + + return response.status(code).json(body) +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function getRequestContext>(request: T): NonNullable { + const requestContext = request.requestContext + if (!requestContext) throw new CredoError('Request context not set.') + + return requestContext +} diff --git a/packages/openid4vc/src/shared/router/express.ts b/packages/openid4vc/src/shared/router/express.ts new file mode 100644 index 0000000000..43bdcf12fa --- /dev/null +++ b/packages/openid4vc/src/shared/router/express.ts @@ -0,0 +1,12 @@ +import type { default as Express } from 'express' + +export function importExpress() { + try { + // NOTE: 'express' is added as a peer-dependency, and is required when using this module + // eslint-disable-next-line import/no-extraneous-dependencies, @typescript-eslint/no-var-requires + const express = require('express') as typeof Express + return express + } catch (error) { + throw new Error('Express must be installed as a peer dependency') + } +} diff --git a/packages/openid4vc/src/shared/router/index.ts b/packages/openid4vc/src/shared/router/index.ts new file mode 100644 index 0000000000..dc3697dcc1 --- /dev/null +++ b/packages/openid4vc/src/shared/router/index.ts @@ -0,0 +1,3 @@ +export * from './express' +export * from './context' +export * from './tenants' diff --git a/packages/openid4vc/src/shared/router/tenants.ts b/packages/openid4vc/src/shared/router/tenants.ts new file mode 100644 index 0000000000..cc3a2e1198 --- /dev/null +++ b/packages/openid4vc/src/shared/router/tenants.ts @@ -0,0 +1,56 @@ +import type { AgentContext, AgentContextProvider } from '@credo-ts/core' +import type { TenantsModule } from '@credo-ts/tenants' + +import { getApiForModuleByName, InjectionSymbols } from '@credo-ts/core' + +const OPENID4VC_ACTOR_IDS_METADATA_KEY = '_openid4vc/openId4VcActorIds' + +export async function getAgentContextForActorId(rootAgentContext: AgentContext, actorId: string) { + // Check if multi-tenancy is enabled, and if so find the associated multi-tenant record + // This is a bit hacky as it uses the tenants module to store the openid4vc actor id + // but this way we don't have to expose the contextCorrelationId in the openid metadata + const tenantsApi = getApiForModuleByName(rootAgentContext, 'TenantsModule') + if (tenantsApi) { + const [tenant] = await tenantsApi.findTenantsByQuery({ + [OPENID4VC_ACTOR_IDS_METADATA_KEY]: [actorId], + }) + + if (tenant) { + const agentContextProvider = rootAgentContext.dependencyManager.resolve( + InjectionSymbols.AgentContextProvider + ) + return agentContextProvider.getAgentContextForContextCorrelationId(tenant.id) + } + } + + return rootAgentContext +} + +/** + * Store the actor id associated with a context correlation id. If multi-tenancy is not used + * this method won't do anything as we can just use the actor from the default context. However + * if multi-tenancy is used, we will store the actor id in the tenant record metadata so it can + * be queried when a request comes in for the specific actor id. + * + * The reason for doing this is that we don't want to expose the context correlation id in the + * actor metadata url, as it is then possible to see exactly which actors are registered under + * the same agent. + */ +export async function storeActorIdForContextCorrelationId(agentContext: AgentContext, actorId: string) { + // It's kind of hacky, but we add support for the tenants module specifically here to map an actorId to + // a specific tenant. Otherwise we have to expose /:contextCorrelationId/:actorId in all the public URLs + // which is of course not so nice. + const tenantsApi = getApiForModuleByName(agentContext, 'TenantsModule') + + // We don't want to query the tenant record if the current context is the root context + if (tenantsApi && tenantsApi.rootAgentContext.contextCorrelationId !== agentContext.contextCorrelationId) { + const tenantRecord = await tenantsApi.getTenantById(agentContext.contextCorrelationId) + + const currentOpenId4VcActorIds = tenantRecord.metadata.get(OPENID4VC_ACTOR_IDS_METADATA_KEY) ?? [] + const openId4VcActorIds = [...currentOpenId4VcActorIds, actorId] + + tenantRecord.metadata.set(OPENID4VC_ACTOR_IDS_METADATA_KEY, openId4VcActorIds) + tenantRecord.setTag(OPENID4VC_ACTOR_IDS_METADATA_KEY, openId4VcActorIds) + await tenantsApi.updateTenant(tenantRecord) + } +} diff --git a/packages/openid4vc/src/shared/transform.ts b/packages/openid4vc/src/shared/transform.ts new file mode 100644 index 0000000000..bf2cebf80e --- /dev/null +++ b/packages/openid4vc/src/shared/transform.ts @@ -0,0 +1,73 @@ +import type { SdJwtVc, VerifiablePresentation, VerifiableCredential } from '@credo-ts/core' +import type { + W3CVerifiableCredential as SphereonW3cVerifiableCredential, + W3CVerifiablePresentation as SphereonW3cVerifiablePresentation, + CompactSdJwtVc as SphereonCompactSdJwtVc, + WrappedVerifiablePresentation, +} from '@sphereon/ssi-types' + +import { + JsonTransformer, + CredoError, + W3cJsonLdVerifiablePresentation, + W3cJwtVerifiablePresentation, + W3cJwtVerifiableCredential, + W3cJsonLdVerifiableCredential, + JsonEncoder, +} from '@credo-ts/core' + +export function getSphereonVerifiableCredential( + verifiableCredential: VerifiableCredential +): SphereonW3cVerifiableCredential | SphereonCompactSdJwtVc { + // encoded sd-jwt or jwt + if (typeof verifiableCredential === 'string') { + return verifiableCredential + } else if (verifiableCredential instanceof W3cJsonLdVerifiableCredential) { + return JsonTransformer.toJSON(verifiableCredential) as SphereonW3cVerifiableCredential + } else if (verifiableCredential instanceof W3cJwtVerifiableCredential) { + return verifiableCredential.serializedJwt + } else { + return verifiableCredential.compact + } +} + +export function getSphereonVerifiablePresentation( + verifiablePresentation: VerifiablePresentation +): SphereonW3cVerifiablePresentation | SphereonCompactSdJwtVc { + // encoded sd-jwt or jwt + if (typeof verifiablePresentation === 'string') { + return verifiablePresentation + } else if (verifiablePresentation instanceof W3cJsonLdVerifiablePresentation) { + return JsonTransformer.toJSON(verifiablePresentation) as SphereonW3cVerifiablePresentation + } else if (verifiablePresentation instanceof W3cJwtVerifiablePresentation) { + return verifiablePresentation.serializedJwt + } else { + return verifiablePresentation.compact + } +} + +export function getVerifiablePresentationFromSphereonWrapped( + wrappedVerifiablePresentation: WrappedVerifiablePresentation +): VerifiablePresentation { + if (wrappedVerifiablePresentation.format === 'jwt_vp') { + if (typeof wrappedVerifiablePresentation.original !== 'string') { + throw new CredoError('Unable to transform JWT VP to W3C VP') + } + + return W3cJwtVerifiablePresentation.fromSerializedJwt(wrappedVerifiablePresentation.original) + } else if (wrappedVerifiablePresentation.format === 'ldp_vp') { + return JsonTransformer.fromJSON(wrappedVerifiablePresentation.original, W3cJsonLdVerifiablePresentation) + } else if (wrappedVerifiablePresentation.format === 'vc+sd-jwt') { + // We use some custom logic here so we don't have to re-process the encoded SD-JWT + const [encodedHeader] = wrappedVerifiablePresentation.presentation.compactSdJwtVc.split('.') + const header = JsonEncoder.fromBase64(encodedHeader) + return { + compact: wrappedVerifiablePresentation.presentation.compactSdJwtVc, + header, + payload: wrappedVerifiablePresentation.presentation.signedPayload, + prettyClaims: wrappedVerifiablePresentation.presentation.decodedPayload, + } satisfies SdJwtVc + } + + throw new CredoError(`Unsupported presentation format: ${wrappedVerifiablePresentation.format}`) +} diff --git a/packages/openid4vc/src/shared/utils.ts b/packages/openid4vc/src/shared/utils.ts new file mode 100644 index 0000000000..171ae0d0f6 --- /dev/null +++ b/packages/openid4vc/src/shared/utils.ts @@ -0,0 +1,103 @@ +import type { OpenId4VcJwtIssuer } from './models' +import type { AgentContext, JwaSignatureAlgorithm, Key } from '@credo-ts/core' +import type { DIDDocument, SigningAlgo, SuppliedSignature } from '@sphereon/did-auth-siop' + +import { + CredoError, + DidsApi, + TypedArrayEncoder, + getKeyFromVerificationMethod, + getJwkClassFromKeyType, + SignatureSuiteRegistry, +} from '@credo-ts/core' + +/** + * Returns the JWA Signature Algorithms that are supported by the wallet. + * + * This is an approximation based on the supported key types of the wallet. + * This is not 100% correct as a supporting a key type does not mean you support + * all the algorithms for that key type. However, this needs refactoring of the wallet + * that is planned for the 0.5.0 release. + */ +export function getSupportedJwaSignatureAlgorithms(agentContext: AgentContext): JwaSignatureAlgorithm[] { + const supportedKeyTypes = agentContext.wallet.supportedKeyTypes + + // Extract the supported JWS algs based on the key types the wallet support. + const supportedJwaSignatureAlgorithms = supportedKeyTypes + // Map the supported key types to the supported JWK class + .map(getJwkClassFromKeyType) + // Filter out the undefined values + .filter((jwkClass): jwkClass is Exclude => jwkClass !== undefined) + // Extract the supported JWA signature algorithms from the JWK class + .flatMap((jwkClass) => jwkClass.supportedSignatureAlgorithms) + + return supportedJwaSignatureAlgorithms +} + +export async function getSphereonSuppliedSignatureFromJwtIssuer( + agentContext: AgentContext, + jwtIssuer: OpenId4VcJwtIssuer +): Promise { + let key: Key + let alg: string + let kid: string | undefined + let did: string | undefined + + if (jwtIssuer.method === 'did') { + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const didDocument = await didsApi.resolveDidDocument(jwtIssuer.didUrl) + const verificationMethod = didDocument.dereferenceKey(jwtIssuer.didUrl, ['authentication']) + + // get the key from the verification method and use the first supported signature algorithm + key = getKeyFromVerificationMethod(verificationMethod) + const _alg = getJwkClassFromKeyType(key.keyType)?.supportedSignatureAlgorithms[0] + if (!_alg) throw new CredoError(`No supported signature algorithms for key type: ${key.keyType}`) + + alg = _alg + kid = verificationMethod.id + did = verificationMethod.controller + } else { + throw new CredoError(`Unsupported jwt issuer method '${jwtIssuer.method as string}'. Only 'did' is supported.`) + } + + return { + signature: async (data: string | Uint8Array) => { + if (typeof data !== 'string') throw new CredoError("Expected string but received 'Uint8Array'") + const signedData = await agentContext.wallet.sign({ + data: TypedArrayEncoder.fromString(data), + key, + }) + + const signature = TypedArrayEncoder.toBase64URL(signedData) + return signature + }, + alg: alg as unknown as SigningAlgo, + did, + kid, + } +} + +export function getSphereonDidResolver(agentContext: AgentContext) { + return { + resolve: async (didUrl: string) => { + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const result = await didsApi.resolve(didUrl) + + return { + ...result, + didDocument: result.didDocument?.toJSON() as DIDDocument, + } + }, + } +} + +export function getProofTypeFromKey(agentContext: AgentContext, key: Key) { + const signatureSuiteRegistry = agentContext.dependencyManager.resolve(SignatureSuiteRegistry) + + const supportedSignatureSuites = signatureSuiteRegistry.getAllByKeyType(key.keyType) + if (supportedSignatureSuites.length === 0) { + throw new CredoError(`Couldn't find a supported signature suite for the given key type '${key.keyType}'.`) + } + + return supportedSignatureSuites[0].proofType +} diff --git a/packages/openid4vc/tests/openid4vc.e2e.test.ts b/packages/openid4vc/tests/openid4vc.e2e.test.ts new file mode 100644 index 0000000000..0391bd1e8a --- /dev/null +++ b/packages/openid4vc/tests/openid4vc.e2e.test.ts @@ -0,0 +1,683 @@ +import type { AgentType, TenantType } from './utils' +import type { OpenId4VciCredentialBindingResolver } from '../src/openid4vc-holder' +import type { DifPresentationExchangeDefinitionV2, SdJwtVc } from '@credo-ts/core' +import type { Server } from 'http' + +import { + CredoError, + ClaimFormat, + DidsApi, + DifPresentationExchangeService, + getJwkFromKey, + getKeyFromVerificationMethod, + JsonEncoder, + JwaSignatureAlgorithm, + W3cCredential, + W3cCredentialSubject, + w3cDate, + W3cIssuer, +} from '@credo-ts/core' +import express, { type Express } from 'express' + +import { AskarModule } from '../../askar/src' +import { askarModuleConfig } from '../../askar/tests/helpers' +import { TenantsModule } from '../../tenants/src' +import { OpenId4VcHolderModule, OpenId4VcIssuerModule, OpenId4VcVerifierModule } from '../src' + +import { createAgentFromModules, createTenantForAgent } from './utils' +import { universityDegreeCredentialSdJwt, universityDegreeCredentialSdJwt2 } from './utilsVci' +import { openBadgePresentationDefinition, universityDegreePresentationDefinition } from './utilsVp' + +const serverPort = 1234 +const baseUrl = `http://localhost:${serverPort}` +const issuanceBaseUrl = `${baseUrl}/oid4vci` +const verificationBaseUrl = `${baseUrl}/oid4vp` + +describe('OpenId4Vc', () => { + let expressApp: Express + let expressServer: Server + + let issuer: AgentType<{ + openId4VcIssuer: OpenId4VcIssuerModule + tenants: TenantsModule<{ openId4VcIssuer: OpenId4VcIssuerModule }> + }> + let issuer1: TenantType + let issuer2: TenantType + + let holder: AgentType<{ + openId4VcHolder: OpenId4VcHolderModule + tenants: TenantsModule<{ openId4VcHolder: OpenId4VcHolderModule }> + }> + let holder1: TenantType + + let verifier: AgentType<{ + openId4VcVerifier: OpenId4VcVerifierModule + tenants: TenantsModule<{ openId4VcVerifier: OpenId4VcVerifierModule }> + }> + let verifier1: TenantType + let verifier2: TenantType + + beforeEach(async () => { + expressApp = express() + + issuer = (await createAgentFromModules( + 'issuer', + { + openId4VcIssuer: new OpenId4VcIssuerModule({ + baseUrl: issuanceBaseUrl, + endpoints: { + credential: { + credentialRequestToCredentialMapper: async ({ agentContext, credentialRequest, holderBinding }) => { + // We sign the request with the first did:key did we have + const didsApi = agentContext.dependencyManager.resolve(DidsApi) + const [firstDidKeyDid] = await didsApi.getCreatedDids({ method: 'key' }) + const didDocument = await didsApi.resolveDidDocument(firstDidKeyDid.did) + const verificationMethod = didDocument.verificationMethod?.[0] + if (!verificationMethod) { + throw new Error('No verification method found') + } + + if (credentialRequest.format === 'vc+sd-jwt') { + return { + format: credentialRequest.format, + payload: { vct: credentialRequest.vct, university: 'innsbruck', degree: 'bachelor' }, + holder: holderBinding, + issuer: { + method: 'did', + didUrl: verificationMethod.id, + }, + disclosureFrame: { university: true, degree: true }, + } + } + + throw new Error('Invalid request') + }, + }, + }, + }), + askar: new AskarModule(askarModuleConfig), + tenants: new TenantsModule(), + }, + '96213c3d7fc8d4d6754c7a0fd969598g' + )) as unknown as typeof issuer + issuer1 = await createTenantForAgent(issuer.agent, 'iTenant1') + issuer2 = await createTenantForAgent(issuer.agent, 'iTenant2') + + holder = (await createAgentFromModules( + 'holder', + { + openId4VcHolder: new OpenId4VcHolderModule(), + askar: new AskarModule(askarModuleConfig), + tenants: new TenantsModule(), + }, + '96213c3d7fc8d4d6754c7a0fd969598e' + )) as unknown as typeof holder + holder1 = await createTenantForAgent(holder.agent, 'hTenant1') + + verifier = (await createAgentFromModules( + 'verifier', + { + openId4VcVerifier: new OpenId4VcVerifierModule({ + baseUrl: verificationBaseUrl, + }), + askar: new AskarModule(askarModuleConfig), + tenants: new TenantsModule(), + }, + '96213c3d7fc8d4d6754c7a0fd969598f' + )) as unknown as typeof verifier + verifier1 = await createTenantForAgent(verifier.agent, 'vTenant1') + verifier2 = await createTenantForAgent(verifier.agent, 'vTenant2') + + // We let AFJ create the router, so we have a fresh one each time + expressApp.use('/oid4vci', issuer.agent.modules.openId4VcIssuer.config.router) + expressApp.use('/oid4vp', verifier.agent.modules.openId4VcVerifier.config.router) + + expressServer = expressApp.listen(serverPort) + }) + + afterEach(async () => { + expressServer?.close() + + await issuer.agent.shutdown() + await issuer.agent.wallet.delete() + + await holder.agent.shutdown() + await holder.agent.wallet.delete() + }) + + const credentialBindingResolver: OpenId4VciCredentialBindingResolver = ({ supportsJwk, supportedDidMethods }) => { + // prefer did:key + if (supportedDidMethods?.includes('did:key')) { + return { + method: 'did', + didUrl: holder1.verificationMethod.id, + } + } + + // otherwise fall back to JWK + if (supportsJwk) { + return { + method: 'jwk', + jwk: getJwkFromKey(getKeyFromVerificationMethod(holder1.verificationMethod)), + } + } + + // otherwise throw an error + throw new CredoError('Issuer does not support did:key or JWK for credential binding') + } + + it('e2e flow with tenants, issuer endpoints requesting a sd-jwt-vc', async () => { + const issuerTenant1 = await issuer.agent.modules.tenants.getTenantAgent({ tenantId: issuer1.tenantId }) + const issuerTenant2 = await issuer.agent.modules.tenants.getTenantAgent({ tenantId: issuer2.tenantId }) + + const openIdIssuerTenant1 = await issuerTenant1.modules.openId4VcIssuer.createIssuer({ + credentialsSupported: [universityDegreeCredentialSdJwt], + }) + + const openIdIssuerTenant2 = await issuerTenant2.modules.openId4VcIssuer.createIssuer({ + credentialsSupported: [universityDegreeCredentialSdJwt2], + }) + + const { credentialOffer: credentialOffer1 } = await issuerTenant1.modules.openId4VcIssuer.createCredentialOffer({ + issuerId: openIdIssuerTenant1.issuerId, + offeredCredentials: [universityDegreeCredentialSdJwt.id], + preAuthorizedCodeFlowConfig: { userPinRequired: false }, + }) + + const { credentialOffer: credentialOffer2 } = await issuerTenant2.modules.openId4VcIssuer.createCredentialOffer({ + issuerId: openIdIssuerTenant2.issuerId, + offeredCredentials: [universityDegreeCredentialSdJwt2.id], + preAuthorizedCodeFlowConfig: { userPinRequired: false }, + }) + + await issuerTenant1.endSession() + await issuerTenant2.endSession() + + const holderTenant1 = await holder.agent.modules.tenants.getTenantAgent({ tenantId: holder1.tenantId }) + + const resolvedCredentialOffer1 = await holderTenant1.modules.openId4VcHolder.resolveCredentialOffer( + credentialOffer1 + ) + + expect(resolvedCredentialOffer1.credentialOfferPayload.credential_issuer).toEqual( + `${issuanceBaseUrl}/${openIdIssuerTenant1.issuerId}` + ) + expect(resolvedCredentialOffer1.metadata.credentialIssuerMetadata?.token_endpoint).toEqual( + `${issuanceBaseUrl}/${openIdIssuerTenant1.issuerId}/token` + ) + expect(resolvedCredentialOffer1.metadata.credentialIssuerMetadata?.credential_endpoint).toEqual( + `${issuanceBaseUrl}/${openIdIssuerTenant1.issuerId}/credential` + ) + + // Bind to JWK + const credentialsTenant1 = await holderTenant1.modules.openId4VcHolder.acceptCredentialOfferUsingPreAuthorizedCode( + resolvedCredentialOffer1, + { + credentialBindingResolver, + } + ) + + expect(credentialsTenant1).toHaveLength(1) + const compactSdJwtVcTenant1 = (credentialsTenant1[0] as SdJwtVc).compact + const sdJwtVcTenant1 = holderTenant1.sdJwtVc.fromCompact(compactSdJwtVcTenant1) + expect(sdJwtVcTenant1.payload.vct).toEqual('UniversityDegreeCredential') + + const resolvedCredentialOffer2 = await holderTenant1.modules.openId4VcHolder.resolveCredentialOffer( + credentialOffer2 + ) + expect(resolvedCredentialOffer2.credentialOfferPayload.credential_issuer).toEqual( + `${issuanceBaseUrl}/${openIdIssuerTenant2.issuerId}` + ) + expect(resolvedCredentialOffer2.metadata.credentialIssuerMetadata?.token_endpoint).toEqual( + `${issuanceBaseUrl}/${openIdIssuerTenant2.issuerId}/token` + ) + expect(resolvedCredentialOffer2.metadata.credentialIssuerMetadata?.credential_endpoint).toEqual( + `${issuanceBaseUrl}/${openIdIssuerTenant2.issuerId}/credential` + ) + + // Bind to did + const credentialsTenant2 = await holderTenant1.modules.openId4VcHolder.acceptCredentialOfferUsingPreAuthorizedCode( + resolvedCredentialOffer2, + { + credentialBindingResolver, + } + ) + + expect(credentialsTenant2).toHaveLength(1) + const compactSdJwtVcTenant2 = (credentialsTenant2[0] as SdJwtVc).compact + const sdJwtVcTenant2 = holderTenant1.sdJwtVc.fromCompact(compactSdJwtVcTenant2) + expect(sdJwtVcTenant2.payload.vct).toEqual('UniversityDegreeCredential2') + + await holderTenant1.endSession() + }) + + it('e2e flow with tenants, verifier endpoints verifying a jwt-vc', async () => { + const holderTenant = await holder.agent.modules.tenants.getTenantAgent({ tenantId: holder1.tenantId }) + const verifierTenant1 = await verifier.agent.modules.tenants.getTenantAgent({ tenantId: verifier1.tenantId }) + const verifierTenant2 = await verifier.agent.modules.tenants.getTenantAgent({ tenantId: verifier2.tenantId }) + + const openIdVerifierTenant1 = await verifierTenant1.modules.openId4VcVerifier.createVerifier() + const openIdVerifierTenant2 = await verifierTenant2.modules.openId4VcVerifier.createVerifier() + + const signedCredential1 = await issuer.agent.w3cCredentials.signCredential({ + format: ClaimFormat.JwtVc, + credential: new W3cCredential({ + type: ['VerifiableCredential', 'OpenBadgeCredential'], + issuer: new W3cIssuer({ id: issuer.did }), + credentialSubject: new W3cCredentialSubject({ id: holder1.did }), + issuanceDate: w3cDate(Date.now()), + }), + alg: JwaSignatureAlgorithm.EdDSA, + verificationMethod: issuer.verificationMethod.id, + }) + + const signedCredential2 = await issuer.agent.w3cCredentials.signCredential({ + format: ClaimFormat.JwtVc, + credential: new W3cCredential({ + type: ['VerifiableCredential', 'UniversityDegreeCredential'], + issuer: new W3cIssuer({ id: issuer.did }), + credentialSubject: new W3cCredentialSubject({ id: holder1.did }), + issuanceDate: w3cDate(Date.now()), + }), + alg: JwaSignatureAlgorithm.EdDSA, + verificationMethod: issuer.verificationMethod.id, + }) + + await holderTenant.w3cCredentials.storeCredential({ credential: signedCredential1 }) + await holderTenant.w3cCredentials.storeCredential({ credential: signedCredential2 }) + + const { + authorizationRequestUri: authorizationRequestUri1, + authorizationRequestPayload: authorizationRequestPayload1, + } = await verifierTenant1.modules.openId4VcVerifier.createAuthorizationRequest({ + verifierId: openIdVerifierTenant1.verifierId, + requestSigner: { + method: 'did', + didUrl: verifier1.verificationMethod.id, + }, + presentationExchange: { + definition: openBadgePresentationDefinition, + }, + }) + + expect( + authorizationRequestUri1.startsWith( + `openid://?redirect_uri=http%3A%2F%2Flocalhost%3A1234%2Foid4vp%2F${openIdVerifierTenant1.verifierId}%2Fauthorize` + ) + ).toBe(true) + + const { + authorizationRequestUri: authorizationRequestUri2, + authorizationRequestPayload: authorizationRequestPayload2, + } = await verifierTenant2.modules.openId4VcVerifier.createAuthorizationRequest({ + requestSigner: { + method: 'did', + didUrl: verifier2.verificationMethod.id, + }, + presentationExchange: { + definition: universityDegreePresentationDefinition, + }, + verifierId: openIdVerifierTenant2.verifierId, + }) + + expect( + authorizationRequestUri2.startsWith( + `openid://?redirect_uri=http%3A%2F%2Flocalhost%3A1234%2Foid4vp%2F${openIdVerifierTenant2.verifierId}%2Fauthorize` + ) + ).toBe(true) + + await verifierTenant1.endSession() + await verifierTenant2.endSession() + + const resolvedProofRequest1 = await holderTenant.modules.openId4VcHolder.resolveSiopAuthorizationRequest( + authorizationRequestUri1 + ) + + expect(resolvedProofRequest1.presentationExchange?.credentialsForRequest).toMatchObject({ + areRequirementsSatisfied: true, + requirements: [ + { + submissionEntry: [ + { + verifiableCredentials: [ + { + credential: { + type: ['VerifiableCredential', 'OpenBadgeCredential'], + }, + }, + ], + }, + ], + }, + ], + }) + + const resolvedProofRequest2 = await holderTenant.modules.openId4VcHolder.resolveSiopAuthorizationRequest( + authorizationRequestUri2 + ) + + expect(resolvedProofRequest2.presentationExchange?.credentialsForRequest).toMatchObject({ + areRequirementsSatisfied: true, + requirements: [ + { + submissionEntry: [ + { + verifiableCredentials: [ + { + credential: { + type: ['VerifiableCredential', 'UniversityDegreeCredential'], + }, + }, + ], + }, + ], + }, + ], + }) + + if (!resolvedProofRequest1.presentationExchange || !resolvedProofRequest2.presentationExchange) { + throw new Error('Presentation exchange not defined') + } + + const presentationExchangeService = holderTenant.dependencyManager.resolve(DifPresentationExchangeService) + const selectedCredentials = presentationExchangeService.selectCredentialsForRequest( + resolvedProofRequest1.presentationExchange.credentialsForRequest + ) + + const { submittedResponse: submittedResponse1, serverResponse: serverResponse1 } = + await holderTenant.modules.openId4VcHolder.acceptSiopAuthorizationRequest({ + authorizationRequest: resolvedProofRequest1.authorizationRequest, + presentationExchange: { + credentials: selectedCredentials, + }, + }) + + expect(submittedResponse1).toEqual({ + expires_in: 6000, + id_token: expect.any(String), + presentation_submission: { + definition_id: 'OpenBadgeCredential', + descriptor_map: [ + { + format: 'jwt_vp', + id: 'OpenBadgeCredentialDescriptor', + path: '$', + path_nested: { + format: 'jwt_vc', + id: 'OpenBadgeCredentialDescriptor', + path: '$.vp.verifiableCredential[0]', + }, + }, + ], + id: expect.any(String), + }, + state: expect.any(String), + vp_token: expect.any(String), + }) + expect(serverResponse1).toMatchObject({ + status: 200, + }) + + // The RP MUST validate that the aud (audience) Claim contains the value of the client_id + // that the RP sent in the Authorization Request as an audience. + // When the request has been signed, the value might be an HTTPS URL, or a Decentralized Identifier. + const verifierTenant1_2 = await verifier.agent.modules.tenants.getTenantAgent({ tenantId: verifier1.tenantId }) + const { idToken: idToken1, presentationExchange: presentationExchange1 } = + await verifierTenant1_2.modules.openId4VcVerifier.verifyAuthorizationResponse({ + authorizationResponse: submittedResponse1, + verifierId: openIdVerifierTenant1.verifierId, + }) + + const requestObjectPayload1 = JsonEncoder.fromBase64(authorizationRequestPayload1.request?.split('.')[1] as string) + expect(idToken1?.payload).toMatchObject({ + state: requestObjectPayload1.state, + nonce: requestObjectPayload1.nonce, + }) + + expect(presentationExchange1).toMatchObject({ + definition: openBadgePresentationDefinition, + submission: { + definition_id: 'OpenBadgeCredential', + }, + presentations: [ + { + verifiableCredential: [ + { + type: ['VerifiableCredential', 'OpenBadgeCredential'], + }, + ], + }, + ], + }) + + const selectedCredentials2 = presentationExchangeService.selectCredentialsForRequest( + resolvedProofRequest2.presentationExchange.credentialsForRequest + ) + + const { serverResponse: serverResponse2, submittedResponse: submittedResponse2 } = + await holderTenant.modules.openId4VcHolder.acceptSiopAuthorizationRequest({ + authorizationRequest: resolvedProofRequest2.authorizationRequest, + presentationExchange: { + credentials: selectedCredentials2, + }, + }) + expect(serverResponse2).toMatchObject({ + status: 200, + }) + + // The RP MUST validate that the aud (audience) Claim contains the value of the client_id + // that the RP sent in the Authorization Request as an audience. + // When the request has been signed, the value might be an HTTPS URL, or a Decentralized Identifier. + const verifierTenant2_2 = await verifier.agent.modules.tenants.getTenantAgent({ tenantId: verifier2.tenantId }) + const { idToken: idToken2, presentationExchange: presentationExchange2 } = + await verifierTenant2_2.modules.openId4VcVerifier.verifyAuthorizationResponse({ + authorizationResponse: submittedResponse2, + verifierId: openIdVerifierTenant2.verifierId, + }) + + const requestObjectPayload2 = JsonEncoder.fromBase64(authorizationRequestPayload2.request?.split('.')[1] as string) + expect(idToken2?.payload).toMatchObject({ + state: requestObjectPayload2.state, + nonce: requestObjectPayload2.nonce, + }) + + expect(presentationExchange2).toMatchObject({ + definition: universityDegreePresentationDefinition, + submission: { + definition_id: 'UniversityDegreeCredential', + }, + presentations: [ + { + verifiableCredential: [ + { + type: ['VerifiableCredential', 'UniversityDegreeCredential'], + }, + ], + }, + ], + }) + }) + + it('e2e flow with verifier endpoints verifying a sd-jwt-vc with selective disclosure', async () => { + const openIdVerifier = await verifier.agent.modules.openId4VcVerifier.createVerifier() + + const signedSdJwtVc = await issuer.agent.sdJwtVc.sign({ + holder: { + method: 'did', + didUrl: holder.kid, + }, + issuer: { + method: 'did', + didUrl: issuer.kid, + }, + payload: { + vct: 'OpenBadgeCredential', + university: 'innsbruck', + degree: 'bachelor', + name: 'John Doe', + }, + disclosureFrame: { + university: true, + name: true, + }, + }) + + await holder.agent.sdJwtVc.store(signedSdJwtVc.compact) + + const presentationDefinition = { + id: 'OpenBadgeCredential', + input_descriptors: [ + { + id: 'OpenBadgeCredentialDescriptor', + // FIXME: https://github.com/Sphereon-Opensource/pex-openapi/issues/32 + // format: { + // 'vc+sd-jwt': { + // 'sd-jwt_alg_values': ['EdDSA'], + // }, + // }, + constraints: { + limit_disclosure: 'required', + fields: [ + { + path: ['$.vct'], + filter: { + type: 'string', + const: 'OpenBadgeCredential', + }, + }, + { + path: ['$.university'], + }, + ], + }, + }, + ], + } satisfies DifPresentationExchangeDefinitionV2 + + const { authorizationRequestUri, authorizationRequestPayload } = + await verifier.agent.modules.openId4VcVerifier.createAuthorizationRequest({ + verifierId: openIdVerifier.verifierId, + requestSigner: { + method: 'did', + didUrl: verifier.kid, + }, + presentationExchange: { + definition: presentationDefinition, + }, + }) + + expect( + authorizationRequestUri.startsWith( + `openid://?redirect_uri=http%3A%2F%2Flocalhost%3A1234%2Foid4vp%2F${openIdVerifier.verifierId}%2Fauthorize` + ) + ).toBe(true) + + const resolvedAuthorizationRequest = await holder.agent.modules.openId4VcHolder.resolveSiopAuthorizationRequest( + authorizationRequestUri + ) + + expect(resolvedAuthorizationRequest.presentationExchange?.credentialsForRequest).toMatchObject({ + areRequirementsSatisfied: true, + requirements: [ + { + submissionEntry: [ + { + verifiableCredentials: [ + { + // FIXME: because we have the record, we don't know which fields will be disclosed + // Can we temp-assign these to the record? + compactSdJwtVc: signedSdJwtVc.compact, + }, + ], + }, + ], + }, + ], + }) + + if (!resolvedAuthorizationRequest.presentationExchange) { + throw new Error('Presentation exchange not defined') + } + + // TODO: better way to auto-select + const presentationExchangeService = holder.agent.dependencyManager.resolve(DifPresentationExchangeService) + const selectedCredentials = presentationExchangeService.selectCredentialsForRequest( + resolvedAuthorizationRequest.presentationExchange.credentialsForRequest + ) + + const { serverResponse, submittedResponse } = + await holder.agent.modules.openId4VcHolder.acceptSiopAuthorizationRequest({ + authorizationRequest: resolvedAuthorizationRequest.authorizationRequest, + presentationExchange: { + credentials: selectedCredentials, + }, + }) + + // path_nested should not be used for sd-jwt + expect(submittedResponse.presentation_submission?.descriptor_map[0].path_nested).toBeUndefined() + expect(submittedResponse).toEqual({ + expires_in: 6000, + id_token: expect.any(String), + presentation_submission: { + definition_id: 'OpenBadgeCredential', + descriptor_map: [ + { + format: 'vc+sd-jwt', + id: 'OpenBadgeCredentialDescriptor', + path: '$', + }, + ], + id: expect.any(String), + }, + state: expect.any(String), + vp_token: expect.any(String), + }) + expect(serverResponse).toMatchObject({ + status: 200, + }) + + // The RP MUST validate that the aud (audience) Claim contains the value of the client_id + // that the RP sent in the Authorization Request as an audience. + // When the request has been signed, the value might be an HTTPS URL, or a Decentralized Identifier. + const { idToken, presentationExchange } = + await verifier.agent.modules.openId4VcVerifier.verifyAuthorizationResponse({ + authorizationResponse: submittedResponse, + verifierId: openIdVerifier.verifierId, + }) + + const requestObjectPayload = JsonEncoder.fromBase64(authorizationRequestPayload.request?.split('.')[1] as string) + expect(idToken?.payload).toMatchObject({ + state: requestObjectPayload.state, + nonce: requestObjectPayload.nonce, + }) + + const presentation = presentationExchange?.presentations[0] as SdJwtVc + + // name SHOULD NOT be disclosed + expect(presentation.prettyClaims).not.toHaveProperty('name') + + // university and name SHOULD NOT be in the signed payload + expect(presentation.payload).not.toHaveProperty('university') + expect(presentation.payload).not.toHaveProperty('name') + + expect(presentationExchange).toMatchObject({ + definition: presentationDefinition, + submission: { + definition_id: 'OpenBadgeCredential', + }, + presentations: [ + { + payload: { + vct: 'OpenBadgeCredential', + degree: 'bachelor', + }, + // university SHOULD be disclosed + prettyClaims: { + degree: 'bachelor', + university: 'innsbruck', + }, + }, + ], + }) + }) +}) diff --git a/packages/openid4vc-client/tests/setup.ts b/packages/openid4vc/tests/setup.ts similarity index 100% rename from packages/openid4vc-client/tests/setup.ts rename to packages/openid4vc/tests/setup.ts diff --git a/packages/openid4vc/tests/utils.ts b/packages/openid4vc/tests/utils.ts new file mode 100644 index 0000000000..88fcfe06a7 --- /dev/null +++ b/packages/openid4vc/tests/utils.ts @@ -0,0 +1,74 @@ +import type { TenantAgent } from '../../tenants/src/TenantAgent' +import type { KeyDidCreateOptions, ModulesMap } from '@credo-ts/core' +import type { TenantsModule } from '@credo-ts/tenants' + +import { LogLevel, Agent, DidKey, KeyType, TypedArrayEncoder, utils } from '@credo-ts/core' + +import { agentDependencies, TestLogger } from '../../core/tests' + +export async function createDidKidVerificationMethod(agent: Agent | TenantAgent, secretKey?: string) { + const didCreateResult = await agent.dids.create({ + method: 'key', + options: { keyType: KeyType.Ed25519 }, + secret: { privateKey: secretKey ? TypedArrayEncoder.fromString(secretKey) : undefined }, + }) + + const did = didCreateResult.didState.did as string + const didKey = DidKey.fromDid(did) + const kid = `${did}#${didKey.key.fingerprint}` + + const verificationMethod = didCreateResult.didState.didDocument?.dereferenceKey(kid, ['authentication']) + if (!verificationMethod) throw new Error('No verification method found') + + return { + did, + kid, + verificationMethod, + } +} + +export async function createAgentFromModules(label: string, modulesMap: MM, secretKey: string) { + const agent = new Agent({ + config: { label, walletConfig: { id: utils.uuid(), key: utils.uuid() }, logger: new TestLogger(LogLevel.off) }, + dependencies: agentDependencies, + modules: modulesMap, + }) + + await agent.initialize() + const data = await createDidKidVerificationMethod(agent, secretKey) + + return { + ...data, + agent, + } +} + +export type AgentType = Awaited>> + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +type AgentWithTenantsModule = Agent<{ tenants: TenantsModule }> + +export async function createTenantForAgent( + // FIXME: we need to make some improvements on the agent typing. It'a quite hard + // to get it right at the moment + // eslint-disable-next-line @typescript-eslint/no-explicit-any + agent: AgentWithTenantsModule & any, + label: string +) { + const tenantRecord = await agent.modules.tenants.createTenant({ + config: { + label, + }, + }) + + const tenant = await agent.modules.tenants.getTenantAgent({ tenantId: tenantRecord.id }) + const data = await createDidKidVerificationMethod(tenant) + await tenant.endSession() + + return { + ...data, + tenantId: tenantRecord.id, + } +} + +export type TenantType = Awaited> diff --git a/packages/openid4vc/tests/utilsVci.ts b/packages/openid4vc/tests/utilsVci.ts new file mode 100644 index 0000000000..798c9f76af --- /dev/null +++ b/packages/openid4vc/tests/utilsVci.ts @@ -0,0 +1,45 @@ +import type { OpenId4VciCredentialSupportedWithId } from '../src' + +import { OpenId4VciCredentialFormatProfile } from '../src' + +export const openBadgeCredential: OpenId4VciCredentialSupportedWithId = { + id: `/credentials/OpenBadgeCredential`, + format: OpenId4VciCredentialFormatProfile.JwtVcJson, + types: ['VerifiableCredential', 'OpenBadgeCredential'], +} + +export const universityDegreeCredential: OpenId4VciCredentialSupportedWithId = { + id: `/credentials/UniversityDegreeCredential`, + format: OpenId4VciCredentialFormatProfile.JwtVcJson, + types: ['VerifiableCredential', 'UniversityDegreeCredential'], +} + +export const universityDegreeCredentialLd: OpenId4VciCredentialSupportedWithId = { + id: `/credentials/UniversityDegreeCredentialLd`, + format: OpenId4VciCredentialFormatProfile.JwtVcJsonLd, + types: ['VerifiableCredential', 'UniversityDegreeCredential'], + '@context': ['context'], +} + +export const universityDegreeCredentialSdJwt = { + id: 'https://openid4vc-issuer.com/credentials/UniversityDegreeCredentialSdJwt', + format: OpenId4VciCredentialFormatProfile.SdJwtVc, + vct: 'UniversityDegreeCredential', + cryptographic_binding_methods_supported: ['did:key'], +} satisfies OpenId4VciCredentialSupportedWithId + +export const universityDegreeCredentialSdJwt2 = { + id: 'https://openid4vc-issuer.com/credentials/UniversityDegreeCredentialSdJwt2', + format: OpenId4VciCredentialFormatProfile.SdJwtVc, + vct: 'UniversityDegreeCredential2', + // FIXME: should this be dynamically generated? I think static is fine for now + cryptographic_binding_methods_supported: ['jwk'], +} satisfies OpenId4VciCredentialSupportedWithId + +export const allCredentialsSupported = [ + openBadgeCredential, + universityDegreeCredential, + universityDegreeCredentialLd, + universityDegreeCredentialSdJwt, + universityDegreeCredentialSdJwt2, +] diff --git a/packages/openid4vc/tests/utilsVp.ts b/packages/openid4vc/tests/utilsVp.ts new file mode 100644 index 0000000000..d92ecc1918 --- /dev/null +++ b/packages/openid4vc/tests/utilsVp.ts @@ -0,0 +1,121 @@ +import type { AgentContext, DifPresentationExchangeDefinitionV2, VerificationMethod } from '@credo-ts/core' + +import { + getKeyFromVerificationMethod, + W3cCredential, + W3cIssuer, + W3cCredentialSubject, + W3cCredentialService, + ClaimFormat, + CREDENTIALS_CONTEXT_V1_URL, +} from '@credo-ts/core' + +import { getProofTypeFromKey } from '../src/shared/utils' + +export const waltPortalOpenBadgeJwt = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6ejZNa3RpUVFFcW0yeWFwWEJEdDFXRVZCM2RxZ3Z5emk5NkZ1RkFOWW1yZ1RyS1Y5I3o2TWt0aVFRRXFtMnlhcFhCRHQxV0VWQjNkcWd2eXppOTZGdUZBTlltcmdUcktWOSJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiT3BlbkJhZGdlQ3JlZGVudGlhbCJdLCJjcmVkZW50aWFsU3ViamVjdCI6e319LCJpc3MiOiJkaWQ6a2V5Ono2TWt0aVFRRXFtMnlhcFhCRHQxV0VWQjNkcWd2eXppOTZGdUZBTlltcmdUcktWOSIsInN1YiI6ImRpZDprZXk6ejZNa3BHUjRnczRSYzNacGg0dmo4d1Juam5BeGdBUFN4Y1I4TUFWS3V0V3NwUXpjIiwibmJmIjoxNzAwNzQzMzM1fQ.OcKPyaWeVV-78BWr8N4h2Cyvjtc9jzknAqvTA77hTbKCNCEbhGboo-S6yXHLC-3NWYQ1vVcqZmdPlIOrHZ7MDw' + +export const waltUniversityDegreeJwt = + 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSIsImtpZCI6ImRpZDprZXk6ejZNa3RpUVFFcW0yeWFwWEJEdDFXRVZCM2RxZ3Z5emk5NkZ1RkFOWW1yZ1RyS1Y5I3o2TWt0aVFRRXFtMnlhcFhCRHQxV0VWQjNkcWd2eXppOTZGdUZBTlltcmdUcktWOSJ9.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiVW5pdmVyc2l0eURlZ3JlZUNyZWRlbnRpYWwiXSwiY3JlZGVudGlhbFN1YmplY3QiOnt9fSwiaXNzIjoiZGlkOmtleTp6Nk1rdGlRUUVxbTJ5YXBYQkR0MVdFVkIzZHFndnl6aTk2RnVGQU5ZbXJnVHJLVjkiLCJzdWIiOiJkaWQ6a2V5Ono2TWtwR1I0Z3M0UmMzWnBoNHZqOHdSbmpuQXhnQVBTeGNSOE1BVkt1dFdzcFF6YyIsIm5iZiI6MTcwMDc0MzM5NH0.EhMnE349oOvzbu0rFl-m_7FOoRsB5VucLV5tUUIW0jPxkJ7J0qVLOJTXVX4KNv_N9oeP8pgTUvydd6nxB_0KCQ' + +export const getOpenBadgeCredentialLdpVc = async ( + agentContext: AgentContext, + issuerVerificationMethod: VerificationMethod, + holderVerificationMethod: VerificationMethod +) => { + const credential = new W3cCredential({ + context: [CREDENTIALS_CONTEXT_V1_URL, 'https://www.w3.org/2018/credentials/examples/v1'], + type: ['VerifiableCredential', 'OpenBadgeCredential'], + id: 'http://example.edu/credentials/3732', + issuer: new W3cIssuer({ + id: issuerVerificationMethod.controller, + }), + issuanceDate: '2017-10-22T12:23:48Z', + expirationDate: '2027-10-22T12:23:48Z', + credentialSubject: new W3cCredentialSubject({ + id: holderVerificationMethod.controller, + }), + }) + + const w3cs = agentContext.dependencyManager.resolve(W3cCredentialService) + const key = getKeyFromVerificationMethod(holderVerificationMethod) + const proofType = getProofTypeFromKey(agentContext, key) + const signedLdpVc = await w3cs.signCredential(agentContext, { + format: ClaimFormat.LdpVc, + credential, + verificationMethod: issuerVerificationMethod.id, + proofType, + }) + + return signedLdpVc +} +export const openBadgeCredentialPresentationDefinitionLdpVc: DifPresentationExchangeDefinitionV2 = { + id: 'OpenBadgeCredential', + input_descriptors: [ + { + id: 'OpenBadgeCredential', + // changed jwt_vc_json to jwt_vc + format: { ldp_vc: { proof_type: ['Ed25519Signature2018'] } }, + // changed $.type to $.vc.type + constraints: { + fields: [{ path: ['$.type.*', '$.vc.type'], filter: { type: 'string', pattern: 'OpenBadgeCredential' } }], + }, + }, + ], +} + +export const universityDegreePresentationDefinition: DifPresentationExchangeDefinitionV2 = { + id: 'UniversityDegreeCredential', + input_descriptors: [ + { + id: 'UniversityDegree', + // changed jwt_vc_json to jwt_vc + format: { jwt_vc: { alg: ['EdDSA'] } }, + // changed $.type to $.vc.type + constraints: { + fields: [{ path: ['$.vc.type.*'], filter: { type: 'string', pattern: 'UniversityDegree' } }], + }, + }, + ], +} + +export const openBadgePresentationDefinition: DifPresentationExchangeDefinitionV2 = { + id: 'OpenBadgeCredential', + input_descriptors: [ + { + id: 'OpenBadgeCredentialDescriptor', + // changed jwt_vc_json to jwt_vc + format: { jwt_vc: { alg: ['EdDSA'] } }, + // changed $.type to $.vc.type + constraints: { + fields: [{ path: ['$.vc.type.*'], filter: { type: 'string', pattern: 'OpenBadgeCredential' } }], + }, + }, + ], +} + +export const combinePresentationDefinitions = ( + presentationDefinitions: DifPresentationExchangeDefinitionV2[] +): DifPresentationExchangeDefinitionV2 => { + return { + id: 'Combined', + input_descriptors: presentationDefinitions.flatMap((p) => p.input_descriptors), + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export function waitForMockFunction(mockFn: jest.Mock) { + return new Promise((resolve, reject) => { + const intervalId = setInterval(() => { + if (mockFn.mock.calls.length > 0) { + clearInterval(intervalId) + resolve(0) + } + }, 100) + + setTimeout(() => { + clearInterval(intervalId) + reject(new Error('Timeout Callback')) + }, 10000) + }) +} diff --git a/packages/openid4vc-client/tsconfig.build.json b/packages/openid4vc/tsconfig.build.json similarity index 100% rename from packages/openid4vc-client/tsconfig.build.json rename to packages/openid4vc/tsconfig.build.json diff --git a/packages/openid4vc-client/tsconfig.json b/packages/openid4vc/tsconfig.json similarity index 100% rename from packages/openid4vc-client/tsconfig.json rename to packages/openid4vc/tsconfig.json diff --git a/packages/question-answer/package.json b/packages/question-answer/package.json index 948e7cbf49..c50bf411ab 100644 --- a/packages/question-answer/package.json +++ b/packages/question-answer/package.json @@ -26,7 +26,7 @@ "dependencies": { "@credo-ts/core": "0.4.2", "class-transformer": "0.5.1", - "class-validator": "0.14.0", + "class-validator": "0.14.1", "rxjs": "^7.2.0" }, "devDependencies": { diff --git a/packages/question-answer/src/QuestionAnswerModule.ts b/packages/question-answer/src/QuestionAnswerModule.ts index 6b877724aa..5bb6873f2b 100644 --- a/packages/question-answer/src/QuestionAnswerModule.ts +++ b/packages/question-answer/src/QuestionAnswerModule.ts @@ -14,9 +14,6 @@ export class QuestionAnswerModule implements Module { * Registers the dependencies of the question answer module on the dependency manager. */ public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(QuestionAnswerApi) - // Services dependencyManager.registerSingleton(QuestionAnswerService) diff --git a/packages/question-answer/src/__tests__/QuestionAnswerModule.test.ts b/packages/question-answer/src/__tests__/QuestionAnswerModule.test.ts index aaa38e727b..d789f7e114 100644 --- a/packages/question-answer/src/__tests__/QuestionAnswerModule.test.ts +++ b/packages/question-answer/src/__tests__/QuestionAnswerModule.test.ts @@ -3,7 +3,6 @@ import type { DependencyManager, FeatureRegistry } from '@credo-ts/core' import { Protocol } from '@credo-ts/core' import { - QuestionAnswerApi, QuestionAnswerModule, QuestionAnswerRepository, QuestionAnswerRole, @@ -25,9 +24,6 @@ describe('QuestionAnswerModule', () => { const questionAnswerModule = new QuestionAnswerModule() questionAnswerModule.register(dependencyManager, featureRegistry) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledTimes(1) - expect(dependencyManager.registerContextScoped).toHaveBeenCalledWith(QuestionAnswerApi) - expect(dependencyManager.registerSingleton).toHaveBeenCalledTimes(2) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(QuestionAnswerService) expect(dependencyManager.registerSingleton).toHaveBeenCalledWith(QuestionAnswerRepository) diff --git a/packages/sd-jwt-vc/README.md b/packages/sd-jwt-vc/README.md deleted file mode 100644 index 5d88c256e5..0000000000 --- a/packages/sd-jwt-vc/README.md +++ /dev/null @@ -1,57 +0,0 @@ -

-
- Credo Logo -

-

Credo Selective Disclosure JWT VC Module

-

- License - typescript - @credo-ts/sd-jwt-vc version -

-
- -### Installation - -Add the `sd-jwt-vc` module to your project. - -```sh -yarn add @credo-ts/sd-jwt-vc -``` - -### Quick start - -After the installation you can follow the [guide to setup your agent](https://credo.js.org/guides/0.4/getting-started/set-up) and add the following to your agent modules. - -```ts -import { SdJwtVcModule } from '@credo-ts/sd-jwt-vc' - -const agent = new Agent({ - config: { - /* config */ - }, - dependencies: agentDependencies, - modules: { - sdJwtVc: new SdJwtVcModule(), - /* other custom modules */ - }, -}) - -await agent.initialize() -``` diff --git a/packages/sd-jwt-vc/package.json b/packages/sd-jwt-vc/package.json deleted file mode 100644 index d2bede53cd..0000000000 --- a/packages/sd-jwt-vc/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "@credo-ts/sd-jwt-vc", - "main": "build/index", - "types": "build/index", - "version": "0.4.2", - "private": true, - "files": [ - "build" - ], - "license": "Apache-2.0", - "publishConfig": { - "access": "public" - }, - "homepage": "https://github.com/openwallet-foundation/credo-ts/tree/main/packages/sd-jwt-vc", - "repository": { - "type": "git", - "url": "https://github.com/openwallet-foundation/credo-ts", - "directory": "packages/sd-jwt-vc" - }, - "scripts": { - "build": "yarn run clean && yarn run compile", - "clean": "rimraf ./build", - "compile": "tsc -p tsconfig.build.json", - "prepublishOnly": "yarn run build", - "test": "jest" - }, - "dependencies": { - "@credo-ts/askar": "^0.4.2", - "@credo-ts/core": "^0.4.2", - "class-transformer": "0.5.1", - "class-validator": "0.14.0", - "jwt-sd": "^0.1.2" - }, - "devDependencies": { - "reflect-metadata": "^0.1.13", - "rimraf": "^4.4.0", - "typescript": "~4.9.5" - } -} diff --git a/packages/sd-jwt-vc/src/SdJwtVcApi.ts b/packages/sd-jwt-vc/src/SdJwtVcApi.ts deleted file mode 100644 index e72206c28d..0000000000 --- a/packages/sd-jwt-vc/src/SdJwtVcApi.ts +++ /dev/null @@ -1,93 +0,0 @@ -import type { - SdJwtVcCreateOptions, - SdJwtVcPresentOptions, - SdJwtVcReceiveOptions, - SdJwtVcVerifyOptions, -} from './SdJwtVcOptions' -import type { SdJwtVcVerificationResult } from './SdJwtVcService' -import type { SdJwtVcRecord } from './repository' -import type { Query } from '@credo-ts/core' - -import { AgentContext, injectable } from '@credo-ts/core' - -import { SdJwtVcService } from './SdJwtVcService' - -/** - * @public - */ -@injectable() -export class SdJwtVcApi { - private agentContext: AgentContext - private sdJwtVcService: SdJwtVcService - - public constructor(agentContext: AgentContext, sdJwtVcService: SdJwtVcService) { - this.agentContext = agentContext - this.sdJwtVcService = sdJwtVcService - } - - public async create = Record>( - payload: Payload, - options: SdJwtVcCreateOptions - ): Promise<{ sdJwtVcRecord: SdJwtVcRecord; compact: string }> { - return await this.sdJwtVcService.create(this.agentContext, payload, options) - } - - /** - * - * Validates and stores an sd-jwt-vc from the perspective of an holder - * - */ - public async storeCredential(sdJwtVcCompact: string, options: SdJwtVcReceiveOptions): Promise { - return await this.sdJwtVcService.storeCredential(this.agentContext, sdJwtVcCompact, options) - } - - /** - * - * Create a compact presentation of the sd-jwt. - * This presentation can be send in- or out-of-band to the verifier. - * - * Within the `options` field, you can supply the indicies of the disclosures you would like to share with the verifier. - * Also, whether to include the holder key binding. - * - */ - public async present(sdJwtVcRecord: SdJwtVcRecord, options: SdJwtVcPresentOptions): Promise { - return await this.sdJwtVcService.present(this.agentContext, sdJwtVcRecord, options) - } - - /** - * - * Verify an incoming sd-jwt. It will check whether everything is valid, but also returns parts of the validation. - * - * For example, you might still want to continue with a flow if not all the claims are included, but the signature is valid. - * - */ - public async verify< - Header extends Record = Record, - Payload extends Record = Record - >( - sdJwtVcCompact: string, - options: SdJwtVcVerifyOptions - ): Promise<{ sdJwtVcRecord: SdJwtVcRecord; validation: SdJwtVcVerificationResult }> { - return await this.sdJwtVcService.verify(this.agentContext, sdJwtVcCompact, options) - } - - public async getById(id: string): Promise { - return await this.sdJwtVcService.getCredentialRecordById(this.agentContext, id) - } - - public async getAll(): Promise> { - return await this.sdJwtVcService.getAllCredentialRecords(this.agentContext) - } - - public async findAllByQuery(query: Query): Promise> { - return await this.sdJwtVcService.findCredentialRecordsByQuery(this.agentContext, query) - } - - public async remove(id: string) { - return await this.sdJwtVcService.removeCredentialRecord(this.agentContext, id) - } - - public async update(sdJwtVcRecord: SdJwtVcRecord) { - return await this.sdJwtVcService.updateCredentialRecord(this.agentContext, sdJwtVcRecord) - } -} diff --git a/packages/sd-jwt-vc/src/SdJwtVcOptions.ts b/packages/sd-jwt-vc/src/SdJwtVcOptions.ts deleted file mode 100644 index ba8d41949e..0000000000 --- a/packages/sd-jwt-vc/src/SdJwtVcOptions.ts +++ /dev/null @@ -1,44 +0,0 @@ -import type { HashName, JwaSignatureAlgorithm } from '@credo-ts/core' -import type { DisclosureFrame } from 'jwt-sd' - -export type SdJwtVcCreateOptions = Record> = { - holderDidUrl: string - issuerDidUrl: string - jsonWebAlgorithm?: JwaSignatureAlgorithm - disclosureFrame?: DisclosureFrame - hashingAlgorithm?: HashName -} - -export type SdJwtVcReceiveOptions = { - issuerDidUrl: string - holderDidUrl: string -} - -/** - * `includedDisclosureIndices` is not the best API, but it is the best alternative until something like `PEX` is supported - */ -export type SdJwtVcPresentOptions = { - jsonWebAlgorithm?: JwaSignatureAlgorithm - includedDisclosureIndices?: Array - - /** - * This information is received out-of-band from the verifier. - * The claims will be used to create a normal JWT, used for key binding. - */ - verifierMetadata: { - verifierDid: string - nonce: string - issuedAt: number - } -} - -/** - * `requiredClaimKeys` is not the best API, but it is the best alternative until something like `PEX` is supported - */ -export type SdJwtVcVerifyOptions = { - holderDidUrl: string - challenge: { - verifierDid: string - } - requiredClaimKeys?: Array -} diff --git a/packages/sd-jwt-vc/src/SdJwtVcService.ts b/packages/sd-jwt-vc/src/SdJwtVcService.ts deleted file mode 100644 index 30063fc5be..0000000000 --- a/packages/sd-jwt-vc/src/SdJwtVcService.ts +++ /dev/null @@ -1,341 +0,0 @@ -import type { - SdJwtVcCreateOptions, - SdJwtVcPresentOptions, - SdJwtVcReceiveOptions, - SdJwtVcVerifyOptions, -} from './SdJwtVcOptions' -import type { AgentContext, JwkJson, Query } from '@credo-ts/core' -import type { Signer, SdJwtVcVerificationResult, Verifier, HasherAndAlgorithm } from 'jwt-sd' - -import { - parseDid, - DidResolverService, - getKeyFromVerificationMethod, - getJwkFromJson, - Key, - getJwkFromKey, - Hasher, - inject, - injectable, - InjectionSymbols, - Logger, - TypedArrayEncoder, - Buffer, -} from '@credo-ts/core' -import { KeyBinding, SdJwtVc, HasherAlgorithm, Disclosure } from 'jwt-sd' - -import { SdJwtVcError } from './SdJwtVcError' -import { SdJwtVcRepository, SdJwtVcRecord } from './repository' - -export { SdJwtVcVerificationResult } - -/** - * @internal - */ -@injectable() -export class SdJwtVcService { - private logger: Logger - private sdJwtVcRepository: SdJwtVcRepository - - public constructor(sdJwtVcRepository: SdJwtVcRepository, @inject(InjectionSymbols.Logger) logger: Logger) { - this.sdJwtVcRepository = sdJwtVcRepository - this.logger = logger - } - - private async resolveDidUrl(agentContext: AgentContext, didUrl: string) { - const didResolver = agentContext.dependencyManager.resolve(DidResolverService) - const didDocument = await didResolver.resolveDidDocument(agentContext, didUrl) - - return { verificationMethod: didDocument.dereferenceKey(didUrl), didDocument } - } - - private get hasher(): HasherAndAlgorithm { - return { - algorithm: HasherAlgorithm.Sha256, - hasher: (input: string) => { - const serializedInput = TypedArrayEncoder.fromString(input) - return Hasher.hash(serializedInput, 'sha2-256') - }, - } - } - - /** - * @todo validate the JWT header (alg) - */ - private signer
= Record>( - agentContext: AgentContext, - key: Key - ): Signer
{ - return async (input: string) => agentContext.wallet.sign({ key, data: TypedArrayEncoder.fromString(input) }) - } - - /** - * @todo validate the JWT header (alg) - */ - private verifier
= Record>( - agentContext: AgentContext, - signerKey: Key - ): Verifier
{ - return async ({ message, signature, publicKeyJwk }) => { - let key = signerKey - - if (publicKeyJwk) { - if (!('kty' in publicKeyJwk)) { - throw new SdJwtVcError( - 'Key type (kty) claim could not be found in the JWK of the confirmation (cnf) claim. Only JWK is supported right now' - ) - } - - const jwk = getJwkFromJson(publicKeyJwk as JwkJson) - key = Key.fromPublicKey(jwk.publicKey, jwk.keyType) - } - - return await agentContext.wallet.verify({ - signature: Buffer.from(signature), - key: key, - data: TypedArrayEncoder.fromString(message), - }) - } - } - - public async create = Record>( - agentContext: AgentContext, - payload: Payload, - { - issuerDidUrl, - holderDidUrl, - disclosureFrame, - hashingAlgorithm = 'sha2-256', - jsonWebAlgorithm, - }: SdJwtVcCreateOptions - ): Promise<{ sdJwtVcRecord: SdJwtVcRecord; compact: string }> { - if (hashingAlgorithm !== 'sha2-256') { - throw new SdJwtVcError(`Unsupported hashing algorithm used: ${hashingAlgorithm}`) - } - - const parsedDid = parseDid(issuerDidUrl) - if (!parsedDid.fragment) { - throw new SdJwtVcError( - `issuer did url '${issuerDidUrl}' does not contain a '#'. Unable to derive key from did document` - ) - } - - const { verificationMethod: issuerVerificationMethod, didDocument: issuerDidDocument } = await this.resolveDidUrl( - agentContext, - issuerDidUrl - ) - const issuerKey = getKeyFromVerificationMethod(issuerVerificationMethod) - const alg = jsonWebAlgorithm ?? getJwkFromKey(issuerKey).supportedSignatureAlgorithms[0] - - const { verificationMethod: holderVerificationMethod } = await this.resolveDidUrl(agentContext, holderDidUrl) - const holderKey = getKeyFromVerificationMethod(holderVerificationMethod) - const holderKeyJwk = getJwkFromKey(holderKey).toJson() - - const header = { - alg: alg.toString(), - typ: 'vc+sd-jwt', - kid: parsedDid.fragment, - } - - const sdJwtVc = new SdJwtVc({}, { disclosureFrame }) - .withHasher(this.hasher) - .withSigner(this.signer(agentContext, issuerKey)) - .withSaltGenerator(agentContext.wallet.generateNonce) - .withHeader(header) - .withPayload({ ...payload }) - - // Add the `cnf` claim for the holder key binding - sdJwtVc.addPayloadClaim('cnf', { jwk: holderKeyJwk }) - - // Add the issuer DID as the `iss` claim - sdJwtVc.addPayloadClaim('iss', issuerDidDocument.id) - - // Add the issued at (iat) claim - sdJwtVc.addPayloadClaim('iat', Math.floor(new Date().getTime() / 1000)) - - const compact = await sdJwtVc.toCompact() - - if (!sdJwtVc.signature) { - throw new SdJwtVcError('Invalid sd-jwt-vc state. Signature should have been set when calling `toCompact`.') - } - - const sdJwtVcRecord = new SdJwtVcRecord({ - sdJwtVc: { - header: sdJwtVc.header, - payload: sdJwtVc.payload, - signature: sdJwtVc.signature, - disclosures: sdJwtVc.disclosures?.map((d) => d.decoded), - holderDidUrl, - }, - }) - - await this.sdJwtVcRepository.save(agentContext, sdJwtVcRecord) - - return { - sdJwtVcRecord, - compact, - } - } - - public async storeCredential< - Header extends Record = Record, - Payload extends Record = Record - >( - agentContext: AgentContext, - sdJwtVcCompact: string, - { issuerDidUrl, holderDidUrl }: SdJwtVcReceiveOptions - ): Promise { - const sdJwtVc = SdJwtVc.fromCompact(sdJwtVcCompact) - - if (!sdJwtVc.signature) { - throw new SdJwtVcError('A signature must be included for an sd-jwt-vc') - } - - const { verificationMethod: issuerVerificationMethod } = await this.resolveDidUrl(agentContext, issuerDidUrl) - const issuerKey = getKeyFromVerificationMethod(issuerVerificationMethod) - - const { isSignatureValid } = await sdJwtVc.verify(this.verifier(agentContext, issuerKey)) - - if (!isSignatureValid) { - throw new SdJwtVcError('sd-jwt-vc has an invalid signature from the issuer') - } - - const { verificationMethod: holderVerificiationMethod } = await this.resolveDidUrl(agentContext, holderDidUrl) - const holderKey = getKeyFromVerificationMethod(holderVerificiationMethod) - const holderKeyJwk = getJwkFromKey(holderKey).toJson() - - sdJwtVc.assertClaimInPayload('cnf', { jwk: holderKeyJwk }) - - const sdJwtVcRecord = new SdJwtVcRecord({ - sdJwtVc: { - header: sdJwtVc.header, - payload: sdJwtVc.payload, - signature: sdJwtVc.signature, - disclosures: sdJwtVc.disclosures?.map((d) => d.decoded), - holderDidUrl, - }, - }) - - await this.sdJwtVcRepository.save(agentContext, sdJwtVcRecord) - - return sdJwtVcRecord - } - - public async present( - agentContext: AgentContext, - sdJwtVcRecord: SdJwtVcRecord, - { includedDisclosureIndices, verifierMetadata, jsonWebAlgorithm }: SdJwtVcPresentOptions - ): Promise { - const { verificationMethod: holderVerificationMethod } = await this.resolveDidUrl( - agentContext, - sdJwtVcRecord.sdJwtVc.holderDidUrl - ) - const holderKey = getKeyFromVerificationMethod(holderVerificationMethod) - const alg = jsonWebAlgorithm ?? getJwkFromKey(holderKey).supportedSignatureAlgorithms[0] - - const header = { - alg: alg.toString(), - typ: 'kb+jwt', - } as const - - const payload = { - iat: verifierMetadata.issuedAt, - nonce: verifierMetadata.nonce, - aud: verifierMetadata.verifierDid, - } - - const keyBinding = new KeyBinding, Record>({ header, payload }).withSigner( - this.signer(agentContext, holderKey) - ) - - const sdJwtVc = new SdJwtVc({ - header: sdJwtVcRecord.sdJwtVc.header, - payload: sdJwtVcRecord.sdJwtVc.payload, - signature: sdJwtVcRecord.sdJwtVc.signature, - disclosures: sdJwtVcRecord.sdJwtVc.disclosures?.map(Disclosure.fromArray), - }).withKeyBinding(keyBinding) - - return await sdJwtVc.present(includedDisclosureIndices) - } - - public async verify< - Header extends Record = Record, - Payload extends Record = Record - >( - agentContext: AgentContext, - sdJwtVcCompact: string, - { challenge: { verifierDid }, requiredClaimKeys, holderDidUrl }: SdJwtVcVerifyOptions - ): Promise<{ sdJwtVcRecord: SdJwtVcRecord; validation: SdJwtVcVerificationResult }> { - const sdJwtVc = SdJwtVc.fromCompact(sdJwtVcCompact) - - if (!sdJwtVc.signature) { - throw new SdJwtVcError('A signature is required for verification of the sd-jwt-vc') - } - - if (!sdJwtVc.keyBinding || !sdJwtVc.keyBinding.payload) { - throw new SdJwtVcError('Keybinding is required for verification of the sd-jwt-vc') - } - - sdJwtVc.keyBinding.assertClaimInPayload('aud', verifierDid) - - const { verificationMethod: holderVerificationMethod } = await this.resolveDidUrl(agentContext, holderDidUrl) - const holderKey = getKeyFromVerificationMethod(holderVerificationMethod) - const holderKeyJwk = getJwkFromKey(holderKey).toJson() - - sdJwtVc.assertClaimInPayload('cnf', { jwk: holderKeyJwk }) - - sdJwtVc.assertClaimInHeader('kid') - sdJwtVc.assertClaimInPayload('iss') - - const issuerKid = sdJwtVc.getClaimInHeader('kid') - const issuerDid = sdJwtVc.getClaimInPayload('iss') - - // TODO: is there a more Credo way of doing this? - const issuerDidUrl = `${issuerDid}#${issuerKid}` - - const { verificationMethod: issuerVerificationMethod } = await this.resolveDidUrl(agentContext, issuerDidUrl) - const issuerKey = getKeyFromVerificationMethod(issuerVerificationMethod) - - const verificationResult = await sdJwtVc.verify(this.verifier(agentContext, issuerKey), requiredClaimKeys) - - const sdJwtVcRecord = new SdJwtVcRecord({ - sdJwtVc: { - signature: sdJwtVc.signature, - payload: sdJwtVc.payload, - disclosures: sdJwtVc.disclosures?.map((d) => d.decoded), - header: sdJwtVc.header, - holderDidUrl, - }, - }) - - await this.sdJwtVcRepository.save(agentContext, sdJwtVcRecord) - - return { - sdJwtVcRecord, - validation: verificationResult, - } - } - - public async getCredentialRecordById(agentContext: AgentContext, id: string): Promise { - return await this.sdJwtVcRepository.getById(agentContext, id) - } - - public async getAllCredentialRecords(agentContext: AgentContext): Promise> { - return await this.sdJwtVcRepository.getAll(agentContext) - } - - public async findCredentialRecordsByQuery( - agentContext: AgentContext, - query: Query - ): Promise> { - return await this.sdJwtVcRepository.findByQuery(agentContext, query) - } - - public async removeCredentialRecord(agentContext: AgentContext, id: string) { - await this.sdJwtVcRepository.deleteById(agentContext, id) - } - - public async updateCredentialRecord(agentContext: AgentContext, sdJwtVcRecord: SdJwtVcRecord) { - await this.sdJwtVcRepository.update(agentContext, sdJwtVcRecord) - } -} diff --git a/packages/sd-jwt-vc/src/__tests__/sdjwtvc.fixtures.ts b/packages/sd-jwt-vc/src/__tests__/sdjwtvc.fixtures.ts deleted file mode 100644 index e345cd8c3e..0000000000 --- a/packages/sd-jwt-vc/src/__tests__/sdjwtvc.fixtures.ts +++ /dev/null @@ -1,17 +0,0 @@ -export const simpleJwtVc = - 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6Ino2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyJ9.eyJjbGFpbSI6InNvbWUtY2xhaW0iLCJ0eXBlIjoiSWRlbnRpdHlDcmVkZW50aWFsIiwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyfQ.5oT776RbzRyRTINojXJExV1Ul6aP7sXKssU5bR0uWmQzVJ046y7gNhD5shJ3arYbtdakeVKBTicPM8LAzOvzAw' - -export const simpleJwtVcPresentation = - 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6Ino2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyJ9.eyJjbGFpbSI6InNvbWUtY2xhaW0iLCJ0eXBlIjoiSWRlbnRpdHlDcmVkZW50aWFsIiwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyfQ.5oT776RbzRyRTINojXJExV1Ul6aP7sXKssU5bR0uWmQzVJ046y7gNhD5shJ3arYbtdakeVKBTicPM8LAzOvzAw~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkifQ.VdZSnQJ5sklqMPnIzaOaGxP2qPiEPniTaUFHy4VMcW9h9pV1c17fcuTySJtmV2tcpKhei4ss04q_rFyN1EVRDg' - -export const sdJwtVcWithSingleDisclosure = - 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6Ino2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyJ9.eyJ0eXBlIjoiSWRlbnRpdHlDcmVkZW50aWFsIiwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyJ2Y3ZGVTREc0ZLVHFRMXZsNG5lbEpXWFRiXy0wZE5vQmtzNmlxTkZwdHlnIl19.G5jb2P0z-9H-AsEGBbJmGk9VUTPJJ_bkVE95oKDu4YmilmQuvCritpOoK5nt9n4Bg_3v23ywagHHOnGTBCtQCQ~WyJzYWx0IiwiY2xhaW0iLCJzb21lLWNsYWltIl0~' - -export const sdJwtVcWithSingleDisclosurePresentation = - 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6Ino2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyJ9.eyJ0eXBlIjoiSWRlbnRpdHlDcmVkZW50aWFsIiwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyJ2Y3ZGVTREc0ZLVHFRMXZsNG5lbEpXWFRiXy0wZE5vQmtzNmlxTkZwdHlnIl19.G5jb2P0z-9H-AsEGBbJmGk9VUTPJJ_bkVE95oKDu4YmilmQuvCritpOoK5nt9n4Bg_3v23ywagHHOnGTBCtQCQ~WyJzYWx0IiwiY2xhaW0iLCJzb21lLWNsYWltIl0~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkifQ.VdZSnQJ5sklqMPnIzaOaGxP2qPiEPniTaUFHy4VMcW9h9pV1c17fcuTySJtmV2tcpKhei4ss04q_rFyN1EVRDg' - -export const complexSdJwtVc = - 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6Ino2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyJ9.eyJ0eXBlIjoiSWRlbnRpdHlDcmVkZW50aWFsIiwiZmFtaWx5X25hbWUiOiJEb2UiLCJwaG9uZV9udW1iZXIiOiIrMS0yMDItNTU1LTAxMDEiLCJhZGRyZXNzIjp7InN0cmVldF9hZGRyZXNzIjoiMTIzIE1haW4gU3QiLCJsb2NhbGl0eSI6IkFueXRvd24iLCJfc2QiOlsiTkpubWN0MEJxQk1FMUpmQmxDNmpSUVZSdWV2cEVPTmlZdzdBN01IdUp5USIsIm9tNVp6dFpIQi1HZDAwTEcyMUNWX3hNNEZhRU5Tb2lhT1huVEFKTmN6QjQiXX0sImNuZiI6eyJqd2siOnsia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJvRU5Wc3hPVWlINTRYOHdKTGFWa2ljQ1JrMDB3QklRNHNSZ2JrNTROOE1vIn19LCJpc3MiOiJkaWQ6a2V5Ono2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyIsImlhdCI6MTY5ODE1MTUzMiwiX3NkX2FsZyI6InNoYS0yNTYiLCJfc2QiOlsiMUN1cjJrMkEyb0lCNUNzaFNJZl9BX0tnLWwyNnVfcUt1V1E3OVAwVmRhcyIsIlIxelRVdk9ZSGdjZXBqMGpIeXBHSHo5RUh0dFZLZnQweXN3YmM5RVRQYlUiLCJlRHFRcGRUWEpYYldoZi1Fc0k3enc1WDZPdlltRk4tVVpRUU1lc1h3S1B3IiwicGREazJfWEFLSG83Z09BZndGMWI3T2RDVVZUaXQya0pIYXhTRUNROXhmYyIsInBzYXVLVU5XRWkwOW51M0NsODl4S1hnbXBXRU5abDV1eTFOMW55bl9qTWsiLCJzTl9nZTBwSFhGNnFtc1luWDFBOVNkd0o4Y2g4YUVOa3hiT0RzVDc0WXdJIl19.LcCXQx4IEnA_JWK_fLD08xXL0RWO796UuiN8YL9CU4zy_MT-LTvWJa1WNoBBeoHLcKI6NlLbXHExGU7sbG1oDw~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8xOCIsdHJ1ZV0~WyJzYWx0IiwiYmlydGhkYXRlIiwiMTk0MC0wMS0wMSJd~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwicmVnaW9uIiwiQW55c3RhdGUiXQ~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~' - -export const complexSdJwtVcPresentation = - 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6Ino2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyJ9.eyJ0eXBlIjoiSWRlbnRpdHlDcmVkZW50aWFsIiwiZmFtaWx5X25hbWUiOiJEb2UiLCJwaG9uZV9udW1iZXIiOiIrMS0yMDItNTU1LTAxMDEiLCJhZGRyZXNzIjp7InN0cmVldF9hZGRyZXNzIjoiMTIzIE1haW4gU3QiLCJsb2NhbGl0eSI6IkFueXRvd24iLCJfc2QiOlsiTkpubWN0MEJxQk1FMUpmQmxDNmpSUVZSdWV2cEVPTmlZdzdBN01IdUp5USIsIm9tNVp6dFpIQi1HZDAwTEcyMUNWX3hNNEZhRU5Tb2lhT1huVEFKTmN6QjQiXX0sImNuZiI6eyJqd2siOnsia3R5IjoiT0tQIiwiY3J2IjoiRWQyNTUxOSIsIngiOiJvRU5Wc3hPVWlINTRYOHdKTGFWa2ljQ1JrMDB3QklRNHNSZ2JrNTROOE1vIn19LCJpc3MiOiJkaWQ6a2V5Ono2TWt0cXRYTkc4Q0RVWTlQcnJ0b1N0RnplQ25ocE1tZ3hZTDFnaWtjVzNCenZOVyIsImlhdCI6MTY5ODE1MTUzMiwiX3NkX2FsZyI6InNoYS0yNTYiLCJfc2QiOlsiMUN1cjJrMkEyb0lCNUNzaFNJZl9BX0tnLWwyNnVfcUt1V1E3OVAwVmRhcyIsIlIxelRVdk9ZSGdjZXBqMGpIeXBHSHo5RUh0dFZLZnQweXN3YmM5RVRQYlUiLCJlRHFRcGRUWEpYYldoZi1Fc0k3enc1WDZPdlltRk4tVVpRUU1lc1h3S1B3IiwicGREazJfWEFLSG83Z09BZndGMWI3T2RDVVZUaXQya0pIYXhTRUNROXhmYyIsInBzYXVLVU5XRWkwOW51M0NsODl4S1hnbXBXRU5abDV1eTFOMW55bl9qTWsiLCJzTl9nZTBwSFhGNnFtc1luWDFBOVNkd0o4Y2g4YUVOa3hiT0RzVDc0WXdJIl19.LcCXQx4IEnA_JWK_fLD08xXL0RWO796UuiN8YL9CU4zy_MT-LTvWJa1WNoBBeoHLcKI6NlLbXHExGU7sbG1oDw~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkifQ.VdZSnQJ5sklqMPnIzaOaGxP2qPiEPniTaUFHy4VMcW9h9pV1c17fcuTySJtmV2tcpKhei4ss04q_rFyN1EVRDg' diff --git a/packages/sd-jwt-vc/src/repository/SdJwtVcRecord.ts b/packages/sd-jwt-vc/src/repository/SdJwtVcRecord.ts deleted file mode 100644 index b00f5e8860..0000000000 --- a/packages/sd-jwt-vc/src/repository/SdJwtVcRecord.ts +++ /dev/null @@ -1,97 +0,0 @@ -import type { TagsBase, Constructable } from '@credo-ts/core' -import type { DisclosureItem, HasherAndAlgorithm } from 'jwt-sd' - -import { JsonTransformer, Hasher, TypedArrayEncoder, BaseRecord, utils } from '@credo-ts/core' -import { Disclosure, HasherAlgorithm, SdJwtVc } from 'jwt-sd' - -export type SdJwtVcRecordTags = TagsBase & { - disclosureKeys?: Array -} - -export type SdJwt< - Header extends Record = Record, - Payload extends Record = Record -> = { - disclosures?: Array - header: Header - payload: Payload - signature: Uint8Array - - holderDidUrl: string -} - -export type SdJwtVcRecordStorageProps< - Header extends Record = Record, - Payload extends Record = Record -> = { - id?: string - createdAt?: Date - tags?: SdJwtVcRecordTags - sdJwtVc: SdJwt -} - -export class SdJwtVcRecord< - Header extends Record = Record, - Payload extends Record = Record -> extends BaseRecord { - public static readonly type = 'SdJwtVcRecord' - public readonly type = SdJwtVcRecord.type - - public sdJwtVc!: SdJwt - - public constructor(props: SdJwtVcRecordStorageProps) { - super() - - if (props) { - this.id = props.id ?? utils.uuid() - this.createdAt = props.createdAt ?? new Date() - this.sdJwtVc = props.sdJwtVc - this._tags = props.tags ?? {} - } - } - - private get hasher(): HasherAndAlgorithm { - return { - algorithm: HasherAlgorithm.Sha256, - hasher: (input: string) => { - const serializedInput = TypedArrayEncoder.fromString(input) - return Hasher.hash(serializedInput, 'sha2-256') - }, - } - } - - /** - * This function gets the claims from the payload and combines them with the claims in the disclosures. - * - * This can be used to display all claims included in the `sd-jwt-vc` to the holder or verifier. - */ - public async getPrettyClaims | Payload = Payload>(): Promise { - const sdJwtVc = new SdJwtVc({ - header: this.sdJwtVc.header, - payload: this.sdJwtVc.payload, - disclosures: this.sdJwtVc.disclosures?.map(Disclosure.fromArray), - }).withHasher(this.hasher) - - // Assert that we only support `sha-256` as a hashing algorithm - if ('_sd_alg' in this.sdJwtVc.payload) { - sdJwtVc.assertClaimInPayload('_sd_alg', HasherAlgorithm.Sha256.toString()) - } - - return await sdJwtVc.getPrettyClaims() - } - - public getTags() { - const disclosureKeys = this.sdJwtVc.disclosures - ?.filter((d): d is [string, string, unknown] => d.length === 3) - .map((d) => d[1]) - - return { - ...this._tags, - disclosureKeys, - } - } - - public clone(): this { - return JsonTransformer.fromJSON(JsonTransformer.toJSON(this), this.constructor as Constructable) - } -} diff --git a/packages/sd-jwt-vc/src/repository/__tests__/SdJwtVcRecord.test.ts b/packages/sd-jwt-vc/src/repository/__tests__/SdJwtVcRecord.test.ts deleted file mode 100644 index 7ecad9e5f6..0000000000 --- a/packages/sd-jwt-vc/src/repository/__tests__/SdJwtVcRecord.test.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { JsonTransformer } from '@credo-ts/core' -import { SdJwtVc, SignatureAndEncryptionAlgorithm } from 'jwt-sd' - -import { SdJwtVcRecord } from '../SdJwtVcRecord' - -describe('SdJwtVcRecord', () => { - const holderDidUrl = 'did:key:zUC74VEqqhEHQcgv4zagSPkqFJxuNWuoBPKjJuHETEUeHLoSqWt92viSsmaWjy82y' - - test('sets the values passed in the constructor on the record', () => { - const createdAt = new Date() - const sdJwtVcRecord = new SdJwtVcRecord({ - id: 'sdjwt-id', - createdAt, - tags: { - some: 'tag', - }, - sdJwtVc: { - header: { alg: SignatureAndEncryptionAlgorithm.EdDSA }, - payload: { iss: 'did:key:123' }, - signature: new Uint8Array(32).fill(42), - holderDidUrl, - }, - }) - - expect(sdJwtVcRecord.type).toBe('SdJwtVcRecord') - expect(sdJwtVcRecord.id).toBe('sdjwt-id') - expect(sdJwtVcRecord.createdAt).toBe(createdAt) - expect(sdJwtVcRecord.getTags()).toEqual({ - some: 'tag', - }) - expect(sdJwtVcRecord.sdJwtVc).toEqual({ - header: { alg: SignatureAndEncryptionAlgorithm.EdDSA }, - payload: { iss: 'did:key:123' }, - signature: new Uint8Array(32).fill(42), - holderDidUrl, - }) - }) - - test('serializes and deserializes', () => { - const createdAt = new Date('2022-02-02') - const sdJwtVcRecord = new SdJwtVcRecord({ - id: 'sdjwt-id', - createdAt, - tags: { - some: 'tag', - }, - sdJwtVc: { - header: { alg: SignatureAndEncryptionAlgorithm.EdDSA }, - payload: { iss: 'did:key:123' }, - signature: new Uint8Array(32).fill(42), - holderDidUrl, - }, - }) - - const json = sdJwtVcRecord.toJSON() - expect(json).toMatchObject({ - id: 'sdjwt-id', - createdAt: '2022-02-02T00:00:00.000Z', - metadata: {}, - _tags: { - some: 'tag', - }, - sdJwtVc: { - header: { alg: SignatureAndEncryptionAlgorithm.EdDSA }, - payload: { iss: 'did:key:123' }, - signature: new Uint8Array(32).fill(42), - }, - }) - - const instance = JsonTransformer.fromJSON(json, SdJwtVcRecord) - - expect(instance.type).toBe('SdJwtVcRecord') - expect(instance.id).toBe('sdjwt-id') - expect(instance.createdAt.getTime()).toBe(createdAt.getTime()) - expect(instance.getTags()).toEqual({ - some: 'tag', - }) - expect(instance.sdJwtVc).toMatchObject({ - header: { alg: SignatureAndEncryptionAlgorithm.EdDSA }, - payload: { iss: 'did:key:123' }, - signature: new Uint8Array(32).fill(42), - }) - }) - - test('Get the pretty claims', async () => { - const compactSdJwtVc = - 'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCJ9.eyJ0eXBlIjoiSWRlbnRpdHlDcmVkZW50aWFsIiwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6IlVXM3ZWRWp3UmYwSWt0Sm9jdktSbUdIekhmV0FMdF9YMkswd3ZsdVpJU3MifX0sImlzcyI6ImRpZDprZXk6MTIzIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyJ2Y3ZGVTREc0ZLVHFRMXZsNG5lbEpXWFRiXy0wZE5vQmtzNmlxTkZwdHlnIl19.IW6PaMTtxMNvqwrRac5nh7L9_ie4r-PUDL6Gqoey2O3axTm6RBrUv0ETLbdgALK6tU_HoIDuNE66DVrISQXaCw~WyJzYWx0IiwiY2xhaW0iLCJzb21lLWNsYWltIl0~' - - const sdJwtVc = SdJwtVc.fromCompact(compactSdJwtVc) - - const sdJwtVcRecord = new SdJwtVcRecord({ - tags: { - some: 'tag', - }, - sdJwtVc: { - header: sdJwtVc.header, - payload: sdJwtVc.payload, - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - signature: sdJwtVc.signature!, - disclosures: sdJwtVc.disclosures?.map((d) => d.decoded), - holderDidUrl, - }, - }) - - const prettyClaims = await sdJwtVcRecord.getPrettyClaims() - - expect(prettyClaims).toEqual({ - type: 'IdentityCredential', - cnf: { - jwk: { - kty: 'OKP', - crv: 'Ed25519', - x: 'UW3vVEjwRf0IktJocvKRmGHzHfWALt_X2K0wvluZISs', - }, - }, - iss: 'did:key:123', - iat: 1698151532, - claim: 'some-claim', - }) - }) -}) diff --git a/packages/sd-jwt-vc/tests/sdJwtVc.e2e.test.ts b/packages/sd-jwt-vc/tests/sdJwtVc.e2e.test.ts deleted file mode 100644 index 89aae8ad85..0000000000 --- a/packages/sd-jwt-vc/tests/sdJwtVc.e2e.test.ts +++ /dev/null @@ -1,134 +0,0 @@ -import type { Key } from '@credo-ts/core' - -import { Agent, DidKey, DidsModule, KeyDidRegistrar, KeyDidResolver, KeyType, TypedArrayEncoder } from '@credo-ts/core' - -import { getInMemoryAgentOptions } from '../../core/tests' -import { SdJwtVcModule } from '../src' - -const getAgent = (label: string) => - new Agent( - getInMemoryAgentOptions( - label, - {}, - { - sdJwt: new SdJwtVcModule(), - dids: new DidsModule({ - resolvers: [new KeyDidResolver()], - registrars: [new KeyDidRegistrar()], - }), - } - ) - ) - -describe('sd-jwt-vc end to end test', () => { - const issuer = getAgent('sdjwtvcissueragent') - let issuerKey: Key - let issuerDidUrl: string - - const holder = getAgent('sdjwtvcholderagent') - let holderKey: Key - let holderDidUrl: string - - const verifier = getAgent('sdjwtvcverifieragent') - const verifierDid = 'did:key:zUC74VEqqhEHQcgv4zagSPkqFJxuNWuoBPKjJuHETEUeHLoSqWt92viSsmaWjy82y' - - beforeAll(async () => { - await issuer.initialize() - issuerKey = await issuer.context.wallet.createKey({ - keyType: KeyType.Ed25519, - seed: TypedArrayEncoder.fromString('00000000000000000000000000000000'), - }) - - const issuerDidKey = new DidKey(issuerKey) - const issuerDidDocument = issuerDidKey.didDocument - issuerDidUrl = (issuerDidDocument.verificationMethod ?? [])[0].id - await issuer.dids.import({ didDocument: issuerDidDocument, did: issuerDidDocument.id }) - - await holder.initialize() - holderKey = await holder.context.wallet.createKey({ - keyType: KeyType.Ed25519, - seed: TypedArrayEncoder.fromString('00000000000000000000000000000001'), - }) - - const holderDidKey = new DidKey(holderKey) - const holderDidDocument = holderDidKey.didDocument - holderDidUrl = (holderDidDocument.verificationMethod ?? [])[0].id - await holder.dids.import({ didDocument: holderDidDocument, did: holderDidDocument.id }) - - await verifier.initialize() - }) - - test('end to end flow', async () => { - const credential = { - type: 'IdentityCredential', - given_name: 'John', - family_name: 'Doe', - email: 'johndoe@example.com', - phone_number: '+1-202-555-0101', - address: { - street_address: '123 Main St', - locality: 'Anytown', - region: 'Anystate', - country: 'US', - }, - birthdate: '1940-01-01', - is_over_18: true, - is_over_21: true, - is_over_65: true, - } - - const { compact } = await issuer.modules.sdJwt.create(credential, { - holderDidUrl, - issuerDidUrl, - disclosureFrame: { - is_over_65: true, - is_over_21: true, - is_over_18: true, - birthdate: true, - email: true, - address: { country: true, region: true, locality: true, __decoyCount: 2, street_address: true }, - __decoyCount: 2, - given_name: true, - family_name: true, - phone_number: true, - }, - }) - - const sdJwtVcRecord = await holder.modules.sdJwt.storeCredential(compact, { issuerDidUrl, holderDidUrl }) - - // Metadata created by the verifier and send out of band by the verifier to the holder - const verifierMetadata = { - verifierDid, - issuedAt: new Date().getTime() / 1000, - nonce: await verifier.wallet.generateNonce(), - } - - const presentation = await holder.modules.sdJwt.present(sdJwtVcRecord, { - verifierMetadata, - includedDisclosureIndices: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], - }) - - const { - validation: { isValid }, - } = await verifier.modules.sdJwt.verify(presentation, { - holderDidUrl, - challenge: { verifierDid }, - requiredClaimKeys: [ - 'is_over_65', - 'is_over_21', - 'is_over_18', - 'birthdate', - 'email', - 'country', - 'region', - 'locality', - 'street_address', - 'given_name', - 'family_name', - 'phone_number', - ], - }) - - expect(isValid).toBeTruthy() - }) -}) diff --git a/packages/sd-jwt-vc/tests/setup.ts b/packages/sd-jwt-vc/tests/setup.ts deleted file mode 100644 index 78143033f2..0000000000 --- a/packages/sd-jwt-vc/tests/setup.ts +++ /dev/null @@ -1,3 +0,0 @@ -import 'reflect-metadata' - -jest.setTimeout(120000) diff --git a/packages/sd-jwt-vc/tsconfig.build.json b/packages/sd-jwt-vc/tsconfig.build.json deleted file mode 100644 index 2b75d0adab..0000000000 --- a/packages/sd-jwt-vc/tsconfig.build.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../tsconfig.build.json", - "compilerOptions": { - "outDir": "./build" - }, - "include": ["src/**/*"] -} diff --git a/packages/sd-jwt-vc/tsconfig.json b/packages/sd-jwt-vc/tsconfig.json deleted file mode 100644 index 46efe6f721..0000000000 --- a/packages/sd-jwt-vc/tsconfig.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "types": ["jest"] - } -} diff --git a/packages/tenants/README.md b/packages/tenants/README.md index 64a0095e01..813be5bacb 100644 --- a/packages/tenants/README.md +++ b/packages/tenants/README.md @@ -11,7 +11,7 @@ License { - private agentContext: AgentContext + public readonly rootAgentContext: AgentContext private tenantRecordService: TenantRecordService private agentContextProvider: AgentContextProvider private logger: Logger public constructor( tenantRecordService: TenantRecordService, - agentContext: AgentContext, + rootAgentContext: AgentContext, @inject(InjectionSymbols.AgentContextProvider) agentContextProvider: AgentContextProvider, @inject(InjectionSymbols.Logger) logger: Logger ) { this.tenantRecordService = tenantRecordService - this.agentContext = agentContext + this.rootAgentContext = rootAgentContext this.agentContextProvider = agentContextProvider this.logger = logger } @@ -58,7 +59,7 @@ export class TenantsApi { public async createTenant(options: CreateTenantOptions) { this.logger.debug(`Creating tenant with label ${options.config.label}`) - const tenantRecord = await this.tenantRecordService.createTenant(this.agentContext, options.config) + const tenantRecord = await this.tenantRecordService.createTenant(this.rootAgentContext, options.config) // This initializes the tenant agent, creates the wallet etc... const tenantAgent = await this.getTenantAgent({ tenantId: tenantRecord.id }) @@ -71,7 +72,7 @@ export class TenantsApi { public async getTenantById(tenantId: string) { this.logger.debug(`Getting tenant by id '${tenantId}'`) - return this.tenantRecordService.getTenantById(this.agentContext, tenantId) + return this.tenantRecordService.getTenantById(this.rootAgentContext, tenantId) } public async deleteTenantById(tenantId: string) { @@ -84,11 +85,19 @@ export class TenantsApi { this.logger.trace(`Shutting down agent for tenant '${tenantId}'`) await tenantAgent.endSession() - return this.tenantRecordService.deleteTenantById(this.agentContext, tenantId) + return this.tenantRecordService.deleteTenantById(this.rootAgentContext, tenantId) + } + + public async updateTenant(tenant: TenantRecord) { + await this.tenantRecordService.updateTenant(this.rootAgentContext, tenant) + } + + public async findTenantsByQuery(query: Query) { + return this.tenantRecordService.findTenantsByQuery(this.rootAgentContext, query) } public async getAllTenants() { this.logger.debug('Getting all tenants') - return this.tenantRecordService.getAllTenants(this.agentContext) + return this.tenantRecordService.getAllTenants(this.rootAgentContext) } } diff --git a/packages/tenants/src/services/TenantRecordService.ts b/packages/tenants/src/services/TenantRecordService.ts index 9b97f6f242..a9fc6d09dd 100644 --- a/packages/tenants/src/services/TenantRecordService.ts +++ b/packages/tenants/src/services/TenantRecordService.ts @@ -1,5 +1,5 @@ import type { TenantConfig } from '../models/TenantConfig' -import type { AgentContext, Key } from '@credo-ts/core' +import type { AgentContext, Key, Query } from '@credo-ts/core' import { injectable, utils, KeyDerivationMethod } from '@credo-ts/core' @@ -64,6 +64,14 @@ export class TenantRecordService { await this.tenantRepository.delete(agentContext, tenantRecord) } + public async updateTenant(agentContext: AgentContext, tenantRecord: TenantRecord) { + return this.tenantRepository.update(agentContext, tenantRecord) + } + + public async findTenantsByQuery(agentContext: AgentContext, query: Query) { + return this.tenantRepository.findByQuery(agentContext, query) + } + public async findTenantRoutingRecordByRecipientKey( agentContext: AgentContext, recipientKey: Key diff --git a/samples/extension-module/dummy/DummyModule.ts b/samples/extension-module/dummy/DummyModule.ts index 9d97e843a7..f7669486c9 100644 --- a/samples/extension-module/dummy/DummyModule.ts +++ b/samples/extension-module/dummy/DummyModule.ts @@ -10,6 +10,7 @@ import { DummyService } from './services' export class DummyModule implements Module { public readonly config: DummyModuleConfig + public readonly api = DummyApi public constructor(config?: DummyModuleConfigOptions) { @@ -17,9 +18,6 @@ export class DummyModule implements Module { } public register(dependencyManager: DependencyManager, featureRegistry: FeatureRegistry) { - // Api - dependencyManager.registerContextScoped(DummyApi) - // Config dependencyManager.registerInstance(DummyModuleConfig, this.config) diff --git a/samples/extension-module/package.json b/samples/extension-module/package.json index f0ea8a414e..8339b533ca 100644 --- a/samples/extension-module/package.json +++ b/samples/extension-module/package.json @@ -22,7 +22,7 @@ "@credo-ts/core": "*", "@credo-ts/node": "*", "@credo-ts/askar": "*", - "class-validator": "0.14.0", + "class-validator": "0.14.1", "rxjs": "^7.2.0", "@hyperledger/aries-askar-nodejs": "^0.2.0-dev.6" } diff --git a/tests/InMemoryWallet.ts b/tests/InMemoryWallet.ts index 1b087ce524..3d32ff9ae1 100644 --- a/tests/InMemoryWallet.ts +++ b/tests/InMemoryWallet.ts @@ -63,7 +63,7 @@ export class InMemoryWallet implements Wallet { return [KeyType.Ed25519, KeyType.P256] } - private get inMemoryKeys(): InMemoryKeys { + private getInMemoryKeys(): InMemoryKeys { if (!this.activeWalletId || !this.isInitialized) { throw new WalletError('No active wallet') } @@ -170,7 +170,7 @@ export class InMemoryWallet implements Wallet { const keyPublicBytes = key.publicBytes // Store key - this.inMemoryKeys[TypedArrayEncoder.toBase58(keyPublicBytes)] = { + this.getInMemoryKeys()[TypedArrayEncoder.toBase58(keyPublicBytes)] = { publicKeyBytes: keyPublicBytes, secretKeyBytes: key.secretBytes, keyType, @@ -200,7 +200,7 @@ export class InMemoryWallet implements Wallet { * @returns A signature for the data */ public async sign({ data, key }: WalletSignOptions): Promise { - const inMemoryKey = this.inMemoryKeys[key.publicKeyBase58] + const inMemoryKey = this.getInMemoryKeys()[key.publicKeyBase58] if (!inMemoryKey) { throw new WalletError(`Key not found in wallet`) } @@ -211,7 +211,7 @@ export class InMemoryWallet implements Wallet { let askarKey: AskarKey | undefined try { - const inMemoryKey = this.inMemoryKeys[key.publicKeyBase58] + const inMemoryKey = this.getInMemoryKeys()[key.publicKeyBase58] askarKey = AskarKey.fromSecretBytes({ algorithm: keyAlgFromString(inMemoryKey.keyType), secretKey: inMemoryKey.secretKeyBytes, @@ -267,7 +267,7 @@ export class InMemoryWallet implements Wallet { recipientKeys: string[], senderVerkey?: string // in base58 ): Promise { - const senderKey = senderVerkey ? this.inMemoryKeys[senderVerkey] : undefined + const senderKey = senderVerkey ? this.getInMemoryKeys()[senderVerkey] : undefined if (senderVerkey && !senderKey) { throw new WalletError(`Sender key not found`) @@ -300,7 +300,7 @@ export class InMemoryWallet implements Wallet { const recipientKids: string[] = protectedJson.recipients.map((r: any) => r.header.kid) for (const recipientKid of recipientKids) { - const recipientKey = this.inMemoryKeys[recipientKid] + const recipientKey = this.getInMemoryKeys()[recipientKid] const recipientAskarKey = recipientKey ? AskarKey.fromSecretBytes({ algorithm: keyAlgFromString(recipientKey.keyType), diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json index e2cd714c3a..67c6233f11 100644 --- a/tsconfig.eslint.json +++ b/tsconfig.eslint.json @@ -16,6 +16,7 @@ "tests", "samples", "demo", + "demo-openid", "scripts" ], "exclude": ["node_modules", "build"] diff --git a/tsconfig.test.json b/tsconfig.test.json index a95d1e400e..64130837af 100644 --- a/tsconfig.test.json +++ b/tsconfig.test.json @@ -4,12 +4,15 @@ "require": ["tsconfig-paths/register"] }, "compilerOptions": { + // Needed because of type-issued in sphereon siop-oid4vp lib + // https://github.com/Sphereon-Opensource/SIOP-OID4VP/pull/71#issuecomment-1913552869 + "skipLibCheck": true, "baseUrl": ".", "paths": { "@credo-ts/*": ["packages/*/src"] }, "types": ["jest", "node"] }, - "include": ["tests", "samples", "demo", "packages/core/types/jest.d.ts"], + "include": ["tests", "samples", "demo", "demo-openid", "packages/core/types/jest.d.ts"], "exclude": ["node_modules", "build", "**/build/**"] } diff --git a/yarn.lock b/yarn.lock index e3105bcf81..97be392de7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,6 +24,11 @@ node-addon-api "^3.0.0" node-gyp-build "^4.2.1" +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@ampproject/remapping@^2.2.0": version "2.2.1" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" @@ -44,22 +49,7 @@ resolved "https://registry.yarnpkg.com/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz#0dd3849fb8d97f062a39db0e5cadc9ffaf861fec" integrity sha512-3rkP4LnnlWawl0LZptJOdXNrT/fHp2eQMadoasa6afspXdpGrtPZuAQc2PD0cpgyuoXtUWyC3tv7xfntjGS5Dw== -"@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" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/code-frame@^7.22.13": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== - dependencies: - "@babel/highlight" "^7.22.13" - chalk "^2.4.2" - -"@babel/code-frame@^7.23.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== @@ -67,38 +57,12 @@ "@babel/highlight" "^7.23.4" chalk "^2.4.2" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5", "@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" - integrity sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g== - -"@babel/compat-data@^7.23.5": +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== -"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.20.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.4.tgz#c6dc73242507b8e2a27fd13a9c1814f9fa34a659" - integrity sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.4" - "@babel/helper-compilation-targets" "^7.21.4" - "@babel/helper-module-transforms" "^7.21.2" - "@babel/helpers" "^7.21.0" - "@babel/parser" "^7.21.4" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.4" - "@babel/types" "^7.21.4" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" - -"@babel/core@^7.14.6": +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.14.6", "@babel/core@^7.20.0": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.9.tgz#b028820718000f267870822fec434820e9b1e4d1" integrity sha512-5q0175NOjddqpvvzU+kDiSOAk4PfdO6FvwCWoQ6RO7rTzEe8vlo+4HVfcnAREhD4npMs0e9uZypjTwzZPCf/cw== @@ -119,27 +83,7 @@ json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.20.0", "@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" - integrity sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA== - dependencies: - "@babel/types" "^7.21.4" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/generator@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" - integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== - dependencies: - "@babel/types" "^7.23.0" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/generator@^7.23.6": +"@babel/generator@^7.20.0", "@babel/generator@^7.23.6", "@babel/generator@^7.7.2": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.6.tgz#9e1fca4811c77a10580d17d26b57b036133f3c2e" integrity sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw== @@ -149,25 +93,14 @@ "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" - integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9", "@babel/helper-compilation-targets@^7.20.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" - integrity sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg== +"@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== dependencies: - "@babel/compat-data" "^7.21.4" - "@babel/helper-validator-option" "^7.21.0" - browserslist "^4.21.3" - lru-cache "^5.1.1" - semver "^6.3.0" + "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.23.6": +"@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.23.6": version "7.23.6" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz#4d79069b16cbcf1461289eccfbbd81501ae39991" integrity sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ== @@ -178,59 +111,47 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.4.tgz#3a017163dc3c2ba7deb9a7950849a9586ea24c18" - integrity sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.23.6": + version "7.23.10" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.10.tgz#25d55fafbaea31fd0e723820bb6cc3df72edf7ea" + integrity sha512-2XpP2XhkXzgxecPNEEK8Vz8Asj9aRxt08oKOqtiZoqV2UGZ5T+EkyP9sXQ9nwMxBIG34a7jmasVqoMop7VdPUw== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-member-expression-to-functions" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.4.tgz#40411a8ab134258ad2cf3a3d987ec6aa0723cee5" - integrity sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA== +"@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.22.5" regexpu-core "^5.3.1" + semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.3.tgz#8612e55be5d51f0cd1f36b4a5a83924e89884b7a" - integrity sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww== +"@babel/helper-define-polyfill-provider@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.5.0.tgz#465805b7361f461e86c680f1de21eaf88c25901b" + integrity sha512-NovQquuQLAQ5HuyjCz7WQP9MjRj7dx++yspwiyUiGl9ZyadHRSql1HZh5ogRd8W8w6YM6EQ/NTB8rgjLt5W65Q== dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" - semver "^6.1.2" - -"@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" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== -"@babel/helper-environment-visitor@^7.22.20": +"@babel/helper-environment-visitor@^7.18.9", "@babel/helper-environment-visitor@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@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" - integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== - dependencies: - "@babel/template" "^7.20.7" - "@babel/types" "^7.21.0" - -"@babel/helper-function-name@^7.23.0": +"@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== @@ -245,19 +166,12 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-member-expression-to-functions@^7.20.7", "@babel/helper-member-expression-to-functions@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz#319c6a940431a133897148515877d2f3269c3ba5" - integrity sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q== - dependencies: - "@babel/types" "^7.21.0" - -"@babel/helper-module-imports@^7.18.6", "@babel/helper-module-imports@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af" - integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== +"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== dependencies: - "@babel/types" "^7.21.4" + "@babel/types" "^7.23.0" "@babel/helper-module-imports@^7.22.15": version "7.22.15" @@ -266,20 +180,6 @@ dependencies: "@babel/types" "^7.22.15" -"@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" - integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.2" - "@babel/types" "^7.21.2" - "@babel/helper-module-transforms@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" @@ -291,51 +191,35 @@ "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.20" -"@babel/helper-optimise-call-expression@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" - integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== +"@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== dependencies: - "@babel/types" "^7.18.6" - -"@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.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.8.0": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629" - integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ== + "@babel/types" "^7.22.5" -"@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.3": +"@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.18.9", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== -"@babel/helper-remap-async-to-generator@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" - integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-wrap-function" "^7.18.9" - "@babel/types" "^7.18.9" - -"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.20.7.tgz#243ecd2724d2071532b2c8ad2f0f9f083bcae331" - integrity sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A== +"@babel/helper-remap-async-to-generator@^7.18.9", "@babel/helper-remap-async-to-generator@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-member-expression-to-functions" "^7.20.7" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" - "@babel/types" "^7.20.7" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" -"@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" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== +"@babel/helper-replace-supers@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== dependencies: - "@babel/types" "^7.20.2" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" "@babel/helper-simple-access@^7.22.5": version "7.22.5" @@ -344,19 +228,12 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-skip-transparent-expression-wrappers@^7.20.0": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz#fbe4c52f60518cab8140d77101f0e63a8a230684" - integrity sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg== - dependencies: - "@babel/types" "^7.20.0" - -"@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" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== +"@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== dependencies: - "@babel/types" "^7.18.6" + "@babel/types" "^7.22.5" "@babel/helper-split-export-declaration@^7.22.6": version "7.22.6" @@ -365,59 +242,29 @@ dependencies: "@babel/types" "^7.22.5" -"@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" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - "@babel/helper-string-parser@^7.23.4": version "7.23.4" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== -"@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" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== -"@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" - integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== - -"@babel/helper-validator-option@^7.23.5": +"@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": version "7.23.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== -"@babel/helper-wrap-function@^7.18.9": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.20.5.tgz#75e2d84d499a0ab3b31c33bcfe59d6b8a45f62e3" - integrity sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q== - dependencies: - "@babel/helper-function-name" "^7.19.0" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.20.5" - "@babel/types" "^7.20.5" - -"@babel/helpers@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" - integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== +"@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.0" - "@babel/types" "^7.21.0" + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" "@babel/helpers@^7.23.9": version "7.23.9" @@ -428,24 +275,6 @@ "@babel/traverse" "^7.23.9" "@babel/types" "^7.23.9" -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - "@babel/highlight@^7.23.4": version "7.23.4" resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" @@ -455,17 +284,7 @@ chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.0", "@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" - integrity sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw== - -"@babel/parser@^7.22.15", "@babel/parser@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" - integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== - -"@babel/parser@^7.23.9": +"@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.9.tgz#7b903b6149b0f8fa7ad564af646c4c38a77fc44b" integrity sha512-9tcKgqKbs3xGJ+NtKF2ndOBBLVwPjl1SHxPQkd36r3Dlirw3xWUeGaTbqr7uGZcTaxkVNwc+03SVP7aCdWrTlA== @@ -489,12 +308,12 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-export-default-from@^7.0.0": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.18.10.tgz#091f4794dbce4027c03cf4ebc64d3fb96b75c206" - integrity sha512-5H2N3R2aQFxkV4PIBUR/i7PUSwgTZjouJKzI8eKswfIjT0PhvzkPn0t0wIS5zn6maQuvtT0t1oHtMUz61LOuow== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.23.3.tgz#6f511a676c540ccc8d17a8553dbba9230b0ddac0" + integrity sha512-Q23MpLZfSGZL1kU7fWqV262q65svLSCIP5kZ/JCW/rKTCm/FrLjpvEd2kfUYMVeHh4QhV/xzyoRAHWrAZJrE3Q== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" - "@babel/plugin-syntax-export-default-from" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-default-from" "^7.23.3" "@babel/plugin-proposal-export-namespace-from@^7.14.5": version "7.18.9" @@ -568,12 +387,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.18.6.tgz#8df076711a4818c4ce4f23e61d622b0ba2ff84bc" - integrity sha512-Kr//z3ujSVNx6E9z9ih5xXXMqK07VVTuqPmqGe6Mss/zW5XPeLZeSDZoP9ab/hT4wPKqAgjl2PnhPrcpk8Seew== +"@babel/plugin-syntax-export-default-from@^7.0.0", "@babel/plugin-syntax-export-default-from@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.23.3.tgz#7e6d4bf595d5724230200fb2b7401d4734b15335" + integrity sha512-KeENO5ck1IeZ/l2lFZNy+mpobV3D2Zy5C1YFnWm+YuY5mQiAWc4yAp13dqgguwsBsFVLh4LPCEqCa5qW13N+hw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-namespace-from@^7.8.3": version "7.8.3" @@ -582,12 +401,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.21.4.tgz#3e37fca4f06d93567c1cd9b75156422e90a67107" - integrity sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw== +"@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz#084564e0f3cc21ea6c70c44cff984a1c0509729a" + integrity sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" @@ -603,12 +422,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.18.6", "@babel/plugin-syntax-jsx@^7.21.4", "@babel/plugin-syntax-jsx@^7.7.2": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.21.4.tgz#f264ed7bf40ffc9ec239edabc17a50c4f5b6fea2" - integrity sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ== +"@babel/plugin-syntax-jsx@^7.0.0", "@babel/plugin-syntax-jsx@^7.23.3", "@babel/plugin-syntax-jsx@^7.7.2": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" @@ -659,121 +478,112 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.20.0", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.21.4.tgz#2751948e9b7c6d771a8efa59340c15d4a2891ff8" - integrity sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA== +"@babel/plugin-syntax-typescript@^7.23.3", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-arrow-functions@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.20.7.tgz#bea332b0e8b2dab3dafe55a163d8227531ab0551" - integrity sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" + integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-async-to-generator@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.20.7.tgz#dfee18623c8cb31deb796aa3ca84dda9cea94354" - integrity sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" + integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== dependencies: - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-remap-async-to-generator" "^7.18.9" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" "@babel/plugin-transform-block-scoped-functions@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" - integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" + integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-block-scoping@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz#e737b91037e5186ee16b76e7ae093358a5634f02" - integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ== + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" + integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-classes@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz#f469d0b07a4c5a7dbb21afad9e27e57b47031665" - integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ== + version "7.23.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.8.tgz#d08ae096c240347badd68cdf1b6d1624a6435d92" + integrity sha512-yAYslGsY1bX6Knmg46RjiCiNSwJKv2IUC8qOdYKqMMr0491SXFhcHqOdRDeCRohOOIzwN/90C6mQ9qAKgrP7dg== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-optimise-call-expression" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-replace-supers" "^7.20.7" - "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.23.6" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.20.7.tgz#704cc2fd155d1c996551db8276d55b9d46e4d0aa" - integrity sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" + integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/template" "^7.20.7" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.15" "@babel/plugin-transform-destructuring@^7.0.0": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.21.3.tgz#73b46d0fd11cd6ef57dea8a381b1215f4959d401" - integrity sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" + integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz#6aeca0adcb81dc627c8986e770bfaa4d9812aff5" - integrity sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w== +"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz#cfa7ca159cc3306fab526fc67091556b51af26ff" + integrity sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-flow" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.23.3" "@babel/plugin-transform-for-of@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz#964108c9988de1a60b4be2354a7d7e245f36e86e" - integrity sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ== + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.6.tgz#81c37e24171b37b370ba6aaffa7ac86bcb46f94e" + integrity sha512-aYH4ytZ0qSuBbpfhuofbg/e96oQ7U2w1Aw/UQmKT+1l39uEhUPoFS3fHevDc1G0OvewyDudfMKY1OulczHzWIw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-transform-function-name@^7.0.0": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" - integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" + integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== dependencies: - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-function-name" "^7.18.9" - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-literals@^7.0.0": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" - integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" + integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-member-expression-literals@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" - integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.21.2": - version "7.21.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.21.2.tgz#6ff5070e71e3192ef2b7e39820a06fb78e3058e7" - integrity sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" + integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== dependencies: - "@babel/helper-module-transforms" "^7.21.2" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-commonjs@^7.14.5": +"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.14.5", "@babel/plugin-transform-modules-commonjs@^7.23.3": version "7.23.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== @@ -783,155 +593,155 @@ "@babel/helper-simple-access" "^7.22.5" "@babel/plugin-transform-named-capturing-groups-regex@^7.0.0": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.20.5.tgz#626298dd62ea51d452c3be58b285d23195ba69a8" - integrity sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA== + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.20.5" - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-object-super@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" - integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" + integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-replace-supers" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" "@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.20.7": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.21.3.tgz#18fc4e797cf6d6d972cb8c411dbe8a809fa157db" - integrity sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" + integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-property-literals@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" - integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" + integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-display-name@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" - integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz#70529f034dd1e561045ad3c8152a267f0d7b6200" + integrity sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-jsx-self@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz#ec98d4a9baafc5a1eb398da4cf94afbb40254a54" - integrity sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.23.3.tgz#ed3e7dadde046cce761a8e3cf003a13d1a7972d9" + integrity sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz#88578ae8331e5887e8ce28e4c9dc83fb29da0b86" - integrity sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.23.3.tgz#03527006bdc8775247a78643c51d4e715fe39a3e" + integrity sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g== dependencies: - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-jsx@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz#656b42c2fdea0a6d8762075d58ef9d4e3c4ab8a2" - integrity sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg== + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312" + integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-jsx" "^7.18.6" - "@babel/types" "^7.21.0" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/types" "^7.23.4" "@babel/plugin-transform-runtime@^7.0.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.4.tgz#2e1da21ca597a7d01fc96b699b21d8d2023191aa" - integrity sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA== + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.23.9.tgz#2c64d0680fc8e09e1dfe8fd5c646fe72abd82004" + integrity sha512-A7clW3a0aSjm3ONU9o2HAILSegJCYlEZmOhmBRReVtIpY/Z/p7yIZ+wR41Z+UipwdGuqwtID/V/dOdZXjwi9gQ== dependencies: - "@babel/helper-module-imports" "^7.21.4" - "@babel/helper-plugin-utils" "^7.20.2" - babel-plugin-polyfill-corejs2 "^0.3.3" - babel-plugin-polyfill-corejs3 "^0.6.0" - babel-plugin-polyfill-regenerator "^0.4.1" - semver "^6.3.0" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + babel-plugin-polyfill-corejs2 "^0.4.8" + babel-plugin-polyfill-corejs3 "^0.9.0" + babel-plugin-polyfill-regenerator "^0.5.5" + semver "^6.3.1" "@babel/plugin-transform-shorthand-properties@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" - integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" + integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-spread@^7.0.0": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.20.7.tgz#c2d83e0b99d3bf83e07b11995ee24bf7ca09401e" - integrity sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" + integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-transform-sticky-regex@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" - integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" + integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-template-literals@^7.0.0": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" - integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" + integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== dependencies: - "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typescript@^7.21.3", "@babel/plugin-transform-typescript@^7.5.0": - version "7.21.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.3.tgz#316c5be579856ea890a57ebc5116c5d064658f2b" - integrity sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw== +"@babel/plugin-transform-typescript@^7.23.3", "@babel/plugin-transform-typescript@^7.5.0": + version "7.23.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.6.tgz#aa36a94e5da8d94339ae3a4e22d40ed287feb34c" + integrity sha512-6cBG5mBvUu4VUD04OHKnYzbuHNP8huDsD3EDqqpIpsswTDoqHCjLoHb6+QgsV1WsT2nipRqCPgxD3LXnEO7XfA== dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-typescript" "^7.20.0" + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.23.6" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.23.3" "@babel/plugin-transform-unicode-regex@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" - integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" + integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-flow@^7.13.13": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.21.4.tgz#a5de2a1cafa61f0e0b3af9b30ff0295d38d3608f" - integrity sha512-F24cSq4DIBmhq4OzK3dE63NHagb27OPE3eWR+HLekt4Z3Y5MzIIUGF3LlLgV0gN8vzbDViSY7HnrReNVCJXTeA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.23.3.tgz#8084e08b9ccec287bd077ab288b286fab96ffab1" + integrity sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.21.0" - "@babel/plugin-transform-flow-strip-types" "^7.21.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-transform-flow-strip-types" "^7.23.3" "@babel/preset-typescript@^7.13.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.21.4.tgz#b913ac8e6aa8932e47c21b01b4368d8aa239a529" - integrity sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" + integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-validator-option" "^7.21.0" - "@babel/plugin-syntax-jsx" "^7.21.4" - "@babel/plugin-transform-modules-commonjs" "^7.21.2" - "@babel/plugin-transform-typescript" "^7.21.3" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-typescript" "^7.23.3" "@babel/register@^7.13.16": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.21.0.tgz#c97bf56c2472e063774f31d344c592ebdcefa132" - integrity sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw== + version "7.23.7" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.23.7.tgz#485a5e7951939d21304cae4af1719fdb887bc038" + integrity sha512-EjJeB6+kvpk+Y5DAkEAmbOBEFkh9OASx0huoEkqYTFxAZHzOAX2Oh5uwAUuL2rUddqfM0SA+KPXV2TbzoZ2kvQ== dependencies: clone-deep "^4.0.1" find-cache-dir "^2.0.0" make-dir "^2.1.0" - pirates "^4.0.5" + pirates "^4.0.6" source-map-support "^0.5.16" "@babel/regjsgen@^0.8.0": @@ -940,31 +750,13 @@ integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== "@babel/runtime@^7.0.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" - integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/template@^7.0.0", "@babel/template@^7.18.10", "@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" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/template@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + version "7.23.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.9.tgz#47791a15e4603bb5f905bc0753801cf21d6345f7" + integrity sha512-0CX6F+BI2s9dkUqr08KFrAIZgNFj75rdBU/DjCyYLIaV/quFjkk6T+EJ2LkZHyZTbEV4L5p97mNkUsHl2wLFAw== dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" + regenerator-runtime "^0.14.0" -"@babel/template@^7.23.9": +"@babel/template@^7.0.0", "@babel/template@^7.22.15", "@babel/template@^7.23.9", "@babel/template@^7.3.3": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.23.9.tgz#f881d0487cba2828d3259dcb9ef5005a9731011a" integrity sha512-+xrD2BWLpvHKNmX2QbpdpsBaWnRxahMwJjO+KZk2JOElj5nSmKezyS1B4u+QbHMTX69t4ukm6hh9lsYQ7GHCKA== @@ -973,23 +765,7 @@ "@babel/parser" "^7.23.9" "@babel/types" "^7.23.9" -"@babel/traverse@^7.20.0", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.21.4": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" - integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.0" - "@babel/types" "^7.23.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/traverse@^7.23.9": +"@babel/traverse@^7.20.0", "@babel/traverse@^7.23.9": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.9.tgz#2f9d6aead6b564669394c5ce0f9302bb65b9d950" integrity sha512-I/4UJ9vs90OkBtY6iiiTORVMyIhJ4kAVmsKo9KFc8UOxMeUfi2hvtIBsET5u9GizXE6/GFSuKCTNfgCswuEjRg== @@ -1005,25 +781,7 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@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" - integrity sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA== - dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" - -"@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@babel/types@^7.23.6", "@babel/types@^7.23.9": +"@babel/types@^7.0.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.23.6", "@babel/types@^7.23.9", "@babel/types@^7.3.3": version "7.23.9" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.9.tgz#1dd7b59a9a2b5c87f8b41e52770b5ecbf492e002" integrity sha512-dQjSq/7HaSjRM43FFGnv5keM2HsxpmyV1PfaSVm0nzzjwwTmjOe6J4bC8e3+pTEIgHaHj+1ZlLThRJ2auc/w1Q== @@ -1038,11 +796,11 @@ integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== "@cheqd/sdk@cjs": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@cheqd/sdk/-/sdk-2.3.0.tgz#0594ccb501d1ad74f3360fa5beb12f002dc8e8d2" - integrity sha512-ncHwBdAAyauuLLWHXUNzUJo6Y7z02nhNOt87n2owUhvf5K2UbNcHHB/CzNwcQIc7OGcShPABydug8KE1ueNk/Q== + version "2.3.2" + resolved "https://registry.yarnpkg.com/@cheqd/sdk/-/sdk-2.3.2.tgz#5901bf4cb463c86fd59f7ad961099639b1db4bfd" + integrity sha512-oYKKPCiQR/xL1yvrLaofxagnBDSs9fiLQgBofgGwP38CEbG0G3rDuWAr/fPpRJCfOzqf957Az6uZx8+fSibiLA== dependencies: - "@cheqd/ts-proto" "^2.2.0" + "@cheqd/ts-proto" "~2.2.0" "@cosmjs/amino" "^0.29.5" "@cosmjs/crypto" "^0.29.5" "@cosmjs/encoding" "^0.29.5" @@ -1055,10 +813,11 @@ cosmjs-types "^0.5.2" did-jwt "^6.11.6" did-resolver "^4.1.0" + file-type "^16.5.4" multiformats "^9.9.0" uuid "^9.0.0" -"@cheqd/ts-proto@^2.2.0", "@cheqd/ts-proto@cjs": +"@cheqd/ts-proto@cjs", "@cheqd/ts-proto@~2.2.0": version "2.2.2" resolved "https://registry.yarnpkg.com/@cheqd/ts-proto/-/ts-proto-2.2.2.tgz#c0e808c6d438da7098a225ea24ee94db9822fa06" integrity sha512-32XCz1tD/T8r9Pw6IWH+XDttnGEguN0/1dWoUnTZ6uIPAA65YYSz2Ba9ZJ69a7YipYzX9C1CRddVZ3u229dfYg== @@ -1084,15 +843,15 @@ "@cosmjs/math" "^0.29.5" "@cosmjs/utils" "^0.29.5" -"@cosmjs/amino@^0.31.1": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.31.1.tgz#e6b4adc3ebe19ddfd953c67ee04b1eae488238af" - integrity sha512-kkB9IAkNEUFtjp/uwHv95TgM8VGJ4VWfZwrTyLNqBDD1EpSX2dsNrmUe7k8OMPzKlZUFcKmD4iA0qGvIwzjbGA== +"@cosmjs/amino@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.31.3.tgz#0f4aa6bd68331c71bd51b187fa64f00eb075db0a" + integrity sha512-36emtUq895sPRX8PTSOnG+lhJDCVyIcE0Tr5ct59sUbgQiI14y43vj/4WAlJ/utSOxy+Zhj9wxcs4AZfu0BHsw== dependencies: - "@cosmjs/crypto" "^0.31.1" - "@cosmjs/encoding" "^0.31.1" - "@cosmjs/math" "^0.31.1" - "@cosmjs/utils" "^0.31.1" + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" "@cosmjs/crypto@^0.29.5": version "0.29.5" @@ -1107,14 +866,14 @@ elliptic "^6.5.4" libsodium-wrappers "^0.7.6" -"@cosmjs/crypto@^0.31.1": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.31.1.tgz#ce4917df0f7b38f0909a32020907ccff04acefe6" - integrity sha512-4R/SqdzdVzd4E5dpyEh1IKm5GbTqwDogutyIyyb1bcOXiX/x3CrvPI9Tb4WSIMDLvlb5TVzu2YnUV51Q1+6mMA== +"@cosmjs/crypto@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.31.3.tgz#c752cb6d682fdc735dcb45a2519f89c56ba16c26" + integrity sha512-vRbvM9ZKR2017TO73dtJ50KxoGcFzKtKI7C8iO302BQ5p+DuB+AirUg1952UpSoLfv5ki9O416MFANNg8UN/EQ== dependencies: - "@cosmjs/encoding" "^0.31.1" - "@cosmjs/math" "^0.31.1" - "@cosmjs/utils" "^0.31.1" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" "@noble/hashes" "^1" bn.js "^5.2.0" elliptic "^6.5.4" @@ -1129,10 +888,10 @@ bech32 "^1.1.4" readonly-date "^1.0.0" -"@cosmjs/encoding@^0.31.1": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.31.1.tgz#0041b2650c443d883e22f27c7d3cd7b844c6d0ec" - integrity sha512-IuxP6ewwX6vg9sUJ8ocJD92pkerI4lyG8J5ynAM3NaX3q+n+uMoPRSQXNeL9bnlrv01FF1kIm8if/f5F7ZPtkA== +"@cosmjs/encoding@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.31.3.tgz#2519d9c9ae48368424971f253775c4580b54c5aa" + integrity sha512-6IRtG0fiVYwyP7n+8e54uTx2pLYijO48V3t9TLiROERm5aUAIzIlz6Wp0NYaI5he9nh1lcEGJ1lkquVKFw3sUg== dependencies: base64-js "^1.3.0" bech32 "^1.1.4" @@ -1153,10 +912,10 @@ dependencies: bn.js "^5.2.0" -"@cosmjs/math@^0.31.1": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.31.1.tgz#74c02cf237c2996b77661b636b014168b18d95e6" - integrity sha512-kiuHV6m6DSB8/4UV1qpFhlc4ul8SgLXTGRlYkYiIIP4l0YNeJ+OpPYaOlEgx4Unk2mW3/O2FWYj7Jc93+BWXng== +"@cosmjs/math@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.31.3.tgz#767f7263d12ba1b9ed2f01f68d857597839fd957" + integrity sha512-kZ2C6glA5HDb9hLz1WrftAjqdTBb3fWQsRR+Us2HsjAYdeE6M3VdXMsYCP5M3yiihal1WDwAY2U7HmfJw7Uh4A== dependencies: bn.js "^5.2.0" @@ -1174,15 +933,15 @@ long "^4.0.0" "@cosmjs/proto-signing@^0.31.0": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.31.1.tgz#3929d5bee3c88c42b3bc3c4b9db4ab3bddb684c4" - integrity sha512-hipbBVrssPu+jnmRzQRP5hhS/mbz2nU7RvxG/B1ZcdNhr1AtZC5DN09OTUoEpMSRgyQvScXmk/NTbyf+xmCgYg== - dependencies: - "@cosmjs/amino" "^0.31.1" - "@cosmjs/crypto" "^0.31.1" - "@cosmjs/encoding" "^0.31.1" - "@cosmjs/math" "^0.31.1" - "@cosmjs/utils" "^0.31.1" + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.31.3.tgz#20440b7b96fb2cd924256a10e656fd8d4481cdcd" + integrity sha512-24+10/cGl6lLS4VCrGTCJeDRPQTn1K5JfknzXzDIHOx8THR31JxA7/HV5eWGHqWgAbudA7ccdSvEK08lEHHtLA== + dependencies: + "@cosmjs/amino" "^0.31.3" + "@cosmjs/crypto" "^0.31.3" + "@cosmjs/encoding" "^0.31.3" + "@cosmjs/math" "^0.31.3" + "@cosmjs/utils" "^0.31.3" cosmjs-types "^0.8.0" long "^4.0.0" @@ -1242,10 +1001,10 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== -"@cosmjs/utils@^0.31.1": - version "0.31.1" - resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.31.1.tgz#e6055cd7d722fa72df9cbd0d39cd1f7a9ac80483" - integrity sha512-n4Se1wu4GnKwztQHNFfJvUeWcpvx3o8cWhSbNs9JQShEuB3nv3R5lqFBtDCgHZF/emFQAP+ZjF8bTfCs9UBGhA== +"@cosmjs/utils@^0.31.3": + version "0.31.3" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.31.3.tgz#f97bbfda35ad69e80cd5c7fe0a270cbda16db1ed" + integrity sha512-VBhAgzrrYdIe0O5IbKRqwszbQa7ZyQLx9nEQuHQ3HUplQW7P44COG/ye2n6AzCudtqxmwdX7nyX8ta1J07GoqA== "@cspotcode/source-map-support@^0.8.0": version "0.8.1" @@ -1272,9 +1031,9 @@ undici "^5.21.2" "@digitalbazaar/security-context@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@digitalbazaar/security-context/-/security-context-1.0.0.tgz#23624692cfadc6d97e1eb787ad38a19635d89297" - integrity sha512-mlj+UmodxTAdMCHGxnGVTRLHcSLyiEOVRiz3J6yiRliJWyrgeXs34wlWjBorDIEMDIjK2JwZrDuFEKO9bS5nKQ== + version "1.0.1" + resolved "https://registry.yarnpkg.com/@digitalbazaar/security-context/-/security-context-1.0.1.tgz#badc4b8da03411a32d4e7321ce7c4b355776b410" + integrity sha512-0WZa6tPiTZZF8leBtQgYAfXQePFQp2z5ivpCEN/iZguYYZ0TB9qRmWtan5XH6mNFuusHtMcyIzAcReyE6rZPhA== "@digitalbazaar/vc-status-list-context@^3.0.1": version "3.0.1" @@ -1349,18 +1108,7 @@ ky "^0.25.1" ky-universal "^0.8.2" -"@digitalcredentials/jsonld-signatures@^9.3.1": - version "9.3.2" - resolved "https://registry.yarnpkg.com/@digitalcredentials/jsonld-signatures/-/jsonld-signatures-9.3.2.tgz#2c8141e7dfec2228b54ebd1f94d925df250351bb" - integrity sha512-auubZrr3D7et5O6zCdqoXsLhI8/F26HqneE94gIoZYVuxNHBNaFoDQ1Z71RfddRqwJonHkfkWgeZSzqjv6aUmg== - dependencies: - "@digitalbazaar/security-context" "^1.0.0" - "@digitalcredentials/jsonld" "^6.0.0" - fast-text-encoding "^1.0.3" - isomorphic-webcrypto "^2.3.8" - serialize-error "^8.0.1" - -"@digitalcredentials/jsonld-signatures@^9.3.2", "@digitalcredentials/jsonld-signatures@^9.4.0": +"@digitalcredentials/jsonld-signatures@^9.3.1", "@digitalcredentials/jsonld-signatures@^9.3.2", "@digitalcredentials/jsonld-signatures@^9.4.0": version "9.4.0" resolved "https://registry.yarnpkg.com/@digitalcredentials/jsonld-signatures/-/jsonld-signatures-9.4.0.tgz#d5881122c4202449b88a7e2384f8e615ae55582c" integrity sha512-DnR+HDTm7qpcDd0wcD1w6GdlAwfHjQSgu+ahion8REkCkkMRywF+CLunU7t8AZpFB2Gr/+N8naUtiEBNje1Oew== @@ -1372,9 +1120,9 @@ serialize-error "^8.0.1" "@digitalcredentials/jsonld@^5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@digitalcredentials/jsonld/-/jsonld-5.2.1.tgz#60acf587bec8331e86324819fd19692939118775" - integrity sha512-pDiO1liw8xs+J/43qnMZsxyz0VOWOb7Q2yUlBt/tyjq6SlT9xPo+3716tJPbjGPnou2lQRw3H5/I++z+6oQ07w== + version "5.2.2" + resolved "https://registry.yarnpkg.com/@digitalcredentials/jsonld/-/jsonld-5.2.2.tgz#d2bdefe25788ece77e900a9491c64c2187e3344c" + integrity sha512-hz7YR3kv6+8UUdgMyTGl1o8NjVKKwnMry/Rh/rWeAvwL+NqgoUHorWzI3rM+PW+MPFyDC0ieXStClt9n9D9SGA== dependencies: "@digitalcredentials/http-client" "^1.0.0" "@digitalcredentials/rdf-canonize" "^1.0.0" @@ -1444,19 +1192,19 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.4.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.0.tgz#f6f729b02feee2c749f57e334b7a1b5f40a81724" - integrity sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ== +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== -"@eslint/eslintrc@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.2.tgz#01575e38707add677cf73ca1589abba8da899a02" - integrity sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ== +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.5.1" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -1464,10 +1212,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.39.0": - version "8.39.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.39.0.tgz#58b536bcc843f4cd1e02a7e6171da5c040f4d44b" - integrity sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng== +"@eslint/js@8.56.0": + version "8.56.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b" + integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A== "@fastify/busboy@^2.0.0": version "2.1.0" @@ -1479,25 +1227,25 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== -"@hapi/hoek@^9.0.0": +"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": version "9.3.0" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== -"@hapi/topo@^5.0.0": +"@hapi/topo@^5.1.0": version "5.1.0" resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== dependencies: "@hapi/hoek" "^9.0.0" -"@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== +"@humanwhocodes/config-array@^0.11.13": + version "0.11.14" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" + integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" + "@humanwhocodes/object-schema" "^2.0.2" + debug "^4.3.1" minimatch "^3.0.5" "@humanwhocodes/module-importer@^1.0.1": @@ -1505,10 +1253,10 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" 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" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== +"@humanwhocodes/object-schema@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz#d9fae00a2d5cb40f92cfe64b47ad749fbc38f917" + integrity sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw== "@hutson/parse-repository-url@^3.0.0": version "3.0.2" @@ -1569,6 +1317,18 @@ resolved "https://registry.yarnpkg.com/@hyperledger/indy-vdr-shared/-/indy-vdr-shared-0.2.0-dev.6.tgz#4954ee06fa8a2e4545b35cd525b7b86e0f10b6fe" integrity sha512-pNLq0zkqv5rFCpU9tzyJ5DPvED5YE+UFP8iKwVD7fe+mAD6/VpweOunYNKgIBT4K1DYI21q7bs3SzxQZ0hLlKw== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@isaacs/string-locale-compare@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz#291c227e93fd407a96ecd59879a35809120e432b" @@ -1637,21 +1397,11 @@ strip-ansi "^6.0.0" "@jest/create-cache-key-function@^29.2.1": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.5.0.tgz#24e019d03e634be4affe8bcee787d75a36ae57a2" - integrity sha512-LIDZyZgnZss7uikvBKBB/USWwG+GO8+GnwRWT+YkCGDGsqLQlhm9BC3z6+7+eMs1kUlvXQIWEzBR8Q2Pnvx6lg== - dependencies: - "@jest/types" "^29.5.0" - -"@jest/environment@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.5.0.tgz#9152d56317c1fdb1af389c46640ba74ef0bb4c65" - integrity sha512-5FXw2+wD29YU1d4I2htpRX7jYnAyTRjP2CsXQdo9SAM8g3ifxWPSV0HnClSn71xwctr0U3oZIIH+dtbfmnbXVQ== + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.7.0.tgz#793be38148fab78e65f40ae30c36785f4ad859f0" + integrity sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA== dependencies: - "@jest/fake-timers" "^29.5.0" - "@jest/types" "^29.5.0" - "@types/node" "*" - jest-mock "^29.5.0" + "@jest/types" "^29.6.3" "@jest/environment@^29.7.0": version "29.7.0" @@ -1663,13 +1413,6 @@ "@types/node" "*" jest-mock "^29.7.0" -"@jest/expect-utils@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.5.0.tgz#f74fad6b6e20f924582dc8ecbf2cb800fe43a036" - integrity sha512-fmKzsidoXQT2KwnrwE0SQq3uj8Z763vzR8LnLBwC2qYWEFpjX8daRsk6rHUM1QvNlEW/UJXNXm59ztmJJWs2Mg== - dependencies: - jest-get-type "^29.4.3" - "@jest/expect-utils@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" @@ -1685,18 +1428,6 @@ expect "^29.7.0" jest-snapshot "^29.7.0" -"@jest/fake-timers@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.5.0.tgz#d4d09ec3286b3d90c60bdcd66ed28d35f1b4dc2c" - integrity sha512-9ARvuAAQcBwDAqOnglWq2zwNIRUDtk/SCkp/ToGEhFv5r86K21l+VEs0qNTaXtyiY0lEePl3kylijSYJQqdbDg== - dependencies: - "@jest/types" "^29.5.0" - "@sinonjs/fake-timers" "^10.0.2" - "@types/node" "*" - jest-message-util "^29.5.0" - jest-mock "^29.5.0" - jest-util "^29.5.0" - "@jest/fake-timers@^29.7.0": version "29.7.0" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" @@ -1749,14 +1480,7 @@ strip-ansi "^6.0.0" v8-to-istanbul "^9.0.1" -"@jest/schemas@^29.4.3": - version "29.4.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" - integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== - dependencies: - "@sinclair/typebox" "^0.25.16" - -"@jest/schemas@^29.6.3": +"@jest/schemas@^29.4.3", "@jest/schemas@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== @@ -1835,18 +1559,6 @@ "@types/yargs" "^16.0.0" chalk "^4.0.0" -"@jest/types@^29.5.0": - version "29.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.5.0.tgz#f59ef9b031ced83047c67032700d8c807d6e1593" - integrity sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog== - dependencies: - "@jest/schemas" "^29.4.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - "@jest/types@^29.6.3": version "29.6.3" resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" @@ -1868,11 +1580,6 @@ "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" -"@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" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": version "3.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" @@ -1883,19 +1590,14 @@ resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== -"@jridgewell/source-map@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" - integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== +"@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" -"@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" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" @@ -1909,43 +1611,35 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.12", "@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" - integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - -"@jridgewell/trace-mapping@^0.3.18": - version "0.3.19" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.22" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz#72a621e5de59f5f1ef792d0793a82ee20f645e4c" + integrity sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw== dependencies: "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@lerna/child-process@6.6.1": - version "6.6.1" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-6.6.1.tgz#e31bc411ad6d474cf7b676904da6f77f58fd64eb" - integrity sha512-yUCDCcRNNbI9UUsUB6FYEmDHpo5Tn/f0q5D7vhDP4i6Or8kBj82y7+e31hwfLvK2ykOYlDVs2MxAluH/+QUBOQ== +"@lerna/child-process@6.6.2": + version "6.6.2" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-6.6.2.tgz#5d803c8dee81a4e013dc428292e77b365cba876c" + integrity sha512-QyKIWEnKQFnYu2ey+SAAm1A5xjzJLJJj3bhIZd3QKyXKKjaJ0hlxam/OsWSltxTNbcyH1jRJjC6Cxv31usv0Ag== dependencies: chalk "^4.1.0" execa "^5.0.0" strong-log-transformer "^2.1.0" -"@lerna/create@6.6.1": - version "6.6.1" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-6.6.1.tgz#fc20f09e10b612d424a576775ad6eefe6aa96517" - integrity sha512-GDmHFhQ0mr0RcXWXrsLyfMV6ch/dZV/Ped1e6sFVQhsLL9P+FFXX1ZWxa/dQQ90VWF2qWcmK0+S/L3kUz2xvTA== +"@lerna/create@6.6.2": + version "6.6.2" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-6.6.2.tgz#39a36d80cddb355340c297ed785aa76f4498177f" + integrity sha512-xQ+1Y7D+9etvUlE+unhG/TwmM6XBzGIdFBaNoW8D8kyOa9M2Jf3vdEtAxVa7mhRz66CENfhL/+I/QkVaa7pwbQ== dependencies: - "@lerna/child-process" "6.6.1" + "@lerna/child-process" "6.6.2" dedent "^0.7.0" fs-extra "^9.1.0" init-package-json "^3.0.2" npm-package-arg "8.1.1" p-reduce "^2.1.0" - pacote "^13.6.1" + pacote "15.1.1" pify "^5.0.0" semver "^7.3.4" slash "^3.0.0" @@ -1953,10 +1647,10 @@ validate-npm-package-name "^4.0.0" yargs-parser "20.2.4" -"@lerna/legacy-package-management@6.6.1": - version "6.6.1" - resolved "https://registry.yarnpkg.com/@lerna/legacy-package-management/-/legacy-package-management-6.6.1.tgz#1f44af40098b9396a4f698514ff2b87016b1ee3d" - integrity sha512-0EYxSFr34VgeudA5rvjGJSY7s4seITMVB7AJ9LRFv9QDUk6jpvapV13ZAaKnhDTxX5vNCfnJuWHXXWq0KyPF/Q== +"@lerna/legacy-package-management@6.6.2": + version "6.6.2" + resolved "https://registry.yarnpkg.com/@lerna/legacy-package-management/-/legacy-package-management-6.6.2.tgz#411c395e72e563ab98f255df77e4068627a85bb0" + integrity sha512-0hZxUPKnHwehUO2xC4ldtdX9bW0W1UosxebDIQlZL2STnZnA2IFmIk2lJVUyFW+cmTPQzV93jfS0i69T9Z+teg== dependencies: "@npmcli/arborist" "6.2.3" "@npmcli/run-script" "4.1.7" @@ -1987,7 +1681,7 @@ inquirer "8.2.4" is-ci "2.0.0" is-stream "2.0.0" - libnpmpublish "6.0.4" + libnpmpublish "7.1.4" load-json-file "6.2.0" make-dir "3.1.0" minimatch "3.0.5" @@ -2001,7 +1695,7 @@ p-map-series "2.1.0" p-queue "6.6.2" p-waterfall "2.1.1" - pacote "13.6.2" + pacote "15.1.1" pify "5.0.0" pretty-format "29.4.3" read-cmd-shim "3.0.0" @@ -2021,7 +1715,7 @@ write-pkg "4.0.0" yargs "16.2.0" -"@mapbox/node-pre-gyp@1.0.11", "@mapbox/node-pre-gyp@^1.0.11": +"@mapbox/node-pre-gyp@1.0.11", "@mapbox/node-pre-gyp@^1.0.10", "@mapbox/node-pre-gyp@^1.0.11": version "1.0.11" resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz#417db42b7f5323d79e93b34a6d7a2a12c0df43fa" integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== @@ -2036,31 +1730,7 @@ semver "^7.3.5" tar "^6.1.11" -"@mapbox/node-pre-gyp@^1.0.10": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" - integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - -"@mattrglobal/bbs-signatures@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@mattrglobal/bbs-signatures/-/bbs-signatures-1.0.0.tgz#8ff272c6d201aadab7e08bd84dbfd6e0d48ba12d" - integrity sha512-FFzybdKqSCrS/e7pl5s6Tl/m/x8ZD5EMBbcTBQaqSOms/lebm91lFukYOIe2qc0a5o+gLhtRKye8OfKwD1Ex/g== - dependencies: - "@stablelib/random" "1.0.0" - optionalDependencies: - "@mattrglobal/node-bbs-signatures" "0.13.0" - -"@mattrglobal/bbs-signatures@^1.0.0": +"@mattrglobal/bbs-signatures@1.3.1", "@mattrglobal/bbs-signatures@^1.0.0": version "1.3.1" resolved "https://registry.yarnpkg.com/@mattrglobal/bbs-signatures/-/bbs-signatures-1.3.1.tgz#ed00b9c5bb5ea7fb4ca1dc6316a32d0618acc82e" integrity sha512-syZGkapPpktD2el4lPTCQRw/LSia6/NwBS83hzCKu4dTlaJRO636qo5NCiiQb+iBYWyZQQEzN0jdRik8N9EUGA== @@ -2070,21 +1740,13 @@ "@mattrglobal/node-bbs-signatures" "0.18.1" "@mattrglobal/bls12381-key-pair@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@mattrglobal/bls12381-key-pair/-/bls12381-key-pair-1.0.0.tgz#2959f8663595de0209bebe88517235ae34f1e2b1" - integrity sha512-FbvSkoy1n3t5FHtAPj8cyQJL7Bz+hvvmquCBZW2+bOBBBT26JhGtr//s6EmXE9e4EZk7bAA1yMHI6i1Ky2us0Q== + version "1.2.1" + resolved "https://registry.yarnpkg.com/@mattrglobal/bls12381-key-pair/-/bls12381-key-pair-1.2.1.tgz#4c6625bd9375c4bd0702a275d22c7de12c7aba1e" + integrity sha512-Xh63NP1iSGBLW10N5uRpDyoPo2LtNHHh/TRGVJEHRgo+07yxgl8tS06Q2zO9gN9+b+GU5COKvR3lACwrvn+MYw== dependencies: - "@mattrglobal/bbs-signatures" "1.0.0" + "@mattrglobal/bbs-signatures" "1.3.1" bs58 "4.0.1" - rfc4648 "1.4.0" - -"@mattrglobal/node-bbs-signatures@0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@mattrglobal/node-bbs-signatures/-/node-bbs-signatures-0.13.0.tgz#3e431b915325d4b139706f8b26fd84b27c192a29" - integrity sha512-S2wOwDCQYxdjSEjVfcbP3bTq4ZMKeRw/wvBhWRff8CEwuH5u3Qiul+azwDGSesvve1DDceaEhXWiGkXeZTojfQ== - dependencies: - neon-cli "0.8.2" - node-pre-gyp "0.17.0" + rfc4648 "1.5.2" "@mattrglobal/node-bbs-signatures@0.18.1": version "0.18.1" @@ -2100,9 +1762,9 @@ integrity sha512-eMk0b9ReBbV23xXU693TAIrLyeO5iTgBZGSJfpqriG8UkYvr/hC9u9pyMlAakDNHWmbhMZCDs6KQO0jzKD8OTw== "@noble/hashes@^1", "@noble/hashes@^1.0.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" - integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== + version "1.3.3" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" + integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== "@nodelib/fs.scandir@2.1.5": version "2.1.5" @@ -2179,25 +1841,10 @@ dependencies: semver "^7.3.5" -"@npmcli/git@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-3.0.2.tgz#5c5de6b4d70474cf2d09af149ce42e4e1dacb931" - integrity sha512-CAcd08y3DWBJqJDpfuVL0uijlq5oaXaOJEKHKc4wqrjd00gkvTZB+nFuLn+doOOKddaQS9JfqtNoFCO2LCvA3w== - dependencies: - "@npmcli/promise-spawn" "^3.0.0" - lru-cache "^7.4.4" - mkdirp "^1.0.4" - npm-pick-manifest "^7.0.0" - proc-log "^2.0.0" - promise-inflight "^1.0.1" - promise-retry "^2.0.1" - semver "^7.3.5" - which "^2.0.2" - -"@npmcli/git@^4.0.0": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.0.4.tgz#cdf74f21b1d440c0756fb28159d935129d9daa33" - integrity sha512-5yZghx+u5M47LghaybLCkdSyFzV/w4OuH12d96HO389Ik9CDsLaDZJVynSGGVJOLn6gy/k7Dz5XYcplM3uxXRg== +"@npmcli/git@^4.0.0", "@npmcli/git@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6" + integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== dependencies: "@npmcli/promise-spawn" "^6.0.0" lru-cache "^7.4.4" @@ -2208,14 +1855,6 @@ semver "^7.3.5" which "^3.0.0" -"@npmcli/installed-package-contents@^1.0.7": - version "1.0.7" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" - integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw== - dependencies: - npm-bundled "^1.1.1" - npm-normalize-package-bin "^1.0.1" - "@npmcli/installed-package-contents@^2.0.0", "@npmcli/installed-package-contents@^2.0.1": version "2.0.2" resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33" @@ -2225,13 +1864,13 @@ npm-normalize-package-bin "^3.0.0" "@npmcli/map-workspaces@^3.0.2": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-3.0.3.tgz#476944b63cd1f65bf83c6fdc7f4ca7be56906b1f" - integrity sha512-HlCvFuTzw4UNoKyZdqiNrln+qMF71QJkxy2dsusV8QQdoa89e2TF4dATCzBxbl4zzRzdDoWWyP5ADVrNAH9cRQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-3.0.4.tgz#15ad7d854292e484f7ba04bc30187a8320dba799" + integrity sha512-Z0TbvXkRbacjFFLpVpV0e2mheCh+WzQpcqL+4xp49uNJOxOnIAPZyXtUxZ5Qn3QBTGKA11Exjd9a5411rBrhDg== dependencies: "@npmcli/name-from-folder" "^2.0.0" - glob "^9.3.1" - minimatch "^7.4.2" + glob "^10.2.2" + minimatch "^9.0.0" read-package-json-fast "^3.0.0" "@npmcli/metavuln-calculator@^5.0.0": @@ -2268,11 +1907,16 @@ integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== "@npmcli/package-json@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-3.0.0.tgz#c9219a197e1be8dbf43c4ef8767a72277c0533b6" - integrity sha512-NnuPuM97xfiCpbTEJYtEuKz6CFbpUHtaT0+5via5pQeI25omvQDFbp1GcGJ/c4zvL/WX0qbde6YiLgfZbWFgvg== + version "3.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/package-json/-/package-json-3.1.1.tgz#5628332aac90fa1b4d6f98e03988c5958b35e0c5" + integrity sha512-+UW0UWOYFKCkvszLoTwrYGrjNrT8tI5Ckeb/h+Z1y1fsNJEctl7HmerA5j2FgmoqFaLI2gsA1X9KgMFqx/bRmA== dependencies: + "@npmcli/git" "^4.1.0" + glob "^10.2.2" json-parse-even-better-errors "^3.0.0" + normalize-package-data "^5.0.0" + npm-normalize-package-bin "^3.0.1" + proc-log "^3.0.0" "@npmcli/promise-spawn@^3.0.0": version "3.0.0" @@ -2289,9 +1933,9 @@ which "^3.0.0" "@npmcli/query@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/query/-/query-3.0.0.tgz#51a0dfb85811e04f244171f164b6bc83b36113a7" - integrity sha512-MFNDSJNgsLZIEBVZ0Q9w9K7o07j5N4o4yjtdz2uEpuCZlXGMuPENiRaFYk0vRqAA64qVuUQwC05g27fRtfUgnA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/query/-/query-3.0.1.tgz#77d63ceb7d27ed748da3cc8b50d45fc341448ed6" + integrity sha512-0jE8iHBogf/+bFDj+ju6/UMLbJ39c8h6nSe6qile+dB7PJ0iV3gNqcb2vtt6WWCBrxv9uAjzUT/8vroluulidA== dependencies: postcss-selector-parser "^6.0.10" @@ -2306,21 +1950,10 @@ read-package-json-fast "^2.0.3" which "^2.0.2" -"@npmcli/run-script@^4.1.0": - version "4.2.1" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-4.2.1.tgz#c07c5c71bc1c70a5f2a06b0d4da976641609b946" - integrity sha512-7dqywvVudPSrRCW5nTHpHgeWnbBtz8cFkOuKrecm6ih+oO9ciydhWt6OF7HlqupRRmB8Q/gECVdB9LMfToJbRg== - dependencies: - "@npmcli/node-gyp" "^2.0.0" - "@npmcli/promise-spawn" "^3.0.0" - node-gyp "^9.0.0" - read-package-json-fast "^2.0.3" - which "^2.0.2" - "@npmcli/run-script@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.0.tgz#f89e322c729e26ae29db6cc8cc76559074aac208" - integrity sha512-ql+AbRur1TeOdl1FY+RAwGW9fcr4ZwiVKabdvm93mujGREVuVLbdkXRJDrkTXSdCjaxYydr1wlA2v67jxWG5BQ== + version "6.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" + integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== dependencies: "@npmcli/node-gyp" "^3.0.0" "@npmcli/promise-spawn" "^6.0.0" @@ -2328,87 +1961,85 @@ read-package-json-fast "^3.0.0" which "^3.0.0" -"@nrwl/cli@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.9.2.tgz#82537d3d85410b0143d37a3b4fade09675356084" - integrity sha512-QoCmyrcGakHAYTJaNBbOerRQAmqJHMYGCdqtQidV+aP9p1Dy33XxDELfhd+IYmGqngutXuEWChNpWNhPloLnoA== +"@nrwl/cli@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/cli/-/cli-15.9.7.tgz#1db113f5cb1cfe63213097be1ece041eef33da1f" + integrity sha512-1jtHBDuJzA57My5nLzYiM372mJW0NY6rFKxlWt5a0RLsAZdPTHsd8lE3Gs9XinGC1jhXbruWmhhnKyYtZvX/zA== dependencies: - nx "15.9.2" + nx "15.9.7" "@nrwl/devkit@>=15.5.2 < 16": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.9.2.tgz#482b89f1bf88d3600b11f8b7e3e4452c5766eca4" - integrity sha512-2DvTstVZb91m+d4wqUJMBHQ3elxyabdmFE6/3aXmtOGeDxTyXyDzf/1O6JvBBiL8K6XC3ZYchjtxUHgxl/NJ5A== + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-15.9.7.tgz#14d19ec82ff4209c12147a97f1cdea05d8f6c087" + integrity sha512-Sb7Am2TMT8AVq8e+vxOlk3AtOA2M0qCmhBzoM1OJbdHaPKc0g0UgSnWRml1kPGg5qfPk72tWclLoZJ5/ut0vTg== dependencies: ejs "^3.1.7" ignore "^5.0.4" - semver "7.3.4" + semver "7.5.4" tmp "~0.2.1" tslib "^2.3.0" -"@nrwl/nx-darwin-arm64@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.9.2.tgz#612d8d714ec876cafd6f1483bf5565704d1b75be" - integrity sha512-Yv+OVsQt3C/hmWOC+YhJZQlsyph5w1BHfbp4jyCvV1ZXBbb8NdvwxgDHPWXxKPTc1EXuB7aEX3qzxM3/OWEUJg== - -"@nrwl/nx-darwin-x64@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.9.2.tgz#3f77bd90dbabf4782d81f773cfb2739a443e595f" - integrity sha512-qHfdluHlPzV0UHOwj1ZJ+qNEhzfLGiBuy1cOth4BSzDlvMnkuqBWoprfaXoztzYcus2NSILY1/7b3Jw4DAWmMw== - -"@nrwl/nx-linux-arm-gnueabihf@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.9.2.tgz#3374a5a1692b222ce18f2213a47b4d68fb509e70" - integrity sha512-0GzwbablosnYnnJDCJvAeZv8LlelSrNwUnGhe43saeoZdAew35Ay1E34zBrg/GCGTASuz+knEEYFM+gDD9Mc6A== - -"@nrwl/nx-linux-arm64-gnu@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.9.2.tgz#e3ec95c6ee3285c77422886cf4cbec1f04804460" - integrity sha512-3mFIY7iUTPG45hSIRaM2DmraCy8W6hNoArAGRrTgYw40BIJHtLrW+Rt7DLyvVXaYCvrKugWOKtxC+jG7kpIZVA== - -"@nrwl/nx-linux-arm64-musl@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.9.2.tgz#72ce601d256083ded7380c598f1b3eb4dc2a3472" - integrity sha512-FNBnXEtockwxZa4I3NqggrJp0YIbNokJvt/clrICP+ijOacdUDkv8mJedavobkFsRsNq9gzCbRbUScKymrOLrg== - -"@nrwl/nx-linux-x64-gnu@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.9.2.tgz#2da6bb50cd80d699310e91c7331baa6cfc8ce197" - integrity sha512-gHWsP5lbe4FNQCa1Q/VLxIuik+BqAOcSzyPjdUa4gCDcbxPa8xiE57PgXB5E1XUzOWNnDTlXa/Ll07/TIuKuog== - -"@nrwl/nx-linux-x64-musl@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.9.2.tgz#39b3bda5868a53b722f1d42700dce71c5ff3f6b9" - integrity sha512-EaFUukCbmoHsYECX2AS4pxXH933yesBFVvBgD38DkoFDxDoJMVt6JqYwm+d5R7S4R2P9U3l++aurljQTRq567Q== - -"@nrwl/nx-win32-arm64-msvc@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.9.2.tgz#bc350be5cb7d0bfa6c2c5ced40c5af163a457a2c" - integrity sha512-PGAe7QMr51ivx1X3avvs8daNlvv1wGo3OFrobjlu5rSyjC1Y3qHwT9+wdlwzNZ93FIqWOq09s+rE5gfZRfpdAg== - -"@nrwl/nx-win32-x64-msvc@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.9.2.tgz#3e46c3f7af196bdbf0deb336ec4f9448c54e4a9f" - integrity sha512-Q8onNzhuAZ0l9DNkm8D4Z1AEIzJr8JiT4L2fVBLYrV/R75C2HS3q7lzvfo6oqMY6mXge1cFPcrTtg3YXBQaSWA== - -"@nrwl/tao@15.9.2": - version "15.9.2" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.9.2.tgz#e970efa8b3fb828007b02286e9e505247032b5b3" - integrity sha512-+LqNC37w9c6q6Ukdpf0z0tt1PQFNi4gwhHpJvkYQiKRETHjyrrlyqTNEPEyA7PI62RuYC6VrpVw2gzI7ufqZEA== - dependencies: - nx "15.9.2" +"@nrwl/nx-darwin-arm64@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-arm64/-/nx-darwin-arm64-15.9.7.tgz#a2cb7390c782b8acf3bb8806a3002620226a933d" + integrity sha512-aBUgnhlkrgC0vu0fK6eb9Vob7eFnkuknrK+YzTjmLrrZwj7FGNAeyGXSlyo1dVokIzjVKjJg2saZZ0WQbfuCJw== + +"@nrwl/nx-darwin-x64@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-darwin-x64/-/nx-darwin-x64-15.9.7.tgz#af0437e726aeb97eb660646bfd9a7da5ba7a0a6f" + integrity sha512-L+elVa34jhGf1cmn38Z0sotQatmLovxoASCIw5r1CBZZeJ5Tg7Y9nOwjRiDixZxNN56hPKXm6xl9EKlVHVeKlg== + +"@nrwl/nx-linux-arm-gnueabihf@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-15.9.7.tgz#e29f4d31afa903bfb4d0fd7421e19be1086eae87" + integrity sha512-pqmfqqEUGFu6PmmHKyXyUw1Al0Ki8PSaR0+ndgCAb1qrekVDGDfznJfaqxN0JSLeolPD6+PFtLyXNr9ZyPFlFg== + +"@nrwl/nx-linux-arm64-gnu@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-15.9.7.tgz#eb2880a24d3268dd93583d21a6a0b9ff96bb23b4" + integrity sha512-NYOa/eRrqmM+In5g3M0rrPVIS9Z+q6fvwXJYf/KrjOHqqan/KL+2TOfroA30UhcBrwghZvib7O++7gZ2hzwOnA== + +"@nrwl/nx-linux-arm64-musl@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-arm64-musl/-/nx-linux-arm64-musl-15.9.7.tgz#5d04913c4672a96cefa78491824620d8a8bcfd7f" + integrity sha512-zyStqjEcmbvLbejdTOrLUSEdhnxNtdQXlmOuymznCzYUEGRv+4f7OAepD3yRoR0a/57SSORZmmGQB7XHZoYZJA== + +"@nrwl/nx-linux-x64-gnu@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-gnu/-/nx-linux-x64-gnu-15.9.7.tgz#cf7f61fd87f35a793e6824952a6eb12242fe43fd" + integrity sha512-saNK5i2A8pKO3Il+Ejk/KStTApUpWgCxjeUz9G+T8A+QHeDloZYH2c7pU/P3jA9QoNeKwjVO9wYQllPL9loeVg== + +"@nrwl/nx-linux-x64-musl@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-linux-x64-musl/-/nx-linux-x64-musl-15.9.7.tgz#2bec23c3696780540eb47fa1358dda780c84697f" + integrity sha512-extIUThYN94m4Vj4iZggt6hhMZWQSukBCo8pp91JHnDcryBg7SnYmnikwtY1ZAFyyRiNFBLCKNIDFGkKkSrZ9Q== + +"@nrwl/nx-win32-arm64-msvc@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-15.9.7.tgz#21b56ef3ab4190370effea71bd83fdc3e47ec69c" + integrity sha512-GSQ54hJ5AAnKZb4KP4cmBnJ1oC4ILxnrG1mekxeM65c1RtWg9NpBwZ8E0gU3xNrTv8ZNsBeKi/9UhXBxhsIh8A== + +"@nrwl/nx-win32-x64-msvc@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/nx-win32-x64-msvc/-/nx-win32-x64-msvc-15.9.7.tgz#1677ab1dcce921706b5677dc2844e3e0027f8bd5" + integrity sha512-x6URof79RPd8AlapVbPefUD3ynJZpmah3tYaYZ9xZRMXojVtEHV8Qh5vysKXQ1rNYJiiB8Ah6evSKWLbAH60tw== + +"@nrwl/tao@15.9.7": + version "15.9.7" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-15.9.7.tgz#c0e78c99caa6742762f7558f20d8524bc9015e97" + integrity sha512-OBnHNvQf3vBH0qh9YnvBQQWyyFZ+PWguF6dJ8+1vyQYlrLVk/XZ8nJ4ukWFb+QfPv/O8VBmqaofaOI9aFC4yTw== + dependencies: + nx "15.9.7" "@octokit/auth-token@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.3.tgz#ce7e48a3166731f26068d7a7a7996b5da58cbe0c" - integrity sha512-/aFM2M4HVDBT/jjDBa84sJniv1t9Gm/rLkalaz9htOm+L+8JMj1k9w0CkUdcxNyNxZPlTxKPVko+m1VlM58ZVA== - dependencies: - "@octokit/types" "^9.0.0" + version "3.0.4" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" + integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== "@octokit/core@^4.0.0": - version "4.2.0" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.0.tgz#8c253ba9605aca605bc46187c34fcccae6a96648" - integrity sha512-AgvDRUg3COpR82P7PBdGZF/NNqGmtMq2NiPqeSsDIeCfYFOZ9gddqWNQHnFdEUf+YwOj4aZYmJnlPp7OXmDIDg== + version "4.2.4" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" + integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ== dependencies: "@octokit/auth-token" "^3.0.0" "@octokit/graphql" "^5.0.0" @@ -2419,18 +2050,18 @@ universal-user-agent "^6.0.0" "@octokit/endpoint@^7.0.0": - version "7.0.5" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.5.tgz#2bb2a911c12c50f10014183f5d596ce30ac67dd1" - integrity sha512-LG4o4HMY1Xoaec87IqQ41TQ+glvIeTKqfjkCEmt5AIwDZJwQeVZFIEYXrYY6yLwK+pAScb9Gj4q+Nz2qSw1roA== + version "7.0.6" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" + integrity sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg== dependencies: "@octokit/types" "^9.0.0" is-plain-object "^5.0.0" universal-user-agent "^6.0.0" "@octokit/graphql@^5.0.0": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.5.tgz#a4cb3ea73f83b861893a6370ee82abb36e81afd2" - integrity sha512-Qwfvh3xdqKtIznjX9lz2D458r7dJPP8l6r4GQkIdWQouZwHQK0mVT88uwiU2bdTU2OtT1uOlKpRciUWldpG0yQ== + version "5.0.6" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" + integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== dependencies: "@octokit/request" "^6.0.0" "@octokit/types" "^9.0.0" @@ -2446,10 +2077,10 @@ resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-14.0.0.tgz#949c5019028c93f189abbc2fb42f333290f7134a" integrity sha512-HNWisMYlR8VCnNurDU6os2ikx0s0VyEjDYHNS/h4cgb8DeOxQ0n72HyinUtdDVxJhFy3FWLGl0DJhfEWk3P5Iw== -"@octokit/openapi-types@^17.0.0": - version "17.0.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-17.0.0.tgz#7356d287f48b20e9a1f497ef8dfaabdff9cf8622" - integrity sha512-V8BVJGN0ZmMlURF55VFHFd/L92XQQ43KvFjNmY1IYbCN3V/h/uUFV6iQi19WEHM395Nn+1qhUbViCAD/1czzog== +"@octokit/openapi-types@^18.0.0": + version "18.1.1" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" + integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== "@octokit/plugin-enterprise-rest@6.0.1": version "6.0.1" @@ -2486,9 +2117,9 @@ once "^1.4.0" "@octokit/request@^6.0.0": - version "6.2.3" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.3.tgz#76d5d6d44da5c8d406620a4c285d280ae310bdb4" - integrity sha512-TNAodj5yNzrrZ/VxP+H5HiYaZep0H3GU0O7PaF+fhDrt8FPrnkei9Aal/txsN/1P7V3CPiThG0tIvpPDYUsyAA== + version "6.2.8" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" + integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== dependencies: "@octokit/endpoint" "^7.0.0" "@octokit/request-error" "^3.0.0" @@ -2522,11 +2153,11 @@ "@octokit/openapi-types" "^14.0.0" "@octokit/types@^9.0.0": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.1.2.tgz#1a8d35b1f4a3d2ad386e223f249dd5f7506979c1" - integrity sha512-LPbJIuu1WNoRHbN4UMysEdlissRFpTCWyoKT7kHPufI8T+XX33/qilfMWJo3mCOjNIKu0+43oSQPf+HJa0+TTQ== + version "9.3.2" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" + integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA== dependencies: - "@octokit/openapi-types" "^17.0.0" + "@octokit/openapi-types" "^18.0.0" "@parcel/watcher@2.0.4": version "2.0.4" @@ -2536,14 +2167,14 @@ node-addon-api "^3.2.1" node-gyp-build "^4.3.0" -"@peculiar/asn1-schema@^2.3.6": - version "2.3.6" - resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.6.tgz#3dd3c2ade7f702a9a94dfb395c192f5fa5d6b922" - integrity sha512-izNRxPoaeJeg/AyH8hER6s+H7p4itk+03QCa4sbxI3lNdseQYCuxzgsuNK8bTXChtLTjpJz6NmXKA73qLa3rCA== +"@peculiar/asn1-schema@^2.3.8": + version "2.3.8" + resolved "https://registry.yarnpkg.com/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz#04b38832a814e25731232dd5be883460a156da3b" + integrity sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA== dependencies: asn1js "^3.0.5" - pvtsutils "^1.3.2" - tslib "^2.4.0" + pvtsutils "^1.3.5" + tslib "^2.6.2" "@peculiar/json-schema@^1.1.12": version "1.1.12" @@ -2553,27 +2184,20 @@ tslib "^2.0.0" "@peculiar/webcrypto@^1.0.22": - version "1.4.3" - resolved "https://registry.yarnpkg.com/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz#078b3e8f598e847b78683dc3ba65feb5029b93a7" - integrity sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@peculiar/webcrypto/-/webcrypto-1.4.5.tgz#424bed6b0d133b772f5cbffd143d0468a90f40a0" + integrity sha512-oDk93QCDGdxFRM8382Zdminzs44dg3M2+E5Np+JWkpqLDyJC9DviMh8F8mEJkYuUcUOGA5jHO5AJJ10MFWdbZw== dependencies: - "@peculiar/asn1-schema" "^2.3.6" + "@peculiar/asn1-schema" "^2.3.8" "@peculiar/json-schema" "^1.1.12" - pvtsutils "^1.3.2" - tslib "^2.5.0" - webcrypto-core "^1.7.7" + pvtsutils "^1.3.5" + tslib "^2.6.2" + webcrypto-core "^1.7.8" -"@pkgr/utils@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.3.1.tgz#0a9b06ffddee364d6642b3cd562ca76f55b34a03" - integrity sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw== - dependencies: - cross-spawn "^7.0.3" - is-glob "^4.0.3" - open "^8.4.0" - picocolors "^1.0.0" - tiny-glob "^0.2.9" - tslib "^2.4.0" +"@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" @@ -2657,13 +2281,13 @@ dependencies: serve-static "^1.13.1" -"@react-native-community/cli-doctor@^10.2.2": - version "10.2.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-10.2.2.tgz#b1893604fa9fc8971064e7c00042350f96868bfe" - integrity sha512-49Ep2aQOF0PkbAR/TcyMjOm9XwBa8VQr+/Zzf4SJeYwiYLCT1NZRAVAVjYRXl0xqvq5S5mAGZZShS4AQl4WsZw== +"@react-native-community/cli-doctor@^10.2.5": + version "10.2.5" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-10.2.5.tgz#e5e28c66c2373f05a94b296a8ec637f8df736707" + integrity sha512-1YbzXvsldBmSw1MmBsXB74bKiHXKNCjlb2ByLgkfTiarpSvETYam3g5vex0N+qc0Cdkzkq+8NznE744LFhnUpw== dependencies: "@react-native-community/cli-config" "^10.1.1" - "@react-native-community/cli-platform-ios" "^10.2.1" + "@react-native-community/cli-platform-ios" "^10.2.5" "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" command-exists "^1.2.8" @@ -2701,10 +2325,10 @@ glob "^7.1.3" logkitty "^0.7.1" -"@react-native-community/cli-platform-ios@10.2.1", "@react-native-community/cli-platform-ios@^10.2.1": - version "10.2.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.2.1.tgz#2e6bd2cb6d48cbb8720d7b7265bb1bab80745f72" - integrity sha512-hz4zu4Y6eyj7D0lnZx8Mf2c2si8y+zh/zUTgCTaPPLzQD8jSZNNBtUUiA1cARm2razpe8marCZ1QbTMAGbf3mg== +"@react-native-community/cli-platform-ios@10.2.5", "@react-native-community/cli-platform-ios@^10.2.5": + version "10.2.5" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.2.5.tgz#7888c74b83099885bf9e6d52170c6e663ad971ee" + integrity sha512-hq+FZZuSBK9z82GLQfzdNDl8vbFx5UlwCLFCuTtNCROgBoapFtVZQKRP2QBftYNrQZ0dLAb01gkwxagHsQCFyg== dependencies: "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" @@ -2713,21 +2337,21 @@ glob "^7.1.3" ora "^5.4.1" -"@react-native-community/cli-plugin-metro@^10.2.2": - version "10.2.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.2.2.tgz#766914e3c8007dfe52b253544c4f6cd8549919ac" - integrity sha512-sTGjZlD3OGqbF9v1ajwUIXhGmjw9NyJ/14Lo0sg7xH8Pv4qUd5ZvQ6+DWYrQn3IKFUMfGFWYyL81ovLuPylrpw== +"@react-native-community/cli-plugin-metro@^10.2.3": + version "10.2.3" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.2.3.tgz#419e0155a50951c3329818fba51cb5021a7294f1" + integrity sha512-jHi2oDuTePmW4NEyVT8JEGNlIYcnFXCSV2ZMp4rnDrUk4TzzyvS3IMvDlESEmG8Kry8rvP0KSUx/hTpy37Sbkw== dependencies: "@react-native-community/cli-server-api" "^10.1.1" "@react-native-community/cli-tools" "^10.1.1" chalk "^4.1.2" execa "^1.0.0" - metro "0.73.9" - metro-config "0.73.9" - metro-core "0.73.9" - metro-react-native-babel-transformer "0.73.9" - metro-resolver "0.73.9" - metro-runtime "0.73.9" + metro "0.73.10" + metro-config "0.73.10" + metro-core "0.73.10" + metro-react-native-babel-transformer "0.73.10" + metro-resolver "0.73.10" + metro-runtime "0.73.10" readline "^1.3.0" "@react-native-community/cli-server-api@^10.1.1": @@ -2767,17 +2391,17 @@ dependencies: joi "^17.2.1" -"@react-native-community/cli@10.2.2": - version "10.2.2" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-10.2.2.tgz#3fa438ba7f19f83e07bc337765fc1cabdcf2cac2" - integrity sha512-aZVcVIqj+OG6CrliR/Yn8wHxrvyzbFBY9cj7n0MvRw/P54QUru2nNqUTSSbqv0Qaa297yHJbe6kFDojDMSTM8Q== +"@react-native-community/cli@10.2.6": + version "10.2.6" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-10.2.6.tgz#fe443276eb5eb6004960b82e34c512e017e4b575" + integrity sha512-RiOogGmrMnL2a1ICOBM/XvG4s46AzJoZt4B/aydrpp3xCiuPFBUVWpYtWWcdPmQqilk37c6qfNu9/38g9dW9Bw== dependencies: "@react-native-community/cli-clean" "^10.1.1" "@react-native-community/cli-config" "^10.1.1" "@react-native-community/cli-debugger-ui" "^10.0.0" - "@react-native-community/cli-doctor" "^10.2.2" + "@react-native-community/cli-doctor" "^10.2.5" "@react-native-community/cli-hermes" "^10.2.0" - "@react-native-community/cli-plugin-metro" "^10.2.2" + "@react-native-community/cli-plugin-metro" "^10.2.3" "@react-native-community/cli-server-api" "^10.1.1" "@react-native-community/cli-tools" "^10.1.1" "@react-native-community/cli-types" "^10.0.0" @@ -2795,7 +2419,7 @@ resolved "https://registry.yarnpkg.com/@react-native/assets/-/assets-1.0.0.tgz#c6f9bf63d274bafc8e970628de24986b30a55c8e" integrity sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ== -"@react-native/normalize-color@*", "@react-native/normalize-color@2.1.0": +"@react-native/normalize-color@2.1.0", "@react-native/normalize-color@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.1.0.tgz#939b87a9849e81687d3640c5efa2a486ac266f91" integrity sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA== @@ -2805,10 +2429,49 @@ resolved "https://registry.yarnpkg.com/@react-native/polyfills/-/polyfills-2.0.0.tgz#4c40b74655c83982c8cf47530ee7dc13d957b6aa" integrity sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ== -"@sideway/address@^4.1.3": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" - integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== +"@sd-jwt/core@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@sd-jwt/core/-/core-0.2.0.tgz#e06736ff4920570660fce4e040fe40e900c7fcfa" + integrity sha512-KxsJm/NAvKkbqOXaIq7Pndn70++bm8QNzzBh1KOwhlRub7LVrqeEkie/wrI/sAH+S+5exG0HTbY95F86nHiq7Q== + dependencies: + "@sd-jwt/decode" "0.2.0" + "@sd-jwt/present" "0.2.0" + "@sd-jwt/types" "0.2.0" + "@sd-jwt/utils" "0.2.0" + +"@sd-jwt/decode@0.2.0", "@sd-jwt/decode@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@sd-jwt/decode/-/decode-0.2.0.tgz#44211418fd0884a160f8223feedfe04ae52398c4" + integrity sha512-nmiZN3SQ4ApapEu+rS1h/YAkDIq3exgN7swSCsEkrxSEwnBSbXtISIY/sv+EmwnehF1rcKbivHfHNxOWYtlxvg== + dependencies: + "@sd-jwt/types" "0.2.0" + "@sd-jwt/utils" "0.2.0" + +"@sd-jwt/present@0.2.0", "@sd-jwt/present@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@sd-jwt/present/-/present-0.2.0.tgz#01ecbd09dd21287be892b36d754a79c8629387f2" + integrity sha512-6xDBiB+UqCwW8k7O7OUJ7BgC/8zcO+AD5ZX1k4I6yjDM9vscgPulSVxT/yUH+Aov3cZ/BKvfKC0qDEZkHmP/kg== + dependencies: + "@sd-jwt/types" "0.2.0" + "@sd-jwt/utils" "0.2.0" + +"@sd-jwt/types@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@sd-jwt/types/-/types-0.2.0.tgz#3cb50392e1b76ce69453f403c71c937a6e202352" + integrity sha512-16WFRcL/maG0/JxN9UCSx07/vJ2SDbGscv9gDLmFLgJzhJcGPer41XfI6aDfVARYP430wHFixChfY/n7qC1L/Q== + +"@sd-jwt/utils@0.2.0", "@sd-jwt/utils@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@sd-jwt/utils/-/utils-0.2.0.tgz#ef52b744116e874f72ec01978f0631ad5a131eb7" + integrity sha512-oHCfRYVHCb5RNwdq3eHAt7P9d7TsEaSM1TTux+xl1I9PeQGLtZETnto9Gchtzn8FlTrMdVsLlcuAcK6Viwj1Qw== + dependencies: + "@sd-jwt/types" "0.2.0" + buffer "*" + +"@sideway/address@^4.1.5": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5" + integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q== dependencies: "@hapi/hoek" "^9.0.0" @@ -2822,74 +2485,145 @@ resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== -"@sigstore/protobuf-specs@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz#957cb64ea2f5ce527cc9cf02a096baeb0d2b99b4" - integrity sha512-a31EnjuIDSX8IXBUib3cYLDRlPMU36AWX4xS8ysLaNu4ZzUesDiPt83pgrW2X1YLMe5L2HbDyaKK5BrL4cNKaQ== +"@sigstore/bundle@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" + integrity sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog== + dependencies: + "@sigstore/protobuf-specs" "^0.2.0" + +"@sigstore/protobuf-specs@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" + integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== + +"@sigstore/sign@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-1.0.0.tgz#6b08ebc2f6c92aa5acb07a49784cb6738796f7b4" + integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== + dependencies: + "@sigstore/bundle" "^1.1.0" + "@sigstore/protobuf-specs" "^0.2.0" + make-fetch-happen "^11.0.1" -"@sinclair/typebox@^0.25.16": - version "0.25.24" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.24.tgz#8c7688559979f7079aacaf31aa881c3aa410b718" - integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sigstore/tuf@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" + integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== + dependencies: + "@sigstore/protobuf-specs" "^0.2.0" + tuf-js "^1.1.7" "@sinclair/typebox@^0.27.8": version "0.27.8" resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== -"@sinonjs/commons@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" - integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== +"@sinonjs/commons@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" + integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== dependencies: type-detect "4.0.8" "@sinonjs/fake-timers@^10.0.2": - version "10.0.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" - integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== dependencies: - "@sinonjs/commons" "^2.0.0" + "@sinonjs/commons" "^3.0.0" "@sovpro/delimited-stream@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@sovpro/delimited-stream/-/delimited-stream-1.1.0.tgz#4334bba7ee241036e580fdd99c019377630d26b4" integrity sha512-kQpk267uxB19X3X2T1mvNMjyvIEonpNSHrMlK5ZaBU6aZxw7wPbpgKJOjHN3+/GPVpXgAV9soVT2oyHpLkLtyw== -"@sphereon/openid4vci-client@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@sphereon/openid4vci-client/-/openid4vci-client-0.4.0.tgz#f48c2bb42041b9eab13669de23ba917785c83b24" - integrity sha512-N9ytyV3DHAjBjd67jMowmBMmD9/4Sxkehsrpd1I9Hxg5TO1K+puUPsPXj8Zh4heIWSzT5xBsGTSqXdF0LlrDwQ== +"@sphereon/did-auth-siop@0.6.0-unstable.3": + version "0.6.0-unstable.3" + resolved "https://registry.yarnpkg.com/@sphereon/did-auth-siop/-/did-auth-siop-0.6.0-unstable.3.tgz#705dfd17210846b382f3116a92d9d2e7242b93e3" + integrity sha512-0d2A3EPsywkHw5zfR3JWu0sjy3FACtpAlnWabol/5C8/C1Ys1hCk+X995aADqs8DRtdVFX8TFJkCMshp7pLyEg== dependencies: - "@sphereon/ssi-types" "^0.9.0" - cross-fetch "^3.1.5" - debug "^4.3.4" + "@astronautlabs/jsonpath" "^1.1.2" + "@sphereon/did-uni-client" "^0.6.1" + "@sphereon/pex" "^3.0.1" + "@sphereon/pex-models" "^2.1.5" + "@sphereon/ssi-types" "0.18.1" + "@sphereon/wellknown-dids-client" "^0.1.3" + cross-fetch "^4.0.0" + did-jwt "6.11.6" + did-resolver "^4.1.0" + events "^3.3.0" + language-tags "^1.0.9" + multiformats "^11.0.2" + qs "^6.11.2" + sha.js "^2.4.11" uint8arrays "^3.1.1" + uuid "^9.0.0" -"@sphereon/pex-models@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@sphereon/pex-models/-/pex-models-2.1.2.tgz#e1a0ce16ccc6b32128fc8c2da79d65fc35f6d10f" - integrity sha512-Ec1qZl8tuPd+s6E+ZM7v+HkGkSOjGDMLNN1kqaxAfWpITBYtTLb+d5YvwjvBZ1P2upZ7zwNER97FfW5n/30y2w== +"@sphereon/did-uni-client@^0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@sphereon/did-uni-client/-/did-uni-client-0.6.1.tgz#5fe7fa2b87c22f939c95d388b6fcf9e6e93c70a8" + integrity sha512-ryIPq9fAp8UuaN0ZQ16Gong5n5SX8G+SjNQ3x3Uy/pmd6syxh97kkmrfbna7a8dTmbP8YdNtgPLpcNbhLPMClQ== + dependencies: + cross-fetch "^4.0.0" + did-resolver "^4.1.0" -"@sphereon/pex@^2.2.2": - version "2.2.2" - resolved "https://registry.yarnpkg.com/@sphereon/pex/-/pex-2.2.2.tgz#3df9ed75281b46f0899256774060ed2ff982fade" - integrity sha512-NkR8iDTC2PSnYsOHlG2M2iOpFTTbzszs2/pL3iK3Dlv9QYLqX7NtPAlmeSwaoVP1NB1ewcs6U1DtemQAD+90yQ== +"@sphereon/oid4vci-client@0.8.2-next.46": + version "0.8.2-next.46" + resolved "https://registry.yarnpkg.com/@sphereon/oid4vci-client/-/oid4vci-client-0.8.2-next.46.tgz#0f53dc607a0ee17cf0bedb4e7ca91fe525a4c44e" + integrity sha512-oYY5RbFEpyYMU+EHriGOb/noFpFWhpgimr6drdAI7l5hMIQTs3iz8kUk9CSCJEOYq0n9VtWzd9jE3qDVjMgepA== + dependencies: + "@sphereon/oid4vci-common" "0.8.2-next.46+e3c1601" + "@sphereon/ssi-types" "^0.18.1" + cross-fetch "^3.1.8" + debug "^4.3.4" + +"@sphereon/oid4vci-common@0.8.2-next.46", "@sphereon/oid4vci-common@0.8.2-next.46+e3c1601": + version "0.8.2-next.46" + resolved "https://registry.yarnpkg.com/@sphereon/oid4vci-common/-/oid4vci-common-0.8.2-next.46.tgz#5def7c2aa68b19a7f52691668580755573db28e1" + integrity sha512-mt21K/bukcwdqB3kfKGFj3597rO3WnxW7Dietd0YE87C8yt7WyapXdogP7p18GJ40zu6+OealIeNnEMxCBQPXA== + dependencies: + "@sphereon/ssi-types" "^0.18.1" + cross-fetch "^3.1.8" + jwt-decode "^3.1.2" + +"@sphereon/oid4vci-issuer@0.8.2-next.46": + version "0.8.2-next.46" + resolved "https://registry.yarnpkg.com/@sphereon/oid4vci-issuer/-/oid4vci-issuer-0.8.2-next.46.tgz#3886b5e1b9203de8b6d7c5b435562f888177a87b" + integrity sha512-9/VG9QulFEDpNvEe8X7YCcc2FwUDpR2e7geWdWY9SyOexYtjxTcoyfHb9bPgIg5TuFbA1nADTD804935suhKtw== + dependencies: + "@sphereon/oid4vci-common" "0.8.2-next.46+e3c1601" + "@sphereon/ssi-types" "^0.18.1" + uuid "^9.0.0" + +"@sphereon/pex-models@^2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@sphereon/pex-models/-/pex-models-2.1.5.tgz#ba4474a3783081392b72403c4c8ee6da3d2e5585" + integrity sha512-7THexvdYUK/Dh8olBB46ErT9q/RnecnMdb5r2iwZ6be0Dt4vQLAUN7QU80H0HZBok4jRTb8ydt12x0raBSTHOg== + +"@sphereon/pex@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sphereon/pex/-/pex-3.0.1.tgz#e7d9d36c7c921ab97190a735c67e0a2632432e3b" + integrity sha512-rj+GhFfV5JLyo7dTIA3htWlrT+f6tayF9JRAGxdsIYBfYictLi9BirQ++JRBXsiq7T5zMnfermz4RGi3cvt13Q== dependencies: "@astronautlabs/jsonpath" "^1.1.2" - "@sphereon/pex-models" "^2.1.2" - "@sphereon/ssi-types" "^0.17.5" + "@sd-jwt/decode" "^0.2.0" + "@sd-jwt/present" "^0.2.0" + "@sd-jwt/utils" "^0.2.0" + "@sphereon/pex-models" "^2.1.5" + "@sphereon/ssi-types" "0.18.1" ajv "^8.12.0" ajv-formats "^2.1.1" jwt-decode "^3.1.2" - nanoid "^3.3.6" - string.prototype.matchall "^4.0.8" + nanoid "^3.3.7" + string.prototype.matchall "^4.0.10" -"@sphereon/ssi-types@^0.17.5": - version "0.17.5" - resolved "https://registry.yarnpkg.com/@sphereon/ssi-types/-/ssi-types-0.17.5.tgz#7b4de0326e7c2993ab816caeef6deaea41a5f65f" - integrity sha512-hoQOkeOtshvIzNAG+HTqcKxeGssLVfwX7oILHJgs6VMb1GhR6QlqjMAxflDxZ/8Aq2R0I6fEPWmf73zAXY2X2Q== +"@sphereon/ssi-types@0.18.1", "@sphereon/ssi-types@^0.18.1": + version "0.18.1" + resolved "https://registry.yarnpkg.com/@sphereon/ssi-types/-/ssi-types-0.18.1.tgz#c00e4939149f4e441fae56af860735886a4c33a5" + integrity sha512-uM0gb1woyc0R+p+qh8tVDi15ZWmpzo9BP0iBp/yRkJar7gAfgwox/yvtEToaH9jROKnDCwL3DDQCDeNucpMkwg== dependencies: + "@sd-jwt/decode" "^0.2.0" jwt-decode "^3.1.2" "@sphereon/ssi-types@^0.9.0": @@ -2899,6 +2633,15 @@ dependencies: jwt-decode "^3.1.2" +"@sphereon/wellknown-dids-client@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@sphereon/wellknown-dids-client/-/wellknown-dids-client-0.1.3.tgz#4711599ed732903e9f45fe051660f925c9b508a4" + integrity sha512-TAT24L3RoXD8ocrkTcsz7HuJmgjNjdoV6IXP1p3DdaI/GqkynytXE3J1+F7vUFMRYwY5nW2RaXSgDQhrFJemaA== + dependencies: + "@sphereon/ssi-types" "^0.9.0" + cross-fetch "^3.1.5" + jwt-decode "^3.1.2" + "@stablelib/aead@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" @@ -3043,6 +2786,11 @@ "@stablelib/wipe" "^1.0.1" "@stablelib/xchacha20" "^1.0.1" +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" @@ -3064,27 +2812,27 @@ 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" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== "@tufjs/canonical-json@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31" integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== -"@tufjs/models@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.3.tgz#e6cb8a86834da7459a7c836cd892dee56b4bab44" - integrity sha512-mkFEqqRisi13DmR5pX4x+Zk97EiU8djTtpNW1GeuX410y/raAsq/T3ZCjwoRIZ8/cIBfW0olK/sywlAiWevDVw== +"@tufjs/models@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" + integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== dependencies: "@tufjs/canonical-json" "1.0.0" - minimatch "^7.4.6" + minimatch "^9.0.0" "@types/babel__core@^7.1.14": - version "7.20.0" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" - integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== dependencies: "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" @@ -3093,35 +2841,28 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.4.tgz#1f20ce4c5b1990b37900b63f050182d28c2439b7" - integrity sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg== + version "7.6.8" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.8.tgz#f836c61f48b1346e7d2b0d93c6dacc5b9535d3ab" + integrity sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw== 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" - integrity sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.18.3" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.18.3.tgz#dfc508a85781e5698d5b33443416b6268c4b3e8d" - integrity sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w== - dependencies: - "@babel/types" "^7.3.0" - -"@types/bn.js@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.5.tgz#7b7502be0aa80cc4ef22978846b983edaafcd4dd" + integrity sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ== dependencies: - "@types/node" "*" + "@babel/types" "^7.20.7" -"@types/bn.js@^5.1.5": +"@types/bn.js@^5.1.0", "@types/bn.js@^5.1.5": version "5.1.5" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.5.tgz#2e0dacdcce2c0f16b905d20ff87aedbc6f7b4bf0" integrity sha512-V46N0zwKRF5Q00AZ6hWtN0T8gGmDUaUzLWQvHFo5yThtVwK/VCenFY3wXVbOvNfajEpsTfQM4IN9k/d6gUVX3A== @@ -3129,58 +2870,59 @@ "@types/node" "*" "@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== dependencies: "@types/connect" "*" "@types/node" "*" "@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/cors@^2.8.10": - version "2.8.13" - resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94" - integrity sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA== + version "2.8.17" + resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.17.tgz#5d718a5e494a8166f569d986794e49c48b216b2b" + integrity sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA== dependencies: "@types/node" "*" "@types/eslint@^8.21.2": - version "8.37.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.37.0.tgz#29cebc6c2a3ac7fea7113207bf5a828fdf4d7ef1" - integrity sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ== + version "8.56.2" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.56.2.tgz#1c72a9b794aa26a8b94ad26d5b9aa51c8a6384bb" + integrity sha512-uQDwm1wFHmbBbCZCqAlq6Do9LYwByNZHWzXppSnay9SuwJ+VRbjkbLABer54kcPnMSlG6Fdiy2yaFXm/z9Z5gw== dependencies: "@types/estree" "*" "@types/json-schema" "*" "@types/estree@*": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/events@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" - integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.3.tgz#a8ef894305af28d1fc6d2dfdfc98e899591ea529" + integrity sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g== "@types/express-serve-static-core@^4.17.33": - version "4.17.33" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz#de35d30a9d637dc1450ad18dd583d75d5733d543" - integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA== + version "4.17.42" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.42.tgz#2a276952acc73d1b8dc63fd4210647abbc553a71" + integrity sha512-ckM3jm2bf/MfB3+spLPWYPUH573plBFwpOhqQ2WottxYV85j1HQFlxmnTq57X1yHY9awZPig06hL/cLMgNWHIQ== dependencies: "@types/node" "*" "@types/qs" "*" "@types/range-parser" "*" + "@types/send" "*" -"@types/express@*", "@types/express@^4.17.13", "@types/express@^4.17.15": - version "4.17.18" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.18.tgz#efabf5c4495c1880df1bdffee604b143b29c4a95" - integrity sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ== +"@types/express@*", "@types/express@^4.17.13", "@types/express@^4.17.15", "@types/express@^4.17.21": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^4.17.33" @@ -3188,41 +2930,46 @@ "@types/serve-static" "*" "@types/figlet@^1.5.4": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@types/figlet/-/figlet-1.5.5.tgz#da93169178f0187da288c313ab98ab02fb1e8b8c" - integrity sha512-0sMBeFoqdGgdXoR/hgKYSWMpFufSpToosNsI2VgmkPqZJgeEXsXNu2hGr0FN401dBro2tNO5y2D6uw3UxVaxbg== + version "1.5.8" + resolved "https://registry.yarnpkg.com/@types/figlet/-/figlet-1.5.8.tgz#96b8186c7e2a388b4f8d09ee3276cba2af88bb0b" + integrity sha512-G22AUvy4Tl95XLE7jmUM8s8mKcoz+Hr+Xm9W90gJsppJq9f9tHvOGkrpn4gRX0q/cLtBdNkWtWCKDg2UDZoZvQ== "@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" - integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== dependencies: "@types/node" "*" +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + "@types/inquirer@^8.2.6": - version "8.2.6" - resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.2.6.tgz#abd41a5fb689c7f1acb12933d787d4262a02a0ab" - integrity sha512-3uT88kxg8lNzY8ay2ZjP44DKcRaTGztqeIvN2zHvhzIBH/uAPaL75aBtdNRKbA7xXoMbBt5kX0M00VKAnfOYlA== + version "8.2.10" + resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-8.2.10.tgz#9444dce2d764c35bc5bb4d742598aaa4acb6561b" + integrity sha512-IdD5NmHyVjWM8SHWo/kPBgtzXatwPkfwzyP3fN1jF2g9BWt5WO+8hL2F4o2GKIYsU40PpqeevuUWvkS/roXJkA== dependencies: "@types/through" "*" rxjs "^7.2.0" "@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" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@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" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== 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" - integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" @@ -3235,9 +2982,9 @@ pretty-format "^29.0.0" "@types/json-schema@*", "@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" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" @@ -3255,14 +3002,19 @@ integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== "@types/luxon@^3.2.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.3.0.tgz#a61043a62c0a72696c73a0a305c544c96501e006" - integrity sha512-uKRI5QORDnrGFYgcdAVnHvEIvEZ8noTpP/Bg+HeUzZghwinDlIS87DEenV5r1YoOF9G4x600YsUXLWZ19rmTmg== + version "3.4.2" + resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-3.4.2.tgz#e4fc7214a420173cea47739c33cdf10874694db7" + integrity sha512-TifLZlFudklWlMBfhubvgqTXRzLDI5pCbGa4P8a3wPyUQSW+1xQ5eDsreP9DWHX3tjq1ke96uYG/nwundroWcA== "@types/mime@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" - integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/minimatch@^3.0.3": version "3.0.5" @@ -3270,14 +3022,14 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" + integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/multer@^1.4.7": - version "1.4.7" - resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.7.tgz#89cf03547c28c7bbcc726f029e2a76a7232cc79e" - integrity sha512-/SNsDidUFCvqqcWDwxv2feww/yqhNeTRL5CVoL3jU4Goc4kKEL10T7Eye65ZqPNi4HRx8sAEX59pV1aEH7drNA== + version "1.4.11" + resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.11.tgz#c70792670513b4af1159a2b60bf48cc932af55c5" + integrity sha512-svK240gr6LVWvv3YGyhLlA+6LRRWA4mnGIU7RcNmgjBYFl6665wcXrRfxGp5tEPVHUNm5FMcmq7too9bxCwX/w== dependencies: "@types/express" "*" @@ -3289,90 +3041,99 @@ undici-types "~5.26.4" "@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/object-inspect@^1.8.0": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@types/object-inspect/-/object-inspect-1.8.1.tgz#7c08197ad05cc0e513f529b1f3919cc99f720e1f" - integrity sha512-0JTdf3CGV0oWzE6Wa40Ayv2e2GhpP3pEJMcrlM74vBSJPuuNkVwfDnl0SZxyFCXETcB4oKA/MpTVfuYSMOelBg== + version "1.8.4" + resolved "https://registry.yarnpkg.com/@types/object-inspect/-/object-inspect-1.8.4.tgz#470c8203ed227fe883004f89427e5317d9aa3564" + integrity sha512-2yh72JxmDney1h7LQvkyO8p8FOmNMQXGs8HjuXS3SXvE/dLydLLjBqKCdHqcTUo66CQVHfn7yFR680bvi9jlVw== "@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + version "6.9.11" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.11.tgz#208d8a30bc507bd82e03ada29e4732ea46a6bbda" + integrity sha512-oGk0gmhnEJK4Yyk+oI7EfXsLayXatCWPHary1MtcmbAifkobT9cM9yutG/hZKIseOU0MqbIwQ/u2nn/Gb+ltuQ== "@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/ref-array-di@^1.2.6": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@types/ref-array-di/-/ref-array-di-1.2.6.tgz#c680ff3c9b743939d5fb4992f2bb26bde334aacf" - integrity sha512-v1NeuLBJaHsqKpPTWr8gwH8UIvzrlbdJ/9aD91CZkczDD+DBM64woMIlYiFj/SpQJ/9dWhuZXAu7QEYM10dQwQ== + version "1.2.8" + resolved "https://registry.yarnpkg.com/@types/ref-array-di/-/ref-array-di-1.2.8.tgz#2b44567b8eaae72c59db68a482f5d26297e955be" + integrity sha512-+re5xrhRXDUR3sicMvN9N3C+6mklq5kd7FkN3ciRWio3BAvUDh2OEUTTG+619r10dqc6de25LIDtgpHtXCKGbA== dependencies: "@types/ref-napi" "*" "@types/ref-napi@*": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/ref-napi/-/ref-napi-3.0.7.tgz#20adc93a7a2f9f992dfb17409fd748e6f4bf403d" - integrity sha512-CzPwr36VkezSpaJGdQX/UrczMSDsDgsWQQFEfQkS799Ft7n/s183a53lsql7RwVq+Ik4yLEgI84pRnLC0XXRlA== + version "3.0.12" + resolved "https://registry.yarnpkg.com/@types/ref-napi/-/ref-napi-3.0.12.tgz#2ddde995ecf769f1e5da01604e468348949c72c3" + integrity sha512-UZPKghRaLlWx2lPAphpdtYe62TbGBaPeqUM6gF1vI6FPRIu/Tff/WMAzpJRFU3jJIiD8HiXpVt2RjcFHtA6YRg== dependencies: "@types/node" "*" "@types/ref-struct-di@^1.1.10": - version "1.1.10" - resolved "https://registry.yarnpkg.com/@types/ref-struct-di/-/ref-struct-di-1.1.10.tgz#4ea45151a4561894c654a250763f71199216bb9b" - integrity sha512-ZiMgtvSMow5b8DPyLo4Wf0ttx9qxUcCtqyW1Y1rCUZxiyqYE6RJ8One7sOaNOqkWAU6aqYCHM2IAbiZYn14aeg== + version "1.1.12" + resolved "https://registry.yarnpkg.com/@types/ref-struct-di/-/ref-struct-di-1.1.12.tgz#5d9167488692816754c6d2b9064d9b0313609d59" + integrity sha512-R2RNkGIROGoJTbXYTXrsXybnsQD4iAy26ih/G6HCeCB9luWFQKkr537XGz0uGJ1kH8y8RMkdbQmD/wBulrOPHw== dependencies: "@types/ref-napi" "*" "@types/semver@^7.3.12": - version "7.3.13" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" - integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" "@types/serve-static@*": - version "1.15.1" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" - integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== + version "1.15.5" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== dependencies: + "@types/http-errors" "*" "@types/mime" "*" "@types/node" "*" "@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" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== "@types/through@*": - version "0.0.30" - resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895" - integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg== + version "0.0.33" + resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.33.tgz#14ebf599320e1c7851e7d598149af183c6b9ea56" + integrity sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ== dependencies: "@types/node" "*" "@types/uuid@^9.0.1": - version "9.0.6" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.6.tgz#c91ae743d8344a54b2b0c691195f5ff5265f6dfb" - integrity sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew== + version "9.0.8" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.8.tgz#7545ba4fc3c003d6c756f651f3bf163d8f0f29ba" + integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== -"@types/validator@^13.7.10": - version "13.7.15" - resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.15.tgz#408c99d1b5f0eecc78109c11f896f72d1f026a10" - integrity sha512-yeinDVQunb03AEP8luErFcyf/7Lf7AzKCD0NXfgVoGCCQDNpZET8Jgq74oBgqKld3hafLbfzt/3inUdQvaFeXQ== +"@types/validator@^13.11.8": + version "13.11.8" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.8.tgz#bb1162ec0fe6f87c95ca812f15b996fcc5e1e2dc" + integrity sha512-c/hzNDBh7eRF+KbCf+OoZxKbnkpaK/cKp9iLQWqB7muXtM+MtL9SUUH8vCFcLn6dH1Qm05jiexK0ofWY7TfOhQ== "@types/varint@^6.0.0": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@types/varint/-/varint-6.0.1.tgz#018d424627c7951d370d73816e97e143dc99523b" - integrity sha512-fQdOiZpDMBvaEdl12P1x7xlTPRAtd7qUUtVaWgkCy8DC//wCv19nqFFtrnR3y/ac6VFY0UUvYuQqfKzZTSE26w== + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/varint/-/varint-6.0.3.tgz#e00b00f94d497d7cbf0e9f391cbc7e8443ae2174" + integrity sha512-DHukoGWdJ2aYkveZJTB2rN2lp6m7APzVsoJQ7j/qy1fQxyamJTPD5xQzCMoJ2Qtgn0mE3wWeNOpbTyBFvF+dyA== dependencies: "@types/node" "*" @@ -3384,115 +3145,120 @@ "@types/node" "*" "@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^15.0.0": - version "15.0.15" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.15.tgz#e609a2b1ef9e05d90489c2f5f45bbfb2be092158" - integrity sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg== + version "15.0.19" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.19.tgz#328fb89e46109ecbdb70c295d96ff2f46dfd01b9" + integrity sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA== dependencies: "@types/yargs-parser" "*" "@types/yargs@^16.0.0": - version "16.0.5" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" - integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== + version "16.0.9" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.9.tgz#ba506215e45f7707e6cbcaf386981155b7ab956e" + integrity sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.24" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.24.tgz#b3ef8d50ad4aa6aecf6ddc97c580a00f5aa11902" - integrity sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw== + version "17.0.32" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== dependencies: "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.48.1": - version "5.59.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.1.tgz#9b09ee1541bff1d2cebdcb87e7ce4a4003acde08" - integrity sha512-AVi0uazY5quFB9hlp2Xv+ogpfpk77xzsgsIEWyVS7uK/c7MZ5tw7ZPbapa0SbfkqE0fsAMkz5UwtgMLVk2BQAg== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== dependencies: "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.1" - "@typescript-eslint/type-utils" "5.59.1" - "@typescript-eslint/utils" "5.59.1" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" - grapheme-splitter "^1.0.4" + graphemer "^1.4.0" ignore "^5.2.0" natural-compare-lite "^1.4.0" semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/parser@^5.48.1": - version "5.59.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.59.1.tgz#73c2c12127c5c1182d2e5b71a8fa2a85d215cbb4" - integrity sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== dependencies: - "@typescript-eslint/scope-manager" "5.59.1" - "@typescript-eslint/types" "5.59.1" - "@typescript-eslint/typescript-estree" "5.59.1" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.59.1": - version "5.59.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz#8a20222719cebc5198618a5d44113705b51fd7fe" - integrity sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA== +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== dependencies: - "@typescript-eslint/types" "5.59.1" - "@typescript-eslint/visitor-keys" "5.59.1" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/type-utils@5.59.1": - version "5.59.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.59.1.tgz#63981d61684fd24eda2f9f08c0a47ecb000a2111" - integrity sha512-ZMWQ+Oh82jWqWzvM3xU+9y5U7MEMVv6GLioM3R5NJk6uvP47kZ7YvlgSHJ7ERD6bOY7Q4uxWm25c76HKEwIjZw== +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== dependencies: - "@typescript-eslint/typescript-estree" "5.59.1" - "@typescript-eslint/utils" "5.59.1" + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.59.1": - version "5.59.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.59.1.tgz#03f3fedd1c044cb336ebc34cc7855f121991f41d" - integrity sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/typescript-estree@5.59.1": - version "5.59.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz#4aa546d27fd0d477c618f0ca00b483f0ec84c43c" - integrity sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA== +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: - "@typescript-eslint/types" "5.59.1" - "@typescript-eslint/visitor-keys" "5.59.1" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.59.1": - version "5.59.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.59.1.tgz#d89fc758ad23d2157cfae53f0b429bdf15db9473" - integrity sha512-MkTe7FE+K1/GxZkP5gRj3rCztg45bEhsd8HYjczBuYm+qFHP5vtZmjx3B0yUCDotceQ4sHgTyz60Ycl225njmA== +"@typescript-eslint/utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@types/json-schema" "^7.0.9" "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.1" - "@typescript-eslint/types" "5.59.1" - "@typescript-eslint/typescript-estree" "5.59.1" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.59.1": - version "5.59.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz#0d96c36efb6560d7fb8eb85de10442c10d8f6058" - integrity sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA== +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: - "@typescript-eslint/types" "5.59.1" + "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + "@unimodules/core@*": version "7.1.2" resolved "https://registry.yarnpkg.com/@unimodules/core/-/core-7.1.2.tgz#5181b99586476a5d87afd0958f26a04714c47fa1" @@ -3513,10 +3279,10 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -"@yarnpkg/parsers@^3.0.0-rc.18": - version "3.0.0-rc.42" - resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.42.tgz#3814e90a81bb1f9c06cc83c6a009139c55efe94d" - integrity sha512-eW9Mbegmb5bJjwawJM9ghjUjUqciNMhC6L7XrQPF/clXS5bbP66MstsgCT5hy9VlfUh/CfBT+0Wucf531dMjHA== +"@yarnpkg/parsers@3.0.0-rc.46": + version "3.0.0-rc.46" + resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" + integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== dependencies: js-yaml "^3.10.0" tslib "^2.4.0" @@ -3572,14 +3338,14 @@ acorn-jsx@^5.3.2: 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" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + version "8.3.2" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" + integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -acorn@^8.4.1, acorn@^8.5.0, acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.4.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.11.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" + integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== add-stream@^1.0.0: version "1.0.0" @@ -3594,12 +3360,10 @@ agent-base@6, agent-base@^6.0.2: debug "4" agentkeepalive@^4.2.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.3.0.tgz#bb999ff07412653c1803b3ced35e50729830a255" - integrity sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg== + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== dependencies: - debug "^4.1.0" - depd "^2.0.0" humanize-ms "^1.2.1" aggregate-error@^3.0.0: @@ -3617,7 +3381,7 @@ ajv-formats@^2.1.1: dependencies: ajv "^8.0.0" -ajv@^6.10.0, ajv@^6.12.4: +ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -3663,11 +3427,6 @@ ansi-fragments@^0.2.1: slice-ansi "^2.0.0" strip-ansi "^5.0.0" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - ansi-regex@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" @@ -3678,6 +3437,11 @@ ansi-regex@^5.0.0, ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -3697,6 +3461,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + anymatch@^3.0.3: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -3715,11 +3484,6 @@ append-field@^1.0.0: resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== -aproba@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - "aproba@^1.0.3 || ^2.0.0", aproba@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" @@ -3742,20 +3506,9 @@ are-we-there-yet@^3.0.0: readable-stream "^3.6.0" are-we-there-yet@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-4.0.0.tgz#3ff397dc14f08b52dd8b2a64d3cee154ab8760d2" - integrity sha512-nSXlV+u3vtVjRgihdTzbfWYzxPWGo424zPgQbHD0ZqIla3jqYAewDcvee0Ua2hjS5IfTAmjGlx1Jf0PKwjZDEw== - dependencies: - delegates "^1.0.0" - readable-stream "^4.1.0" - -are-we-there-yet@~1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" - integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" + version "4.0.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-4.0.2.tgz#aed25dd0eae514660d49ac2b2366b175c614785a" + integrity sha512-ncSWAawFhKMJDTdoAeOV+jyW1VCMj5QIAwULIBV0SSR7B/RLPPEQiknKcg/RIIZlUQrxELpsxMiTUoAQ4sIUyg== arg@^4.1.0: version "4.1.3" @@ -3774,21 +3527,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== - array-back@^3.0.1, array-back@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" @@ -3822,15 +3560,15 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== -array-includes@^3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" - integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== +array-includes@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" is-string "^1.0.7" array-index@^1.0.0: @@ -3846,29 +3584,35 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== +array.prototype.findlastindex@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" -array.prototype.flat@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" - integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== +array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.flatmap@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" - integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== +array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" arraybuffer.prototype.slice@^1.0.2: @@ -3913,15 +3657,10 @@ asn1js@^3.0.1, asn1js@^3.0.5: pvutils "^1.1.3" tslib "^2.4.0" -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - -ast-types@0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" - integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== +ast-types@0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.15.2.tgz#39ae4809393c4b16df751ee563411423e85fb49d" + integrity sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg== dependencies: tslib "^2.0.1" @@ -3936,16 +3675,16 @@ async-limiter@~1.0.0: integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== async-mutex@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.4.0.tgz#ae8048cd4d04ace94347507504b3cf15e631c25f" - integrity sha512-eJFZ1YhRR8UN8eBLoNzcDPcy/jqjsg6I1AP+KvWQX80BqOSW1oJPJXDylPUEeMr2ZQvHgnQ//Lp6f3RQ1zI7HA== + version "0.4.1" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.4.1.tgz#bccf55b96f2baf8df90ed798cb5544a1f6ee4c2c" + integrity sha512-WfoBo4E/TbCX1G95XTjbWTE3X2XLG0m1Xbv2cwOtuPdyH9CZvnaA5nCt1ucjaKEgW2A5IF71hxrRhr83Je5xjA== dependencies: tslib "^2.4.0" async@^3.2.2, async@^3.2.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== asynckit@^0.4.0: version "0.4.0" @@ -3957,15 +3696,10 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + version "1.0.6" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.6.tgz#ac812d8ce5a6b976d738e1c45f08d0b00bc7d725" + integrity sha512-j1QzY8iPNPG4o4xmO3ptzpRxTciqD3MgEHtifP/YnJpIo58Xu+ne4BejlbkuaLfXn/nz6HFiw29bLpj2PNMdGg== axios@^0.21.2: version "0.21.4" @@ -3975,11 +3709,11 @@ axios@^0.21.2: follow-redirects "^1.14.0" axios@^1.0.0: - version "1.3.6" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.6.tgz#1ace9a9fb994314b5f6327960918406fa92c6646" - integrity sha512-PEcdkk7JcdPiMDkvM4K6ZBRYq9keuVJsToxm2zQIM70Qqo2WHTdJZMXcG9X+RmRp2VPNUQC8W1RAGbgt6b1yMg== + version "1.6.7" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.7.tgz#7b48c2e27c96f9c68a2f8f31e2ab19f59b06b0a7" + integrity sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA== dependencies: - follow-redirects "^1.15.0" + follow-redirects "^1.15.4" form-data "^4.0.0" proxy-from-env "^1.1.0" @@ -4036,29 +3770,29 @@ babel-plugin-jest-hoist@^29.6.3: "@types/babel__core" "^7.1.14" "@types/babel__traverse" "^7.0.6" -babel-plugin-polyfill-corejs2@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.3.tgz#5d1bd3836d0a19e1b84bbf2d9640ccb6f951c122" - integrity sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q== +babel-plugin-polyfill-corejs2@^0.4.8: + version "0.4.8" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.8.tgz#dbcc3c8ca758a290d47c3c6a490d59429b0d2269" + integrity sha512-OtIuQfafSzpo/LhnJaykc0R/MMnuLSSVjVYy9mHArIZ9qTCSZ6TpWCuEKZYVoN//t8HqBNScHrOtCrIK5IaGLg== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.3.3" - semver "^6.1.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.5.0" + semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.6.0.tgz#56ad88237137eade485a71b52f72dbed57c6230a" - integrity sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA== +babel-plugin-polyfill-corejs3@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.9.0.tgz#9eea32349d94556c2ad3ab9b82ebb27d4bf04a81" + integrity sha512-7nZPG1uzK2Ymhy/NbaOWTg3uibM2BmGASS4vHS4szRZAIR8R6GwA/xAujpdrXU5iyklrimWnLWU+BLF9suPTqg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" - core-js-compat "^3.25.1" + "@babel/helper-define-polyfill-provider" "^0.5.0" + core-js-compat "^3.34.0" -babel-plugin-polyfill-regenerator@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.1.tgz#390f91c38d90473592ed43351e801a9d3e0fd747" - integrity sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw== +babel-plugin-polyfill-regenerator@^0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.5.tgz#8b0c8fc6434239e5d7b8a9d1f832bb2b0310f06a" + integrity sha512-OJGYZlhLqBh2DDHeqAxWB1XIvr49CxiJ2gIt61/PU55CQK4Z58OzMqjDe1zwQdQk+rBYsRc+1rJmdajM3gimHg== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.3" + "@babel/helper-define-polyfill-provider" "^0.5.0" babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: version "7.0.0-beta.0" @@ -4165,19 +3899,6 @@ base64url@^3.0.0, base64url@^3.0.1: resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - bech32@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" @@ -4194,19 +3915,19 @@ before-after-hook@^2.2.0: integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== big-integer@^1.6.51: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== bignumber.js@^9.0.0: - version "9.1.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" - integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== bin-links@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-4.0.1.tgz#afeb0549e642f61ff889b58ea2f8dca78fb9d8d3" - integrity sha512-bmFEM39CyX336ZGGRsGPlc6jZHriIoHacOQcTt72MktIjpPhZoP4te2jOyUXF3BLILmJ8aNLncoPVeIIFlrDeA== + version "4.0.3" + resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-4.0.3.tgz#9e4a3c5900830aee3d7f52178b65e01dcdde64a5" + integrity sha512-obsRaULtJurnfox/MDwgq6Yo9kzbv1CPTk/1/s7Z/61Lezc8IKkFCOXNeVLXz0456WRzBQmSsDWlai2tIhBsfA== dependencies: cmd-shim "^6.0.0" npm-normalize-package-bin "^3.0.0" @@ -4278,22 +3999,6 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^2.3.1: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - braces@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -4306,16 +4011,6 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browserslist@^4.21.3, browserslist@^4.21.5: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== - dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" - browserslist@^4.22.2: version "4.22.3" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.3.tgz#299d11b7e947a6b843981392721169e27d60c5a6" @@ -4352,6 +4047,14 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer@*, buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -4360,14 +4063,6 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - builtins@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" @@ -4402,7 +4097,7 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacache@^16.0.0, cacache@^16.1.0: +cacache@^16.1.0: version "16.1.3" resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== @@ -4427,48 +4122,24 @@ cacache@^16.0.0, cacache@^16.1.0: unique-filename "^2.0.0" cacache@^17.0.0, cacache@^17.0.4: - version "17.0.5" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.0.5.tgz#6dbec26c11f1f6a2b558bc11ed3316577c339ebc" - integrity sha512-Y/PRQevNSsjAPWykl9aeGz8Pr+OI6BYM9fYDNMvOkuUiG9IhG4LEmaYrZZZvioMUEQ+cBCxT0v8wrnCURccyKA== + version "17.1.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" + integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== dependencies: "@npmcli/fs" "^3.1.0" fs-minipass "^3.0.0" - glob "^9.3.1" + glob "^10.2.2" lru-cache "^7.7.1" - minipass "^4.0.0" + minipass "^7.0.3" minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - promise-inflight "^1.0.1" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + p-map "^4.0.0" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" -call-bind@^1.0.4, call-bind@^1.0.5: +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== @@ -4520,15 +4191,10 @@ camelcase@^6.0.0, camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001449: - version "1.0.30001481" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz#f58a717afe92f9e69d0e35ff64df596bfad93912" - integrity sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ== - caniuse-lite@^1.0.30001580: - version "1.0.30001581" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz#0dfd4db9e94edbdca67d57348ebc070dece279f4" - integrity sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ== + version "1.0.30001582" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001582.tgz#db3070547ce0b48d9f44a509b86c4a02ba5d9055" + integrity sha512-vsJG3V5vgfduaQGVxL53uSX/HUzxyr2eA8xCo36OLal7sRcSZbibJtLeh0qja4sFOr/QQGt4opB4tOy+eOgAxg== canonicalize@^1.0.1: version "1.0.8" @@ -4548,7 +4214,7 @@ chalk@4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^2.0.0, chalk@^2.4.2: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -4575,11 +4241,6 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -chownr@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -4590,39 +4251,29 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -ci-info@^3.2.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== +ci-info@^3.2.0, ci-info@^3.6.1: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== 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" - integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== class-transformer@0.5.1, class-transformer@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== +class-validator@0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.1.tgz#ff2411ed8134e9d76acfeb14872884448be98110" + integrity sha512-2VEG9JICxIqTpoK1eMzZqaV+u/EiwEJkMGzTrZf6sU/fwsnOITVgYJ8yojSy6CaXtO9V0Cc6ZQZ8h8m4UBuLwQ== dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -class-validator@0.14.0, class-validator@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.0.tgz#40ed0ecf3c83b2a8a6a320f4edb607be0f0df159" - integrity sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A== - dependencies: - "@types/validator" "^13.7.10" - libphonenumber-js "^1.10.14" - validator "^13.7.0" + "@types/validator" "^13.11.8" + libphonenumber-js "^1.10.53" + validator "^13.9.0" clean-stack@^2.0.0: version "2.2.0" @@ -4647,9 +4298,9 @@ cli-spinners@2.6.1: integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cli-spinners@^2.5.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.8.0.tgz#e97a3e2bd00e6d85aa0c13d7f9e3ce236f7787fc" - integrity sha512-/eG5sJcvEIwxcdYM86k5tPwn0MUzkX5YY3eImTGpJOZgVe4SdTMY14vQpcxgBzJ0wXwAYrS8E+c3uHeK4JNyzQ== + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-width@^3.0.0: version "3.0.0" @@ -4710,32 +4361,19 @@ cmd-shim@5.0.0: mkdirp-infer-owner "^2.0.0" cmd-shim@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" - integrity sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q== + version "6.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.2.tgz#435fd9e5c95340e61715e19f90209ed6fcd9e0a4" + integrity sha512-+FFYbB0YLaAkhkcrjkyNLYDiOsFSfRjwjY19LXk/psmMx1z00xlCv7hhQoTGXXIKi+YXHL/iiFo8NqMVQX9nOw== co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== - 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" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== color-convert@^1.9.0: version "1.9.3" @@ -4861,11 +4499,6 @@ compare-versions@^3.4.0: resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== -component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== - compressible@~2.0.16: version "2.0.18" resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" @@ -4929,7 +4562,7 @@ connect@^3.6.5: parseurl "~1.3.3" utils-merge "1.0.1" -console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: +console-control-strings@^1.0.0, console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== @@ -5037,11 +4670,6 @@ conventional-recommended-bump@6.1.0, conventional-recommended-bump@^6.1.0: meow "^8.0.0" q "^1.5.1" -convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - convert-source-map@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" @@ -5057,17 +4685,12 @@ cookie@0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== - -core-js-compat@^3.25.1: - version "3.30.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.30.1.tgz#961541e22db9c27fc48bfc13a3cafa8734171dfe" - integrity sha512-d690npR7MC6P0gq4npTl5n2VQeNAmUrJ90n+MHiKS7W2+xno4o3F5GDEuylSdi6EJ3VssibSGXOa1r3YXD3Mhw== +core-js-compat@^3.34.0: + version "3.35.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.35.1.tgz#215247d7edb9e830efa4218ff719beb2803555e2" + integrity sha512-sftHa5qUJY3rs9Zht1WEnmkvXputCyDBczPnr7QDgL8n3qrF3CMXY4VPSYtOLLiOUJcah2WNXREd48iOl6mQIw== dependencies: - browserslist "^4.21.5" + browserslist "^4.22.2" core-util-is@~1.0.0: version "1.0.3" @@ -5142,12 +4765,12 @@ credentials-context@^2.0.0: resolved "https://registry.yarnpkg.com/credentials-context/-/credentials-context-2.0.0.tgz#68a9a1a88850c398d3bba4976c8490530af093e8" integrity sha512-/mFKax6FK26KjgV2KW2D4YqKgoJ5DVJpNt87X2Jc9IxT2HBMy7nEIlc+n7pEi+YFFe721XqrvZPd+jbyyBjsvQ== -cross-fetch@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== +cross-fetch@^3.1.5, cross-fetch@^3.1.8: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== dependencies: - node-fetch "2.6.7" + node-fetch "^2.6.12" cross-fetch@^4.0.0: version "4.0.0" @@ -5167,7 +4790,7 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, 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" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -5220,11 +4843,11 @@ dateformat@^3.0.0: integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== dayjs@^1.8.15: - version "1.11.7" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" - integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== + version "1.11.10" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0" + integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ== -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.2.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -5238,7 +4861,7 @@ debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, d dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.2.6, debug@^3.2.7: +debug@^3.1.0, debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -5258,7 +4881,7 @@ decamelize@^1.1.0, decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== -decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: +decode-uri-component@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== @@ -5273,7 +4896,7 @@ dedent@^1.0.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== -deep-extend@^0.6.0, deep-extend@~0.6.0: +deep-extend@~0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== @@ -5314,36 +4937,15 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== dependencies: + define-data-property "^1.0.1" has-property-descriptors "^1.0.0" object-keys "^1.1.1" -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - del@^6.0.0: version "6.1.1" resolved "https://registry.yarnpkg.com/del/-/del-6.1.1.tgz#3b70314f1ec0aa325c6b14eb36b95786671edb7a" @@ -5373,19 +4975,19 @@ denodeify@^1.2.1: resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631" integrity sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg== -depd@2.0.0, depd@^2.0.0: +depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== deprecated-react-native-prop-types@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-3.0.1.tgz#a275f84cd8519cd1665e8df3c99e9067d57a23ec" - integrity sha512-J0jCJcsk4hMlIb7xwOZKLfMpuJn6l8UtrPEzzQV5ewz5gvKNYakhBuq9h2rWX7YwHHJZFhU5W8ye7dB9oN8VcQ== + version "3.0.2" + resolved "https://registry.yarnpkg.com/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-3.0.2.tgz#e724a9837e6a7ccb778753c06ae4f79065873493" + integrity sha512-JoZY5iNM+oJlN2Ldpq0KSi0h3Nig4hlNJj5nWzWp8eL3uikMCvHwjSGPitwkEw0arL5JFra5nuGJQpXRbEjApg== dependencies: - "@react-native/normalize-color" "*" - invariant "*" - prop-types "*" + "@react-native/normalize-color" "^2.1.0" + invariant "^2.2.4" + prop-types "^15.8.1" deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" @@ -5402,22 +5004,17 @@ detect-indent@^5.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== -detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== - detect-libc@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" - integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + version "2.0.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -did-jwt@^6.11.6: +did-jwt@6.11.6, did-jwt@^6.11.6: version "6.11.6" resolved "https://registry.yarnpkg.com/did-jwt/-/did-jwt-6.11.6.tgz#3eeb30d6bd01f33bfa17089574915845802a7d44" integrity sha512-OfbWknRxJuUqH6Lk0x+H1FsuelGugLbBDEwsoJnicFOntIG/A4y19fn0a8RLxaQbWQ5gXg0yDq5E2huSBiiXzw== @@ -5440,11 +5037,6 @@ did-resolver@^4.0.0, did-resolver@^4.1.0: resolved "https://registry.yarnpkg.com/did-resolver/-/did-resolver-4.1.0.tgz#740852083c4fd5bf9729d528eca5d105aff45eb6" integrity sha512-S6fWHvCXkZg2IhS4RcVHxwuyVejPR7c+a4Go0xbQ9ps5kILa8viiYQgrM4gfTyeTjJ0ekgJH9gk/BawTpmkbZA== -diff-sequences@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" - integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== - diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" @@ -5500,6 +5092,11 @@ duplexer@^0.1.1: resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + ed25519-signature-2018-context@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ed25519-signature-2018-context/-/ed25519-signature-2018-context-1.1.0.tgz#68002ea7497c32e8170667cfd67468dedf7d220e" @@ -5522,15 +5119,10 @@ ejs@^3.1.7: dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.284: - version "1.4.371" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.371.tgz#393983ef087268a20c926a89be30e9f0bfc803b0" - integrity sha512-jlBzY4tFcJaiUjzhRTCWAqRvTO/fWzjA3Bls0mykzGZ7zvcMP7h05W6UcgzfT9Ca1SW2xyKDOFRyI0pQeRNZGw== - electron-to-chromium@^1.4.648: - version "1.4.648" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.648.tgz#c7b46c9010752c37bb4322739d6d2dd82354fbe4" - integrity sha512-EmFMarXeqJp9cUKu/QEciEApn0S/xRcpZWuAm32U7NgoZCimjsilKXHRO9saeEW55eHZagIDg6XTUOv32w9pjg== + version "1.4.653" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.653.tgz#832ab25e80ad698ac09c1ca547bd9ee6cce7df10" + integrity sha512-wA2A2LQCqnEwQAvwADQq3KpMpNwgAUBnRmrFgRzHnPhbQUFArTR32Ab46f4p0MovDLcg4uqd4nCsN2hTltslpA== elliptic@^6.5.4: version "6.5.4" @@ -5555,6 +5147,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" @@ -5575,9 +5172,9 @@ end-of-stream@^1.1.0, end-of-stream@^1.4.1: once "^1.4.0" enhanced-resolve@^5.12.0: - version "5.13.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.13.0.tgz#26d1ecc448c02de997133217b5c1053f34a0a275" - integrity sha512-eyV8f0y1+bzyfh8xAwW/WTSZpLbjhqc4ne9eGSH4Zo2ejdyiNG9pU6mf9DG8a7+Auk6MFTlNOT4Y2y/9k8GKVg== + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -5595,9 +5192,9 @@ env-paths@^2.2.0: integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== envinfo@^7.7.2, envinfo@^7.7.4: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + version "7.11.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f" + integrity sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg== err-code@^2.0.2: version "2.0.3" @@ -5626,46 +5223,6 @@ errorhandler@^1.5.0: accepts "~1.3.7" escape-html "~1.0.3" -es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== - dependencies: - array-buffer-byte-length "^1.0.0" - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.10" - is-weakref "^1.0.2" - object-inspect "^1.12.3" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.7" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" - es-abstract@^1.22.1: version "1.22.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" @@ -5712,20 +5269,20 @@ es-abstract@^1.22.1: which-typed-array "^1.1.13" es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" + get-intrinsic "^1.2.2" has-tostringtag "^1.0.0" + hasown "^2.0.0" es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== dependencies: - has "^1.0.3" + hasown "^2.0.0" es-to-primitive@^1.2.1: version "1.2.1" @@ -5800,34 +5357,33 @@ escodegen@^1.8.1: source-map "~0.6.1" eslint-config-prettier@^8.3.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" - integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" + integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== -eslint-import-resolver-node@^0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" - integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== +eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" - is-core-module "^2.11.0" - resolve "^1.22.1" + is-core-module "^2.13.0" + resolve "^1.22.4" eslint-import-resolver-typescript@^3.5.3: - version "3.5.5" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz#0a9034ae7ed94b254a360fbea89187b60ea7456d" - integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw== + version "3.6.1" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz#7b983680edd3f1c5bce1a5829ae0bc2d57fe9efa" + integrity sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg== dependencies: debug "^4.3.4" enhanced-resolve "^5.12.0" eslint-module-utils "^2.7.4" + fast-glob "^3.3.1" get-tsconfig "^4.5.0" - globby "^13.1.3" is-core-module "^2.11.0" is-glob "^4.0.3" - synckit "^0.8.5" -eslint-module-utils@^2.7.4: +eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== @@ -5835,25 +5391,27 @@ eslint-module-utils@^2.7.4: debug "^3.2.7" eslint-plugin-import@^2.23.4: - version "2.27.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" - integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== - dependencies: - array-includes "^3.1.6" - array.prototype.flat "^1.3.1" - array.prototype.flatmap "^1.3.1" + version "2.29.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" + integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.7" - eslint-module-utils "^2.7.4" - has "^1.0.3" - is-core-module "^2.11.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" is-glob "^4.0.3" minimatch "^3.1.2" - object.values "^1.1.6" - resolve "^1.22.1" - semver "^6.3.0" - tsconfig-paths "^3.14.1" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.15.0" eslint-plugin-prettier@^4.2.1: version "4.2.1" @@ -5877,40 +5435,41 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz#c7f0f956124ce677047ddbc192a68f999454dedc" - integrity sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@^8.36.0: - version "8.39.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.39.0.tgz#7fd20a295ef92d43809e914b70c39fd5a23cf3f1" - integrity sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og== + version "8.56.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.56.0.tgz#4957ce8da409dc0809f99ab07a1b94832ab74b15" + integrity sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.2" - "@eslint/js" "8.39.0" - "@humanwhocodes/config-array" "^0.11.8" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.56.0" + "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" debug "^4.3.2" doctrine "^3.0.0" escape-string-regexp "^4.0.0" - eslint-scope "^7.2.0" - eslint-visitor-keys "^3.4.0" - espree "^9.5.1" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -5918,32 +5477,29 @@ eslint@^8.36.0: find-up "^5.0.0" glob-parent "^6.0.2" globals "^13.19.0" - grapheme-splitter "^1.0.4" + graphemer "^1.4.0" ignore "^5.2.0" - import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" - js-sdsl "^4.1.4" js-yaml "^4.1.0" json-stable-stringify-without-jsonify "^1.0.1" levn "^0.4.1" lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" + optionator "^0.9.3" strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.5.1: - version "9.5.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.1.tgz#4f26a4d5f18905bf4f2e0bd99002aab807e96dd4" - integrity sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg== +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.0" + eslint-visitor-keys "^3.4.1" esprima@1.2.2: version "1.2.2" @@ -6052,31 +5608,7 @@ exit@^0.1.2: resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expect@^29.0.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.5.0.tgz#68c0509156cb2a0adb8865d413b137eeaae682f7" - integrity sha512-yM7xqUrCO2JdpFo4XpM82t+PJBFybdqoQuJLDGeDX2ij8NZzqRHyu3Hp188/JX7SWqud+7t4MUdvcgGBICMHZg== - dependencies: - "@jest/expect-utils" "^29.5.0" - jest-get-type "^29.4.3" - jest-matcher-utils "^29.5.0" - jest-message-util "^29.5.0" - jest-util "^29.5.0" - -expect@^29.7.0: +expect@^29.0.0, expect@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== @@ -6099,13 +5631,18 @@ expo-modules-autolinking@^0.0.3: fs-extra "^9.1.0" expo-random@*: - version "13.1.1" - resolved "https://registry.yarnpkg.com/expo-random/-/expo-random-13.1.1.tgz#15e781911d5db4fbcee75e26ac109bc2523fe00c" - integrity sha512-+KkhGp7xW45GvMRzlcSOzvDwzTgyXo6C84GaG4GI43rOdECBQ2lGUJ12st39OtfZm1lORNskpi66DjnuJ73g9w== + version "13.6.0" + resolved "https://registry.yarnpkg.com/expo-random/-/expo-random-13.6.0.tgz#98a1c26922d58fa7f16891f02a3d9555549b2a9f" + integrity sha512-c4Ikio+a2sUyJC0386K6JplqjVDelsyqQfjiy4yCx+0epEu44AP99ipF+HsmZVOvsWsWkd/lkpq5kGnJON5EfA== dependencies: base64-js "^1.3.0" -express@^4.17.1: +exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + +express@^4.17.1, express@^4.18.1, express@^4.18.2: version "4.18.2" resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== @@ -6149,21 +5686,6 @@ ext@^1.1.2: dependencies: type "^2.7.2" -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - external-editor@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" @@ -6173,20 +5695,6 @@ external-editor@^3.0.3: iconv-lite "^0.4.24" tmp "^0.0.33" -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - fast-base64-decode@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fast-base64-decode/-/fast-base64-decode-1.0.0.tgz#b434a0dd7d92b12b43f26819300d2dafb83ee418" @@ -6198,9 +5706,9 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== fast-glob@3.2.7: version "3.2.7" @@ -6213,10 +5721,10 @@ fast-glob@3.2.7: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.5, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== +fast-glob@^3.2.12, fast-glob@^3.2.5, fast-glob@^3.2.9, fast-glob@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -6240,16 +5748,16 @@ fast-text-encoding@^1.0.3: integrity sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w== fast-xml-parser@^4.0.12: - version "4.2.6" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.2.6.tgz#30ad37b014c16e31eec0e01fbf90a85cedb4eacf" - integrity sha512-Xo1qV++h/Y3Ng8dphjahnYe+rGHaaNdsYOBWL9Y9GCPKpNKilJtilvWkLcI9f9X2DoKTLsZsGYAls5+JL5jfLA== + version "4.3.4" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.3.4.tgz#385cc256ad7bbc57b91515a38a22502a9e1fca0d" + integrity sha512-utnwm92SyozgA3hhH2I8qldf2lBqm6qHOICawRNRFu1qMe3+oqr+GcXjGqTmXTMGE5T4eC03kr/rlh5C1IRdZA== dependencies: strnum "^1.0.5" fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.17.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.0.tgz#ca5e1a90b5e68f97fc8b61330d5819b82f5fab03" + integrity sha512-zGygtijUMT7jnk3h26kUms3BkSDp4IfIKjmnqI2tvx6nuBfiF1UqOxbnLfzdv+apBy+53oaImsKtMw/xYbW+1w== dependencies: reusify "^1.0.4" @@ -6274,9 +5782,9 @@ fetch-blob@^3.1.2, fetch-blob@^3.1.4: web-streams-polyfill "^3.0.3" figlet@^1.5.2: - version "1.6.0" - resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.6.0.tgz#812050fa9f01043b4d44ddeb11f20fb268fa4b93" - integrity sha512-31EQGhCEITv6+hi2ORRPyn3bulaV9Fl4xOdR169cBzH/n1UqcxsiSB/noo6SJdD7Kfb1Ljit+IgR1USvF/XbdA== + version "1.7.0" + resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.7.0.tgz#46903a04603fd19c3e380358418bb2703587a72e" + integrity sha512-gO8l3wvqo0V7wEFLXPbkX83b7MVjRrk1oRLfYlZXol8nEpb/ON9pcKLI4qpBv5YtOTfrINtqb7b40iYY2FTWFg== figures@3.2.0, figures@^3.0.0: version "3.2.0" @@ -6292,28 +5800,27 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-type@^16.5.4: + version "16.5.4" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.4.tgz#474fb4f704bee427681f98dd390058a172a6c2fd" + integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.2.4" + token-types "^4.1.1" + file-url@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/file-url/-/file-url-3.0.0.tgz#247a586a746ce9f7a8ed05560290968afc262a77" integrity sha512-g872QGsHexznxkIAdK8UiZRe7SkE6kvylShU4Nsj8NvfvZag7S0QuQ4IgvPDkk75HxgjIVDwycFTDAgIiO4nDA== -filelist@^1.0.1: +filelist@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== dependencies: minimatch "^5.0.1" -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -6417,11 +5924,12 @@ fix-esm@^1.0.1: "@babel/plugin-transform-modules-commonjs" "^7.14.5" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: - flatted "^3.1.0" + flatted "^3.2.9" + keyv "^4.5.3" rimraf "^3.0.2" flat@^5.0.2: @@ -6429,25 +5937,25 @@ flat@^5.0.2: resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== flow-parser@0.*: - version "0.204.1" - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.204.1.tgz#a894bc5e8ad520134c1d13383b8991d03cbf8b01" - integrity sha512-PoeSF0VhSORn3hYzD/NxsQjXX1iLU0UZXzVwZXnRWjeVsedmvDo4epd7PtCQjxveGajmVlyVW35BOOOkqLqJpw== + version "0.227.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.227.0.tgz#e50b65be9dc6810438c975e816a68005fbcd5107" + integrity sha512-nOygtGKcX/siZK/lFzpfdHEfOkfGcTW7rNroR1Zsz6T/JxSahPALXVt5qVHq/fgvMJuv096BTKbgxN3PzVBaDA== flow-parser@^0.185.0: version "0.185.2" resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.185.2.tgz#cb7ee57f77377d6c5d69a469e980f6332a15e492" integrity sha512-2hJ5ACYeJCzNtiVULov6pljKOLygy0zddoqSI1fFetM+XRPpRshFdGEijtqlamA1XwyZ+7rhryI6FQFzvtLWUQ== -follow-redirects@^1.14.0, follow-redirects@^1.15.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== +follow-redirects@^1.14.0, follow-redirects@^1.15.4: + version "1.15.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.5.tgz#54d4d6d062c0fa7d9d17feb008461550e3ba8020" + integrity sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw== for-each@^0.3.3: version "0.3.3" @@ -6456,10 +5964,13 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== +foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" form-data@^4.0.0: version "4.0.0" @@ -6482,13 +5993,6 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - fresh@0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" @@ -6510,9 +6014,9 @@ fs-extra@9.1.0, fs-extra@^9.1.0: universalify "^2.0.0" fs-extra@^11.1.0: - version "11.1.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -6527,13 +6031,6 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-minipass@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -6542,11 +6039,11 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0: minipass "^3.0.0" fs-minipass@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.1.tgz#853809af15b6d03e27638d1ab6432e6b378b085d" - integrity sha512-MhaJDcFRTuLidHrIttu0RDGyyXs/IYHVmlcxfLAEFIWjc1vdLAkdwT7Ace2u7DbitWC0toKMl5eJZRYNVreIMw== + version "3.0.3" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" + integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== dependencies: - minipass "^4.0.0" + minipass "^7.0.3" fs.realpath@^1.0.0: version "1.0.0" @@ -6554,30 +6051,15 @@ fs.realpath@^1.0.0: 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" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - function.prototype.name@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" @@ -6588,7 +6070,7 @@ function.prototype.name@^1.1.6: es-abstract "^1.22.1" functions-have-names "^1.2.3" -functions-have-names@^1.2.2, functions-have-names@^1.2.3: +functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== @@ -6623,33 +6105,19 @@ gauge@^4.0.3: wide-align "^1.1.5" gauge@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-5.0.0.tgz#e270ca9d97dae84abf64e5277ef1ebddc7dd1e2f" - integrity sha512-0s5T5eciEG7Q3ugkxAkFtaDhrrhXsCRivA5y8C9WMHWuI8UlMOJg7+Iwf7Mccii+Dfs3H5jHepU0joPVyQU0Lw== + version "5.0.1" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-5.0.1.tgz#1efc801b8ff076b86ef3e9a7a280a975df572112" + integrity sha512-CmykPMJGuNan/3S4kZOpvvPYSNqSHANiWnh9XcMU2pSjtBfF0XzZ2p1bFAxTbnFxyBuPxQYHhzwaoOmUdqzvxQ== dependencies: aproba "^1.0.3 || ^2.0.0" color-support "^1.1.3" console-control-strings "^1.1.0" has-unicode "^2.0.1" - signal-exit "^3.0.7" + signal-exit "^4.0.1" string-width "^4.2.3" strip-ansi "^6.0.1" wide-align "^1.1.5" -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg== - dependencies: - aproba "^1.0.3" - console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" - signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" - 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" @@ -6660,16 +6128,7 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== @@ -6730,9 +6189,11 @@ get-symbol-from-current-process-h@^1.0.1, get-symbol-from-current-process-h@^1.0 integrity sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw== get-tsconfig@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.5.0.tgz#6d52d1c7b299bd3ee9cd7638561653399ac77b0f" - integrity sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ== + version "4.7.2" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.7.2.tgz#0dcd6fb330391d46332f4c6c1bf89a6514c2ddce" + integrity sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A== + dependencies: + resolve-pkg-maps "^1.0.0" get-uv-event-loop-napi-h@^1.0.5: version "1.0.6" @@ -6741,11 +6202,6 @@ get-uv-event-loop-napi-h@^1.0.5: dependencies: get-symbol-from-current-process-h "^1.0.1" -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - git-config@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/git-config/-/git-config-0.0.7.tgz#a9c8a3ef07a776c3d72261356d8b727b62202b28" @@ -6828,6 +6284,17 @@ glob@7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^10.2.2: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + glob@^7.1.3, glob@^7.1.4: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -6851,7 +6318,7 @@ glob@^8.0.1: minimatch "^5.0.1" once "^1.3.0" -glob@^9.2.0, glob@^9.3.0, glob@^9.3.1: +glob@^9.2.0: version "9.3.5" resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== @@ -6867,9 +6334,9 @@ globals@^11.1.0: integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== globals@^13.19.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + version "13.24.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" + integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== dependencies: type-fest "^0.20.2" @@ -6880,11 +6347,6 @@ globalthis@^1.0.1, globalthis@^1.0.3: dependencies: define-properties "^1.1.3" -globalyzer@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465" - integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q== - globby@11.1.0, globby@^11.0.1, globby@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" @@ -6897,22 +6359,6 @@ globby@11.1.0, globby@^11.0.1, globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -globby@^13.1.3: - version "13.1.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.4.tgz#2f91c116066bcec152465ba36e5caa4a13c01317" - integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.2.11" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^4.0.0" - -globrex@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" - integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== - gopd@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" @@ -6930,18 +6376,18 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.3 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== handlebars@^4.7.6, handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" - neo-async "^2.6.0" + neo-async "^2.6.2" source-map "^0.6.1" wordwrap "^1.0.0" optionalDependencies: @@ -6967,12 +6413,12 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== +has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: - get-intrinsic "^1.1.1" + get-intrinsic "^1.2.2" has-proto@^1.0.1: version "1.0.1" @@ -6991,49 +6437,11 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@2.0.1, has-unicode@^2.0.0, has-unicode@^2.0.1: +has-unicode@2.0.1, has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -7160,7 +6568,7 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: +iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -7179,13 +6587,6 @@ ieee754@^1.1.13, ieee754@^1.2.1: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore-walk@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" - integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== - dependencies: - minimatch "^3.0.4" - ignore-walk@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" @@ -7194,16 +6595,16 @@ ignore-walk@^5.0.1: minimatch "^5.0.1" ignore-walk@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.2.tgz#c48f48397cf8ef6174fcc28aa5f8c1de6203d389" - integrity sha512-ezmQ1Dg2b3jVZh2Dh+ar6Eu2MqNSTkyb32HU2MAQQQX9tKM3q/UQ/9lf03lQ5hW+fOeoMnwxwkleZ0xcNp0/qg== + version "6.0.4" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.4.tgz#89950be94b4f522225eb63a13c56badb639190e9" + integrity sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw== dependencies: - minimatch "^7.4.2" + minimatch "^9.0.0" ignore@^5.0.4, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.1" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" + integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== image-size@^0.6.0: version "0.6.3" @@ -7218,7 +6619,7 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -7257,12 +6658,12 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.2, ini@^1.3.4, ini@~1.3.0: +ini@^1.3.2, ini@^1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -7326,9 +6727,9 @@ inquirer@^7.3.3: through "^2.3.6" inquirer@^8.2.4, inquirer@^8.2.5: - version "8.2.5" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.5.tgz#d8654a7542c35a9b9e069d27e2df4858784d54f8" - integrity sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ== + version "8.2.6" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" + integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== dependencies: ansi-escapes "^4.2.1" chalk "^4.1.1" @@ -7344,18 +6745,18 @@ inquirer@^8.2.4, inquirer@^8.2.5: string-width "^4.1.0" strip-ansi "^6.0.0" through "^2.3.6" - wrap-ansi "^7.0.0" + wrap-ansi "^6.0.1" internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" + get-intrinsic "^1.2.2" + hasown "^2.0.0" side-channel "^1.0.4" -invariant@*, invariant@^2.2.4: +invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -7377,20 +6778,6 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== - dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" - is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" @@ -7420,11 +6807,6 @@ is-boolean-object@^1.1.0: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" @@ -7437,26 +6819,12 @@ is-ci@2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.11.0, is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.12.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.0.tgz#36ad62f6f73c8253fd6472517a12483cf03e7ec4" - integrity sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ== - dependencies: - has "^1.0.3" - -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== - dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== +is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: - kind-of "^6.0.0" + hasown "^2.0.0" is-date-object@^1.0.1: version "1.0.5" @@ -7465,24 +6833,6 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" -is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== - dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== - dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" - is-directory@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" @@ -7493,30 +6843,11 @@ is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== - dependencies: - number-is-nan "^1.0.0" - is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -7561,13 +6892,6 @@ is-number-object@^1.0.4: dependencies: has-tostringtag "^1.0.0" -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -7593,7 +6917,7 @@ is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== -is-plain-object@^2.0.3, is-plain-object@^2.0.4: +is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== @@ -7660,21 +6984,10 @@ is-text-path@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" integrity sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w== - dependencies: - text-extensions "^1.0.0" - -is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" + dependencies: + text-extensions "^1.0.0" -is-typed-array@^1.1.12: +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== @@ -7693,11 +7006,6 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" @@ -7710,16 +7018,16 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -isarray@1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + 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" @@ -7730,14 +7038,7 @@ iso-url@^1.1.5: resolved "https://registry.yarnpkg.com/iso-url/-/iso-url-1.2.1.tgz#db96a49d8d9a64a1c889fc07cc525d093afb1811" integrity sha512-9JPDgCN4B7QPkLtYAAOrEuAWvP9rWvR5offAr0/SeF046wIkglqH3VXgYYP6NcsKslH80UIVgmPqNe3j7tG2ng== -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: +isobject@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== @@ -7766,9 +7067,9 @@ isomorphic-ws@^4.0.1: integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== 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" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== istanbul-lib-instrument@^5.0.4: version "5.2.1" @@ -7793,12 +7094,12 @@ istanbul-lib-instrument@^6.0.0: semver "^7.5.4" 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" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== dependencies: istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" + make-dir "^4.0.0" supports-color "^7.1.0" istanbul-lib-source-maps@^4.0.0: @@ -7811,22 +7112,31 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.1.3: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== dependencies: async "^3.2.3" chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" + filelist "^1.0.4" + minimatch "^3.1.2" jest-changed-files@^29.7.0: version "29.7.0" @@ -7908,16 +7218,6 @@ jest-config@^29.7.0: slash "^3.0.0" strip-json-comments "^3.1.1" -jest-diff@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.5.0.tgz#e0d83a58eb5451dcc1fa61b1c3ee4e8f5a290d63" - integrity sha512-LtxijLLZBduXnHSniy0WMdaHjmQnt3g5sa16W4p0HqukYTTsyTW3GD1q41TyGl5YFXj/5B2U6dlh5FM1LIMgxw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.4.3" - jest-get-type "^29.4.3" - pretty-format "^29.5.0" - jest-diff@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" @@ -7946,19 +7246,7 @@ jest-each@^29.7.0: jest-util "^29.7.0" pretty-format "^29.7.0" -jest-environment-node@^29.2.1: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.5.0.tgz#f17219d0f0cc0e68e0727c58b792c040e332c967" - integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== - dependencies: - "@jest/environment" "^29.5.0" - "@jest/fake-timers" "^29.5.0" - "@jest/types" "^29.5.0" - "@types/node" "*" - jest-mock "^29.5.0" - jest-util "^29.5.0" - -jest-environment-node@^29.7.0: +jest-environment-node@^29.2.1, jest-environment-node@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== @@ -7975,11 +7263,6 @@ jest-get-type@^26.3.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-get-type@^29.4.3: - version "29.4.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" - integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== - jest-get-type@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" @@ -8012,16 +7295,6 @@ jest-leak-detector@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" -jest-matcher-utils@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.5.0.tgz#d957af7f8c0692c5453666705621ad4abc2c59c5" - integrity sha512-lecRtgm/rjIK0CQ7LPQwzCs2VwW6WAahA55YBuI+xqmhm7LAaxokSB8C97yJeYyT+HvQkH741StzpU41wohhWw== - dependencies: - chalk "^4.0.0" - jest-diff "^29.5.0" - jest-get-type "^29.4.3" - pretty-format "^29.5.0" - jest-matcher-utils@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" @@ -8032,21 +7305,6 @@ jest-matcher-utils@^29.7.0: jest-get-type "^29.6.3" pretty-format "^29.7.0" -jest-message-util@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.5.0.tgz#1f776cac3aca332ab8dd2e3b41625435085c900e" - integrity sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.5.0" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.5.0" - slash "^3.0.0" - stack-utils "^2.0.3" - jest-message-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" @@ -8062,15 +7320,6 @@ jest-message-util@^29.7.0: slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.5.0.tgz#26e2172bcc71d8b0195081ff1f146ac7e1518aed" - integrity sha512-GqOzvdWDE4fAV2bWQLQCkujxYWL7RxjCnj71b5VhDAGOevB3qj3Ovg26A5NI84ZpODxyzaozXLOh2NCgkbvyaw== - dependencies: - "@jest/types" "^29.5.0" - "@types/node" "*" - jest-util "^29.5.0" - jest-mock@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" @@ -8219,19 +7468,7 @@ jest-util@^27.2.0: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-util@^29.0.0, jest-util@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.5.0.tgz#24a4d3d92fc39ce90425311b23c27a6e0ef16b8f" - integrity sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ== - dependencies: - "@jest/types" "^29.5.0" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-util@^29.7.0: +jest-util@^29.0.0, jest-util@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== @@ -8311,21 +7548,16 @@ jest@^29.7.0: jest-cli "^29.7.0" joi@^17.2.1: - version "17.9.2" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690" - integrity sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw== + version "17.12.1" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.12.1.tgz#3347ecf4cd3301962d42191c021b165eef1f395b" + integrity sha512-vtxmq+Lsc5SlfqotnfVjlViWfOL9nt/avKNbKYizwf6gsCfq9NYY/ceYRMFD8XDdrjJ9abJyScWmhmIiy+XRtQ== dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.3" + "@hapi/hoek" "^9.3.0" + "@hapi/topo" "^5.1.0" + "@sideway/address" "^4.1.5" "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" -js-sdsl@^4.1.4: - version "4.4.0" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.0.tgz#8b437dbe642daa95760400b602378ed8ffea8430" - integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== - js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -8356,10 +7588,15 @@ jsc-android@^250231.0.0: resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-250231.0.0.tgz#91720f8df382a108872fa4b3f558f33ba5e95262" integrity sha512-rS46PvsjYmdmuz1OAWXY/1kCYG7pnf1TBqeTiOJr1iDz7s5DLxxC9n/ZMknLDxzYzNVfI7R95MH10emSSG1Wuw== -jscodeshift@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.13.1.tgz#69bfe51e54c831296380585c6d9e733512aecdef" - integrity sha512-lGyiEbGOvmMRKgWk4vf+lUrCWO/8YR8sUR3FKF1Cq5fovjZDlIcw3Hu5ppLHAnEXshVffvaM0eyuY/AbOeYpnQ== +jsc-safe-url@^0.2.2: + version "0.2.4" + resolved "https://registry.yarnpkg.com/jsc-safe-url/-/jsc-safe-url-0.2.4.tgz#141c14fbb43791e88d5dc64e85a374575a83477a" + integrity sha512-0wM3YBWtYePOjfyXQH5MWQ8H7sdk5EXSwZvmSLKk2RboVQ2Bu239jycHDz5J/8Blf3K0Qnoy2b6xD+z10MFB+Q== + +jscodeshift@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.14.0.tgz#7542e6715d6d2e8bde0b4e883f0ccea358b46881" + integrity sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA== dependencies: "@babel/core" "^7.13.16" "@babel/parser" "^7.13.16" @@ -8374,10 +7611,10 @@ jscodeshift@^0.13.1: chalk "^4.1.2" flow-parser "0.*" graceful-fs "^4.2.4" - micromatch "^3.1.10" + micromatch "^4.0.4" neo-async "^2.5.0" node-dir "^0.1.17" - recast "^0.20.4" + recast "^0.21.0" temp "^0.8.4" write-file-atomic "^2.3.0" @@ -8391,6 +7628,11 @@ jsesc@~0.5.0: resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -8402,9 +7644,9 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-parse-even-better-errors@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7" - integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" + integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== json-schema-traverse@^0.4.1: version "0.4.1" @@ -8519,33 +7761,14 @@ jwt-decode@^3.1.2: resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A== -jwt-sd@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/jwt-sd/-/jwt-sd-0.1.2.tgz#e03d1a2fed7aadd94ee3c6af6594e40023230ff0" - integrity sha512-bFoAlIBkO6FtfaLZ7YxCHMMWDHoy/eNfw8Kkww9iExHA1si3SxKLTi1TpMmUWfwD37NQgJu2j9PkKHXwI6hGPw== - dependencies: - buffer "^6.0.3" - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== dependencies: - is-buffer "^1.1.5" + json-buffer "3.0.1" -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: +kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== @@ -8581,14 +7804,26 @@ ky@^0.33.3: resolved "https://registry.yarnpkg.com/ky/-/ky-0.33.3.tgz#bf1ad322a3f2c3428c13cfa4b3af95e6c4a2f543" integrity sha512-CasD9OCEQSFIam2U8efFK81Yeg8vNMTBUqtMOHlrcWQHqUX3HeCl9Dr31u4toV7emlH8Mymk5+9p0lL6mKb/Xw== +language-subtag-registry@^0.3.20: + version "0.3.22" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + +language-tags@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" + integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== + dependencies: + language-subtag-registry "^0.3.20" + lerna@^6.5.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-6.6.1.tgz#4897171aed64e244a2d0f9000eef5c5b228f9332" - integrity sha512-WJtrvmbmR+6hMB9b5pvsxJzew0lRL6hARgW/My9BM4vYaxwPIA2I0riv3qQu5Zd7lYse7FEqJkTnl9Kn1bXhLA== + version "6.6.2" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-6.6.2.tgz#ad921f913aca4e7307123a598768b6f15ca5804f" + integrity sha512-W4qrGhcdutkRdHEaDf9eqp7u4JvI+1TwFy5woX6OI8WPe4PYBdxuILAsvhp614fUG41rKSGDKlOh+AWzdSidTg== dependencies: - "@lerna/child-process" "6.6.1" - "@lerna/create" "6.6.1" - "@lerna/legacy-package-management" "6.6.1" + "@lerna/child-process" "6.6.2" + "@lerna/create" "6.6.2" + "@lerna/legacy-package-management" "6.6.2" "@npmcli/arborist" "6.2.3" "@npmcli/run-script" "4.1.7" "@nrwl/devkit" ">=15.5.2 < 16" @@ -8622,8 +7857,8 @@ lerna@^6.5.1: is-ci "2.0.0" is-stream "2.0.0" js-yaml "^4.1.0" - libnpmaccess "6.0.3" - libnpmpublish "6.0.4" + libnpmaccess "^6.0.3" + libnpmpublish "7.1.4" load-json-file "6.2.0" make-dir "3.1.0" minimatch "3.0.5" @@ -8640,7 +7875,7 @@ lerna@^6.5.1: p-queue "6.6.2" p-reduce "2.1.0" p-waterfall "2.1.1" - pacote "13.6.2" + pacote "15.1.1" pify "5.0.0" read-cmd-shim "3.0.0" read-package-json "5.0.1" @@ -8684,55 +7919,58 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -libnpmaccess@6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-6.0.3.tgz#473cc3e4aadb2bc713419d92e45d23b070d8cded" - integrity sha512-4tkfUZprwvih2VUZYMozL7EMKgQ5q9VW2NtRyxWtQWlkLTAWHRklcAvBN49CVqEkhUw7vTX2fNgB5LzgUucgYg== +libnpmaccess@^6.0.3: + version "6.0.4" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-6.0.4.tgz#2dd158bd8a071817e2207d3b201d37cf1ad6ae6b" + integrity sha512-qZ3wcfIyUoW0+qSFkMBovcTrSGJ3ZeyvpR7d5N9pEYv/kXs8sHP2wiqEIXBKLFrZlmM0kR0RJD7mtfLngtlLag== dependencies: aproba "^2.0.0" minipass "^3.1.1" npm-package-arg "^9.0.1" npm-registry-fetch "^13.0.0" -libnpmpublish@6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-6.0.4.tgz#adb41ec6b0c307d6f603746a4d929dcefb8f1a0b" - integrity sha512-lvAEYW8mB8QblL6Q/PI/wMzKNvIrF7Kpujf/4fGS/32a2i3jzUXi04TNyIBcK6dQJ34IgywfaKGh+Jq4HYPFmg== +libnpmpublish@7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.1.4.tgz#a0d138e00e52a0c71ffc82273acf0082fc2dfb36" + integrity sha512-mMntrhVwut5prP4rJ228eEbEyvIzLWhqFuY90j5QeXBCTT2pWSMno7Yo2S2qplPUr02zPurGH4heGLZ+wORczg== dependencies: - normalize-package-data "^4.0.0" - npm-package-arg "^9.0.1" - npm-registry-fetch "^13.0.0" + ci-info "^3.6.1" + normalize-package-data "^5.0.0" + npm-package-arg "^10.1.0" + npm-registry-fetch "^14.0.3" + proc-log "^3.0.0" semver "^7.3.7" - ssri "^9.0.0" + sigstore "^1.4.0" + ssri "^10.0.1" -libphonenumber-js@^1.10.14: - version "1.10.28" - resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.28.tgz#cae7e929cad96cee5ecc9449027192ecba39ee72" - integrity sha512-1eAgjLrZA0+2Wgw4hs+4Q/kEBycxQo8ZLYnmOvZ3AlM8ImAVAJgDPlZtISLEzD1vunc2q8s2Pn7XwB7I8U3Kzw== +libphonenumber-js@^1.10.53: + version "1.10.54" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.54.tgz#8dfba112f49d1b9c2a160e55f9697f22e50f0841" + integrity sha512-P+38dUgJsmh0gzoRDoM4F5jLbyfztkU6PY6eSK6S5HwTi/LPvnwXqVCQZlAy1FxZ5c48q25QhxGQ0pq+WQcSlQ== -libsodium-sumo@^0.7.11: - version "0.7.11" - resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.11.tgz#ab0389e2424fca5c1dc8c4fd394906190da88a11" - integrity sha512-bY+7ph7xpk51Ez2GbE10lXAQ5sJma6NghcIDaSPbM/G9elfrjLa0COHl/7P6Wb/JizQzl5UQontOOP1z0VwbLA== +libsodium-sumo@^0.7.13: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.13.tgz#533b97d2be44b1277e59c1f9f60805978ac5542d" + integrity sha512-zTGdLu4b9zSNLfovImpBCbdAA4xkpkZbMnSQjP8HShyOutnGjRHmSOKlsylh1okao6QhLiz7nG98EGn+04cZjQ== libsodium-wrappers-sumo@^0.7.11: - version "0.7.11" - resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.11.tgz#d96329ee3c0e7ec7f5fcf4cdde16cc3a1ae91d82" - integrity sha512-DGypHOmJbB1nZn89KIfGOAkDgfv5N6SBGC3Qvmy/On0P0WD1JQvNRS/e3UL3aFF+xC0m+MYz5M+MnRnK2HMrKQ== + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.13.tgz#a33aea845a0bb56db067548f04feba28c730ab8e" + integrity sha512-lz4YdplzDRh6AhnLGF2Dj2IUj94xRN6Bh8T0HLNwzYGwPehQJX6c7iYVrFUPZ3QqxE0bqC+K0IIqqZJYWumwSQ== dependencies: - libsodium-sumo "^0.7.11" + libsodium-sumo "^0.7.13" libsodium-wrappers@^0.7.6: - version "0.7.11" - resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.11.tgz#53bd20606dffcc54ea2122133c7da38218f575f7" - integrity sha512-SrcLtXj7BM19vUKtQuyQKiQCRJPgbpauzl3s0rSwD+60wtHqSUuqcoawlMDheCJga85nKOQwxNYQxf/CKAvs6Q== + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.13.tgz#83299e06ee1466057ba0e64e532777d2929b90d3" + integrity sha512-kasvDsEi/r1fMzKouIDv7B8I6vNmknXwGiYodErGuESoFTohGSKZplFtVxZqHaoQ217AynyIFgnOVRitpHs0Qw== dependencies: - libsodium "^0.7.11" + libsodium "^0.7.13" -libsodium@^0.7.11: - version "0.7.11" - resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.11.tgz#cd10aae7bcc34a300cc6ad0ac88fcca674cfbc2e" - integrity sha512-WPfJ7sS53I2s4iM58QxY3Inb83/6mjlYgcmZs7DJsvDlnmVUwNinBCi5vBT43P6bHRy01O4zsMU2CoVR6xJ40A== +libsodium@^0.7.13: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.13.tgz#230712ec0b7447c57b39489c48a4af01985fb393" + integrity sha512-mK8ju0fnrKXXfleL53vtp9xiPq5hKM0zbDQtcxQIsSmxNgSxqCj6R7Hl9PkrNe2j29T4yoDaF7DJLK9/i5iWUw== lines-and-columns@^1.1.6: version "1.2.4" @@ -8740,9 +7978,9 @@ lines-and-columns@^1.1.6: integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lines-and-columns@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" - integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + version "2.0.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" + integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== load-json-file@6.2.0: version "6.2.0" @@ -8882,10 +8120,10 @@ lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== -lru-cache@^9.0.0: - version "9.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-9.1.1.tgz#c58a93de58630b688de39ad04ef02ef26f1902f1" - integrity sha512-65/Jky17UwSb0BuB9V+MyDpsOtXKmYwzhyl+cOa9XUiI4uV2Ouy/2voFP3+al0BjZbJgMBD8FojMpAf+Z+qn4A== +"lru-cache@^9.1.1 || ^10.0.0": + version "10.2.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.2.0.tgz#0bd445ca57363465900f4d1f9bd8db343a4d95c3" + integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== lru_map@^0.4.1: version "0.4.1" @@ -8893,11 +8131,11 @@ lru_map@^0.4.1: integrity sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg== luxon@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.3.0.tgz#d73ab5b5d2b49a461c47cedbc7e73309b4805b48" - integrity sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg== + version "3.4.4" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" + integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA== -make-dir@3.1.0, make-dir@^3.0.0, make-dir@^3.1.0: +make-dir@3.1.0, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -8912,6 +8150,13 @@ make-dir@^2.0.0, make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + make-error@1.x, make-error@^1.1.1, make-error@^1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" @@ -8939,10 +8184,10 @@ make-fetch-happen@^10.0.3, make-fetch-happen@^10.0.6: socks-proxy-agent "^7.0.0" ssri "^9.0.0" -make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1: - version "11.1.0" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.0.tgz#f26b05e89317e960b75fd5e080e40d40f8d7b2a5" - integrity sha512-7ChuOzCb1LzdQZrTy0ky6RsCoMYeM+Fh4cY0+4zsJVhNcH5Q3OJojLY1mGkD0xAhWB29lskECVb6ZopofwjldA== +make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== dependencies: agentkeepalive "^4.2.1" cacache "^17.0.0" @@ -8951,7 +8196,7 @@ make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1: https-proxy-agent "^5.0.0" is-lambda "^1.0.1" lru-cache "^7.7.1" - minipass "^4.0.0" + minipass "^5.0.0" minipass-fetch "^3.0.0" minipass-flush "^1.0.5" minipass-pipeline "^1.2.4" @@ -8972,11 +8217,6 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - map-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" @@ -8987,13 +8227,6 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -9041,53 +8274,53 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== -metro-babel-transformer@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.73.9.tgz#bec8aaaf1bbdc2e469fde586fde455f8b2a83073" - integrity sha512-DlYwg9wwYIZTHtic7dyD4BP0SDftoltZ3clma76nHu43blMWsCnrImHeHsAVne3XsQ+RJaSRxhN5nkG2VyVHwA== +metro-babel-transformer@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.73.10.tgz#b27732fa3869f397246ee8ecf03b64622ab738c1" + integrity sha512-Yv2myTSnpzt/lTyurLvqYbBkytvUJcLHN8XD3t7W6rGiLTQPzmf1zypHQLphvcAXtCWBOXFtH7KLOSi2/qMg+A== dependencies: "@babel/core" "^7.20.0" hermes-parser "0.8.0" - metro-source-map "0.73.9" + metro-source-map "0.73.10" nullthrows "^1.1.1" -metro-cache-key@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.73.9.tgz#7d8c441a3b7150f7b201273087ef3cf7d3435d9f" - integrity sha512-uJg+6Al7UoGIuGfoxqPBy6y1Ewq7Y8/YapGYIDh6sohInwt/kYKnPZgLDYHIPvY2deORnQ/2CYo4tOeBTnhCXQ== +metro-cache-key@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.73.10.tgz#8d63591187d295b62a80aed64a87864b1e9d67a2" + integrity sha512-JMVDl/EREDiUW//cIcUzRjKSwE2AFxVWk47cFBer+KA4ohXIG2CQPEquT56hOw1Y1s6gKNxxs1OlAOEsubrFjw== -metro-cache@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.73.9.tgz#773c2df6ba53434e58ccbe421b0c54e6da8d2890" - integrity sha512-upiRxY8rrQkUWj7ieACD6tna7xXuXdu2ZqrheksT79ePI0aN/t0memf6WcyUtJUMHZetke3j+ppELNvlmp3tOw== +metro-cache@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.73.10.tgz#02e9cb7c1e42aab5268d2ecce35ad8f2c08891de" + integrity sha512-wPGlQZpdVlM404m7MxJqJ+hTReDr5epvfPbt2LerUAHY9RN99w61FeeAe25BMZBwgUgDtAsfGlJ51MBHg8MAqw== dependencies: - metro-core "0.73.9" + metro-core "0.73.10" rimraf "^3.0.2" -metro-config@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.73.9.tgz#6b43c70681bdd6b00f44400fc76dddbe53374500" - integrity sha512-NiWl1nkYtjqecDmw77tbRbXnzIAwdO6DXGZTuKSkH+H/c1NKq1eizO8Fe+NQyFtwR9YLqn8Q0WN1nmkwM1j8CA== +metro-config@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.73.10.tgz#a9ec3d0a1290369e3f46c467a4c4f6dd43acc223" + integrity sha512-wIlybd1Z9I8K2KcStTiJxTB7OK529dxFgogNpKCTU/3DxkgAASqSkgXnZP6kVyqjh5EOWAKFe5U6IPic7kXDdQ== dependencies: cosmiconfig "^5.0.5" jest-validate "^26.5.2" - metro "0.73.9" - metro-cache "0.73.9" - metro-core "0.73.9" - metro-runtime "0.73.9" + metro "0.73.10" + metro-cache "0.73.10" + metro-core "0.73.10" + metro-runtime "0.73.10" -metro-core@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.73.9.tgz#410c5c0aeae840536c10039f68098fdab3da568e" - integrity sha512-1NTs0IErlKcFTfYyRT3ljdgrISWpl1nys+gaHkXapzTSpvtX9F1NQNn5cgAuE+XIuTJhbsCdfIJiM2JXbrJQaQ== +metro-core@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.73.10.tgz#feb3c228aa8c0dde71d8e4cef614cc3a1dc3bbd7" + integrity sha512-5uYkajIxKyL6W45iz/ftNnYPe1l92CvF2QJeon1CHsMXkEiOJxEjo41l+iSnO/YodBGrmMCyupSO4wOQGUc0lw== dependencies: lodash.throttle "^4.1.1" - metro-resolver "0.73.9" + metro-resolver "0.73.10" -metro-file-map@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.73.9.tgz#09c04a8e8ef1eaa6ecb2b9cb8cb53bb0fa0167ec" - integrity sha512-R/Wg3HYeQhYY3ehWtfedw8V0ne4lpufG7a21L3GWer8tafnC9pmjoCKEbJz9XZkVj9i1FtxE7UTbrtZNeIILxQ== +metro-file-map@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.73.10.tgz#55bd906fb7c1bef8e1a31df4b29a3ef4b49f0b5a" + integrity sha512-XOMWAybeaXyD6zmVZPnoCCL2oO3rp4ta76oUlqWP0skBzhFxVtkE/UtDwApEMUY361JeBBago647gnKiARs+1g== dependencies: abort-controller "^3.0.0" anymatch "^3.0.3" @@ -9105,39 +8338,39 @@ metro-file-map@0.73.9: optionalDependencies: fsevents "^2.3.2" -metro-hermes-compiler@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.73.9.tgz#6f473e67e8f76066066f00e2e0ecce865f7d445d" - integrity sha512-5B3vXIwQkZMSh3DQQY23XpTCpX9kPLqZbA3rDuAcbGW0tzC3f8dCenkyBb0GcCzyTDncJeot/A7oVCVK6zapwg== +metro-hermes-compiler@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.73.10.tgz#4525a7835c803a5d0b3b05c6619202e2273d630f" + integrity sha512-rTRWEzkVrwtQLiYkOXhSdsKkIObnL+Jqo+IXHI7VEK2aSLWRAbtGNqECBs44kbOUypDYTFFE+WLtoqvUWqYkWg== -metro-inspector-proxy@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.73.9.tgz#8e11cd300adf3f904f1f5afe28b198312cdcd8c2" - integrity sha512-B3WrWZnlYhtTrv0IaX3aUAhi2qVILPAZQzb5paO1e+xrz4YZHk9c7dXv7qe7B/IQ132e3w46y3AL7rFo90qVjA== +metro-inspector-proxy@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.73.10.tgz#752fed2ab88199c9dcc3369c3d59da6c5b954a51" + integrity sha512-CEEvocYc5xCCZBtGSIggMCiRiXTrnBbh8pmjKQqm9TtJZALeOGyt5pXUaEkKGnhrXETrexsg6yIbsQHhEvVfvQ== dependencies: connect "^3.6.5" debug "^2.2.0" ws "^7.5.1" yargs "^17.5.1" -metro-minify-terser@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.73.9.tgz#301aef2e106b0802f7a14ef0f2b4883b20c80018" - integrity sha512-MTGPu2qV5qtzPJ2SqH6s58awHDtZ4jd7lmmLR+7TXDwtZDjIBA0YVfI0Zak2Haby2SqoNKrhhUns/b4dPAQAVg== +metro-minify-terser@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.73.10.tgz#557eab3a512b90b7779350ff5d25a215c4dbe61f" + integrity sha512-uG7TSKQ/i0p9kM1qXrwbmY3v+6BrMItsOcEXcSP8Z+68bb+t9HeVK0T/hIfUu1v1PEnonhkhfzVsaP8QyTd5lQ== dependencies: terser "^5.15.0" -metro-minify-uglify@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.73.9.tgz#cf4f8c19b688deea103905689ec736c2f2acd733" - integrity sha512-gzxD/7WjYcnCNGiFJaA26z34rjOp+c/Ft++194Wg91lYep3TeWQ0CnH8t2HRS7AYDHU81SGWgvD3U7WV0g4LGA== +metro-minify-uglify@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.73.10.tgz#4de79056d502479733854c90f2075374353ea154" + integrity sha512-eocnSeJKnLz/UoYntVFhCJffED7SLSgbCHgNvI6ju6hFb6EFHGJT9OLbkJWeXaWBWD3Zw5mYLS8GGqGn/CHZPA== dependencies: uglify-es "^3.1.9" -metro-react-native-babel-preset@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.9.tgz#ef54637dd20f025197beb49e71309a9c539e73e2" - integrity sha512-AoD7v132iYDV4K78yN2OLgTPwtAKn0XlD2pOhzyBxiI8PeXzozhbKyPV7zUOJUPETj+pcEVfuYj5ZN/8+bhbCw== +metro-react-native-babel-preset@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.10.tgz#304b24bb391537d2c987732cc0a9774be227d3f6" + integrity sha512-1/dnH4EHwFb2RKEKx34vVDpUS3urt2WEeR8FYim+ogqALg4sTpG7yeQPxWpbgKATezt4rNfqAANpIyH19MS4BQ== dependencies: "@babel/core" "^7.20.0" "@babel/plugin-proposal-async-generator-functions" "^7.0.0" @@ -9178,64 +8411,64 @@ metro-react-native-babel-preset@0.73.9: "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.9.tgz#4f4f0cfa5119bab8b53e722fabaf90687d0cbff0" - integrity sha512-DSdrEHuQ22ixY7DyipyKkIcqhOJrt5s6h6X7BYJCP9AMUfXOwLe2biY3BcgJz5GOXv8/Akry4vTCvQscVS1otQ== +metro-react-native-babel-transformer@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.10.tgz#4e20a9ce131b873cda0b5a44d3eb4002134a64b8" + integrity sha512-4G/upwqKdmKEjmsNa92/NEgsOxUWOygBVs+FXWfXWKgybrmcjh3NoqdRYrROo9ZRA/sB9Y/ZXKVkWOGKHtGzgg== dependencies: "@babel/core" "^7.20.0" babel-preset-fbjs "^3.4.0" hermes-parser "0.8.0" - metro-babel-transformer "0.73.9" - metro-react-native-babel-preset "0.73.9" - metro-source-map "0.73.9" + metro-babel-transformer "0.73.10" + metro-react-native-babel-preset "0.73.10" + metro-source-map "0.73.10" nullthrows "^1.1.1" -metro-resolver@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.73.9.tgz#f3cf77e6c7606a34aa81bad40edb856aad671cf3" - integrity sha512-Ej3wAPOeNRPDnJmkK0zk7vJ33iU07n+oPhpcf5L0NFkWneMmSM2bflMPibI86UjzZGmRfn0AhGhs8yGeBwQ/Xg== +metro-resolver@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.73.10.tgz#c39a3bd8d33e5d78cb256110d29707d8d49ed0be" + integrity sha512-HeXbs+0wjakaaVQ5BI7eT7uqxlZTc9rnyw6cdBWWMgUWB++KpoI0Ge7Hi6eQAOoVAzXC3m26mPFYLejpzTWjng== dependencies: absolute-path "^0.0.0" -metro-runtime@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.73.9.tgz#0b24c0b066b8629ee855a6e5035b65061fef60d5" - integrity sha512-d5Hs83FpKB9r8q8Vb95+fa6ESpwysmPr4lL1I2rM2qXAFiO7OAPT9Bc23WmXgidkBtD0uUFdB2lG+H1ATz8rZg== +metro-runtime@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.73.10.tgz#c3de19d17e75ffe1a145778d99422e7ffc208768" + integrity sha512-EpVKm4eN0Fgx2PEWpJ5NiMArV8zVoOin866jIIvzFLpmkZz1UEqgjf2JAfUJnjgv3fjSV3JqeGG2vZCaGQBTow== dependencies: "@babel/runtime" "^7.0.0" react-refresh "^0.4.0" -metro-source-map@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.73.9.tgz#89ca41f6346aeb12f7f23496fa363e520adafebe" - integrity sha512-l4VZKzdqafipriETYR6lsrwtavCF1+CMhCOY9XbyWeTrpGSNgJQgdeJpttzEZTHQQTLR0csQo0nD1ef3zEP6IQ== +metro-source-map@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.73.10.tgz#28e09a28f1a2f7a4f8d0845b845cbed74e2f48f9" + integrity sha512-NAGv14701p/YaFZ76KzyPkacBw/QlEJF1f8elfs23N1tC33YyKLDKvPAzFJiYqjdcFvuuuDCA8JCXd2TgLxNPw== dependencies: "@babel/traverse" "^7.20.0" "@babel/types" "^7.20.0" invariant "^2.2.4" - metro-symbolicate "0.73.9" + metro-symbolicate "0.73.10" nullthrows "^1.1.1" - ob1 "0.73.9" + ob1 "0.73.10" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.73.9.tgz#cb452299a36e5b86b2826e7426d51221635c48bf" - integrity sha512-4TUOwxRHHqbEHxRqRJ3wZY5TA8xq7AHMtXrXcjegMH9FscgYztsrIG9aNBUBS+VLB6g1qc6BYbfIgoAnLjCDyw== +metro-symbolicate@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.73.10.tgz#7853a9a8fbfd615a5c9db698fffc685441ac880f" + integrity sha512-PmCe3TOe1c/NVwMlB+B17me951kfkB3Wve5RqJn+ErPAj93od1nxicp6OJe7JT4QBRnpUP8p9tw2sHKqceIzkA== dependencies: invariant "^2.2.4" - metro-source-map "0.73.9" + metro-source-map "0.73.10" nullthrows "^1.1.1" source-map "^0.5.6" through2 "^2.0.1" vlq "^1.0.0" -metro-transform-plugins@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.73.9.tgz#9fffbe1b24269e3d114286fa681abc570072d9b8" - integrity sha512-r9NeiqMngmooX2VOKLJVQrMuV7PAydbqst5bFhdVBPcFpZkxxqyzjzo+kzrszGy2UpSQBZr2P1L6OMjLHwQwfQ== +metro-transform-plugins@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.73.10.tgz#1b762330cbbedb6c18438edc3d76b063c88882af" + integrity sha512-D4AgD3Vsrac+4YksaPmxs/0ocT67bvwTkFSIgWWeDvWwIG0U1iHzTS9f8Bvb4PITnXryDoFtjI6OWF7uOpGxpA== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.0" @@ -9243,29 +8476,29 @@ metro-transform-plugins@0.73.9: "@babel/traverse" "^7.20.0" nullthrows "^1.1.1" -metro-transform-worker@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.73.9.tgz#30384cef2d5e35a4abe91b15bf1a8344f5720441" - integrity sha512-Rq4b489sIaTUENA+WCvtu9yvlT/C6zFMWhU4sq+97W29Zj0mPBjdk+qGT5n1ZBgtBIJzZWt1KxeYuc17f4aYtQ== +metro-transform-worker@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.73.10.tgz#bb401dbd7b10a6fe443a5f7970cba38425efece0" + integrity sha512-IySvVubudFxahxOljWtP0QIMMpgUrCP0bW16cz2Enof0PdumwmR7uU3dTbNq6S+XTzuMHR+076aIe4VhPAWsIQ== dependencies: "@babel/core" "^7.20.0" "@babel/generator" "^7.20.0" "@babel/parser" "^7.20.0" "@babel/types" "^7.20.0" babel-preset-fbjs "^3.4.0" - metro "0.73.9" - metro-babel-transformer "0.73.9" - metro-cache "0.73.9" - metro-cache-key "0.73.9" - metro-hermes-compiler "0.73.9" - metro-source-map "0.73.9" - metro-transform-plugins "0.73.9" + metro "0.73.10" + metro-babel-transformer "0.73.10" + metro-cache "0.73.10" + metro-cache-key "0.73.10" + metro-hermes-compiler "0.73.10" + metro-source-map "0.73.10" + metro-transform-plugins "0.73.10" nullthrows "^1.1.1" -metro@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.73.9.tgz#150e69a6735fab0bcb4f6ee97fd1efc65b3ec36f" - integrity sha512-BlYbPmTF60hpetyNdKhdvi57dSqutb+/oK0u3ni4emIh78PiI0axGo7RfdsZ/mn3saASXc94tDbpC5yn7+NpEg== +metro@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.73.10.tgz#d9a0efb1e403e3aee5cf5140e0a96a7220c23901" + integrity sha512-J2gBhNHFtc/Z48ysF0B/bfTwUwaRDLjNv7egfhQCc+934dpXcjJG2KZFeuybF+CvA9vo4QUi56G2U+RSAJ5tsA== dependencies: "@babel/code-frame" "^7.0.0" "@babel/core" "^7.20.0" @@ -9288,24 +8521,25 @@ metro@0.73.9: image-size "^0.6.0" invariant "^2.2.4" jest-worker "^27.2.0" + jsc-safe-url "^0.2.2" lodash.throttle "^4.1.1" - metro-babel-transformer "0.73.9" - metro-cache "0.73.9" - metro-cache-key "0.73.9" - metro-config "0.73.9" - metro-core "0.73.9" - metro-file-map "0.73.9" - metro-hermes-compiler "0.73.9" - metro-inspector-proxy "0.73.9" - metro-minify-terser "0.73.9" - metro-minify-uglify "0.73.9" - metro-react-native-babel-preset "0.73.9" - metro-resolver "0.73.9" - metro-runtime "0.73.9" - metro-source-map "0.73.9" - metro-symbolicate "0.73.9" - metro-transform-plugins "0.73.9" - metro-transform-worker "0.73.9" + metro-babel-transformer "0.73.10" + metro-cache "0.73.10" + metro-cache-key "0.73.10" + metro-config "0.73.10" + metro-core "0.73.10" + metro-file-map "0.73.10" + metro-hermes-compiler "0.73.10" + metro-inspector-proxy "0.73.10" + metro-minify-terser "0.73.10" + metro-minify-uglify "0.73.10" + metro-react-native-babel-preset "0.73.10" + metro-resolver "0.73.10" + metro-runtime "0.73.10" + metro-source-map "0.73.10" + metro-symbolicate "0.73.10" + metro-transform-plugins "0.73.10" + metro-transform-worker "0.73.10" mime-types "^2.1.27" node-fetch "^2.2.0" nullthrows "^1.1.1" @@ -9318,25 +8552,6 @@ metro@0.73.9: ws "^7.5.1" yargs "^17.5.1" -micromatch@^3.1.10: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -9415,13 +8630,6 @@ minimatch@^6.1.6: dependencies: brace-expansion "^2.0.1" -minimatch@^7.4.2, minimatch@^7.4.6: - version "7.4.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" - integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== - dependencies: - brace-expansion "^2.0.1" - minimatch@^8.0.2: version "8.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" @@ -9429,6 +8637,13 @@ minimatch@^8.0.2: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.0, minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimist-options@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -9462,11 +8677,11 @@ minipass-fetch@^2.0.3: encoding "^0.1.13" minipass-fetch@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.2.tgz#2f7275ae13f2fb0f2a469cee4f78250c25c80ab3" - integrity sha512-/ZpF1CQaWYqjbhfFgKNt3azxztEpc/JUPuMkqOgrnMQqcU8CbE409AUdJYTIWryl3PP5CBaTJZT71N49MXP/YA== + version "3.0.4" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" + integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== dependencies: - minipass "^4.0.0" + minipass "^7.0.3" minipass-sized "^1.0.3" minizlib "^2.1.2" optionalDependencies: @@ -9501,14 +8716,6 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^2.6.0, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" @@ -9526,12 +8733,10 @@ minipass@^5.0.0: resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== -minizlib@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" +"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" @@ -9541,14 +8746,6 @@ minizlib@^2.1.1, minizlib@^2.1.2: minipass "^3.0.0" yallist "^4.0.0" -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - mkdirp-infer-owner@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mkdirp-infer-owner/-/mkdirp-infer-owner-2.0.0.tgz#55d3b368e7d89065c38f32fd38e638f0ab61d316" @@ -9558,7 +8755,7 @@ mkdirp-infer-owner@^2.0.0: infer-owner "^1.0.4" mkdirp "^1.0.3" -mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5: +mkdirp@^0.5.1, mkdirp@^0.5.4: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -9608,6 +8805,11 @@ multer@^1.4.5-lts.1: type-is "^1.6.4" xtend "^4.0.0" +multiformats@^11.0.2: + version "11.0.2" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-11.0.2.tgz#b14735efc42cd8581e73895e66bebb9752151b60" + integrity sha512-b5mYMkOkARIuVZCpvijFj9a6m5wMVLC7cf/jIPd5D/ARDOfLC5+IFkbgDXQgcU2goIsTD/O9NY4DI/Mt4OGvlg== + multiformats@^9.4.2, multiformats@^9.6.5, multiformats@^9.9.0: version "9.9.0" resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" @@ -9629,28 +8831,11 @@ mute-stream@0.0.8, mute-stream@~0.0.4: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nanoid@^3.3.6: +nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -9661,21 +8846,12 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -needle@^2.5.2: - version "2.9.1" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684" - integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== - dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" - negotiator@0.6.3, negotiator@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -neo-async@^2.5.0, neo-async@^2.6.0: +neo-async@^2.5.0, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -9700,26 +8876,6 @@ neon-cli@0.10.1: validate-npm-package-license "^3.0.4" validate-npm-package-name "^3.0.0" -neon-cli@0.8.2: - version "0.8.2" - resolved "https://registry.yarnpkg.com/neon-cli/-/neon-cli-0.8.2.tgz#5111b0e9d5d90273bdf85a9aa40a1a47a32df2ef" - integrity sha512-vYRBmiLiwPVeBvR9huCFXRAtdLYfsoSG3hgsXrcuyMSXk7yqpnZlgvOGGuxfhrRb/iNfcd0M0cEs0j22mDgZ+A== - dependencies: - chalk "^4.1.0" - command-line-args "^5.1.1" - command-line-commands "^3.0.1" - command-line-usage "^6.1.0" - git-config "0.0.7" - handlebars "^4.7.6" - inquirer "^7.3.3" - make-promises-safe "^5.1.0" - rimraf "^3.0.2" - semver "^7.3.2" - toml "^3.0.0" - ts-typed-json "^0.3.2" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "^3.0.0" - next-tick@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" @@ -9736,13 +8892,12 @@ nocache@^3.0.1: integrity sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw== nock@^13.3.0: - version "13.3.0" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.3.0.tgz#b13069c1a03f1ad63120f994b04bfd2556925768" - integrity sha512-HHqYQ6mBeiMc+N038w8LkMpDCRquCHWeNmN3v6645P3NhN2+qXOBqvPqo7Rt1VyCMzKhJ733wZqw5B7cQVFNPg== + version "13.5.1" + resolved "https://registry.yarnpkg.com/nock/-/nock-13.5.1.tgz#4e40f9877ad0d43b7cdb474261c190f3715dd806" + integrity sha512-+s7b73fzj5KnxbKH4Oaqz07tQ8degcMilU4rrmnKvI//b0JMBU4wEXFQ8zqr+3+L4eWSfU3H/UoIVGUV0tue1Q== dependencies: debug "^4.1.0" json-stringify-safe "^5.0.1" - lodash "^4.17.21" propagate "^2.0.0" node-addon-api@^3.0.0, node-addon-api@^3.2.1: @@ -9784,17 +8939,10 @@ node-fetch@3.0.0-beta.9: data-uri-to-buffer "^3.0.1" fetch-blob "^2.1.1" -node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.7: - version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.6.12: - version "2.6.12" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" - integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== +node-fetch@^2.2.0, node-fetch@^2.6.0, node-fetch@^2.6.12, node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" @@ -9808,16 +8956,17 @@ node-fetch@^3.2.10: formdata-polyfill "^4.0.10" node-gyp-build@^4.2.1, node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== + version "4.8.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.0.tgz#3fee9c1731df4581a3f9ead74664369ff00d26dd" + integrity sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og== node-gyp@^9.0.0: - version "9.3.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.3.1.tgz#1e19f5f290afcc9c46973d68700cbd21a96192e4" - integrity sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg== + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== dependencies: env-paths "^2.2.0" + exponential-backoff "^3.1.1" glob "^7.1.4" graceful-fs "^4.2.6" make-fetch-happen "^10.0.3" @@ -9833,45 +8982,16 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-pre-gyp@0.17.0: - version "0.17.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.17.0.tgz#5af3f7b4c3848b5ed00edc3d298ff836daae5f1d" - integrity sha512-abzZt1hmOjkZez29ppg+5gGqdPLUuJeAEwVPtHYEJgx0qzttCbcKFpxrCQn2HYbwCv2c+7JwH4BgEzFkUGpn4A== - dependencies: - detect-libc "^1.0.3" - mkdirp "^0.5.5" - needle "^2.5.2" - nopt "^4.0.3" - npm-packlist "^1.4.8" - npmlog "^4.1.2" - rc "^1.2.8" - rimraf "^2.7.1" - semver "^5.7.1" - tar "^4.4.13" - node-releases@^2.0.14: version "2.0.14" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== - node-stream-zip@^1.9.1: version "1.15.0" resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" integrity sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw== -nopt@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -9887,9 +9007,9 @@ nopt@^6.0.0: abbrev "^1.0.0" nopt@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.1.0.tgz#91f6a3366182176e72ecab93a09c19b63b485f28" - integrity sha512-ZFPLe9Iu0tnx7oWhFxAo4s7QTn8+NNDDxYNaKLjE7Dp0tbakQ3M1QhQzsnzXHQBTUO3K9BmwaxnyO8Ayn2I95Q== + version "7.2.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.0.tgz#067378c68116f602f552876194fd11f1292503d7" + integrity sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA== dependencies: abbrev "^2.0.0" @@ -9938,20 +9058,13 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -npm-bundled@^1.0.1, npm-bundled@^1.1.1, npm-bundled@^1.1.2: +npm-bundled@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== dependencies: npm-normalize-package-bin "^1.0.1" -npm-bundled@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-2.0.1.tgz#94113f7eb342cd7a67de1e789f896b04d2c600f4" - integrity sha512-gZLxXdjEzE/+mOstGDqR6b0EkhJ+kM6fxM6vUuckuctuVPh80Q6pw/rSZj9s4Gex9GxWtIicO1pc8DB9KZWudw== - dependencies: - npm-normalize-package-bin "^2.0.0" - npm-bundled@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7" @@ -9959,17 +9072,10 @@ npm-bundled@^3.0.0: dependencies: npm-normalize-package-bin "^3.0.0" -npm-install-checks@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-5.0.0.tgz#5ff27d209a4e3542b8ac6b0c1db6063506248234" - integrity sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA== - dependencies: - semver "^7.1.1" - npm-install-checks@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.1.1.tgz#b459b621634d06546664207fde16810815808db1" - integrity sha512-dH3GmQL4vsPtld59cOn8uY0iOqRmqKvV+DLGwNXV/Q7MDgD2QfOADWd/mFXcIE5LVhYYGjA3baz6W9JneqnuCw== + version "6.3.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" + integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== dependencies: semver "^7.1.1" @@ -9983,10 +9089,10 @@ npm-normalize-package-bin@^2.0.0: resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-2.0.0.tgz#9447a1adaaf89d8ad0abe24c6c84ad614a675fff" integrity sha512-awzfKUO7v0FscrSpRoogyNm0sajikhBWpU0QMrW09AMi9n1PoKU6WaIqUzuJSQnpciZZmJ/jMZ2Egfmb/9LiWQ== -npm-normalize-package-bin@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.0.tgz#6097436adb4ef09e2628b59a7882576fe53ce485" - integrity sha512-g+DPQSkusnk7HYXr75NtzkIP4+N81i3RPsGFidF3DzHd9MT9wWngmqoeg/fnHFz5MNdtG4w03s+QnhewSLTT2Q== +npm-normalize-package-bin@^3.0.0, npm-normalize-package-bin@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" + integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== npm-package-arg@8.1.1: version "8.1.1" @@ -10007,7 +9113,7 @@ npm-package-arg@^10.0.0, npm-package-arg@^10.1.0: semver "^7.3.5" validate-npm-package-name "^5.0.0" -npm-package-arg@^9.0.0, npm-package-arg@^9.0.1: +npm-package-arg@^9.0.1: version "9.1.2" resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.1.2.tgz#fc8acecb00235f42270dda446f36926ddd9ac2bc" integrity sha512-pzd9rLEx4TfNJkovvlBSLGhq31gGu2QDexFPWT19yCDh0JgnRhlBLNo5759N0AJmBk+kQ9Y/hXoLnlgFD+ukmg== @@ -10027,25 +9133,6 @@ npm-packlist@5.1.1: npm-bundled "^1.1.2" npm-normalize-package-bin "^1.0.1" -npm-packlist@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" - integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-normalize-package-bin "^1.0.1" - -npm-packlist@^5.1.0: - version "5.1.3" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.3.tgz#69d253e6fd664b9058b85005905012e00e69274b" - integrity sha512-263/0NGrn32YFYi4J533qzrQ/krmmrWwhKkzwTuM4f/07ug51odoaNjUexxO4vxlzURHcmYMH1QjvHjsNDKLVg== - dependencies: - glob "^8.0.1" - ignore-walk "^5.0.1" - npm-bundled "^2.0.0" - npm-normalize-package-bin "^2.0.0" - npm-packlist@^7.0.0: version "7.0.4" resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32" @@ -10053,20 +9140,10 @@ npm-packlist@^7.0.0: dependencies: ignore-walk "^6.0.0" -npm-pick-manifest@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-7.0.2.tgz#1d372b4e7ea7c6712316c0e99388a73ed3496e84" - integrity sha512-gk37SyRmlIjvTfcYl6RzDbSmS9Y4TOBXfsPnoYqTHARNgWbyDiCSMLUpmALDj4jjcTZpURiEfsSHJj9k7EV4Rw== - dependencies: - npm-install-checks "^5.0.0" - npm-normalize-package-bin "^2.0.0" - npm-package-arg "^9.0.0" - semver "^7.3.5" - npm-pick-manifest@^8.0.0, npm-pick-manifest@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.1.tgz#c6acd97d1ad4c5dbb80eac7b386b03ffeb289e5f" - integrity sha512-mRtvlBjTsJvfCCdmPtiu2bdlx8d/KXtF7yNXNWe7G0Z36qWA9Ny5zXsI2PfBZEv7SXgoxTmNaTzGSbbzDZChoA== + version "8.0.2" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz#2159778d9c7360420c925c1a2287b5a884c713aa" + integrity sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg== dependencies: npm-install-checks "^6.0.0" npm-normalize-package-bin "^3.0.0" @@ -10086,7 +9163,7 @@ npm-registry-fetch@14.0.3: npm-package-arg "^10.0.0" proc-log "^3.0.0" -npm-registry-fetch@^13.0.0, npm-registry-fetch@^13.0.1: +npm-registry-fetch@^13.0.0: version "13.3.1" resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-13.3.1.tgz#bb078b5fa6c52774116ae501ba1af2a33166af7e" integrity sha512-eukJPi++DKRTjSBRcDZSDDsGqRK3ehbxfFUcgaRd0Yp6kRwOwh2WVn0r+8rMB4nnuzvAk6rQVzl6K5CkYOmnvw== @@ -10100,12 +9177,12 @@ npm-registry-fetch@^13.0.0, npm-registry-fetch@^13.0.1: proc-log "^2.0.0" npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3: - version "14.0.4" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.4.tgz#43dfa55ce7c0d0c545d625c7a916bab5b95f7038" - integrity sha512-pMS2DRkwg+M44ct65zrN/Cr9IHK1+n6weuefAo6Er4lc+/8YBCU0Czq04H3ZiSigluh7pb2rMM5JpgcytctB+Q== + version "14.0.5" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" + integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== dependencies: make-fetch-happen "^11.0.0" - minipass "^4.0.0" + minipass "^5.0.0" minipass-fetch "^3.0.0" minipass-json-stream "^1.0.1" minizlib "^2.1.2" @@ -10136,16 +9213,6 @@ npmlog@6.0.2, npmlog@^6.0.0, npmlog@^6.0.2: gauge "^4.0.3" set-blocking "^2.0.0" -npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== - dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" - npmlog@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" @@ -10171,21 +9238,16 @@ nullthrows@^1.1.1: resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== - -nx@15.9.2, "nx@>=15.5.2 < 16": - version "15.9.2" - resolved "https://registry.yarnpkg.com/nx/-/nx-15.9.2.tgz#d7ace1e5ae64a47f1b553dc5da08dbdd858bde96" - integrity sha512-wtcs+wsuplSckvgk+bV+/XuGlo+sVWzSG0RpgWBjQYeqA3QsVFEAPVY66Z5cSoukDbTV77ddcAjEw+Rz8oOR1A== +nx@15.9.7, "nx@>=15.5.2 < 16": + version "15.9.7" + resolved "https://registry.yarnpkg.com/nx/-/nx-15.9.7.tgz#f0e713cedb8637a517d9c4795c99afec4959a1b6" + integrity sha512-1qlEeDjX9OKZEryC8i4bA+twNg+lB5RKrozlNwWx/lLJHqWPUfvUTvxh+uxlPYL9KzVReQjUuxMLFMsHNqWUrA== dependencies: - "@nrwl/cli" "15.9.2" - "@nrwl/tao" "15.9.2" + "@nrwl/cli" "15.9.7" + "@nrwl/tao" "15.9.7" "@parcel/watcher" "2.0.4" "@yarnpkg/lockfile" "^1.1.0" - "@yarnpkg/parsers" "^3.0.0-rc.18" + "@yarnpkg/parsers" "3.0.0-rc.46" "@zkochan/js-yaml" "0.0.6" axios "^1.0.0" chalk "^4.1.0" @@ -10206,7 +9268,7 @@ nx@15.9.2, "nx@>=15.5.2 < 16": minimatch "3.0.5" npm-run-path "^4.0.1" open "^8.4.0" - semver "7.3.4" + semver "7.5.4" string-width "^4.2.3" strong-log-transformer "^2.1.0" tar-stream "~2.2.0" @@ -10217,41 +9279,27 @@ nx@15.9.2, "nx@>=15.5.2 < 16": yargs "^17.6.2" yargs-parser "21.1.1" optionalDependencies: - "@nrwl/nx-darwin-arm64" "15.9.2" - "@nrwl/nx-darwin-x64" "15.9.2" - "@nrwl/nx-linux-arm-gnueabihf" "15.9.2" - "@nrwl/nx-linux-arm64-gnu" "15.9.2" - "@nrwl/nx-linux-arm64-musl" "15.9.2" - "@nrwl/nx-linux-x64-gnu" "15.9.2" - "@nrwl/nx-linux-x64-musl" "15.9.2" - "@nrwl/nx-win32-arm64-msvc" "15.9.2" - "@nrwl/nx-win32-x64-msvc" "15.9.2" - -ob1@0.73.9: - version "0.73.9" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.9.tgz#d5677a0dd3e2f16ad84231278d79424436c38c59" - integrity sha512-kHOzCOFXmAM26fy7V/YuXNKne2TyRiXbFAvPBIbuedJCZZWQZHLdPzMeXJI4Egt6IcfDttRzN3jQ90wOwq1iNw== - -object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: + "@nrwl/nx-darwin-arm64" "15.9.7" + "@nrwl/nx-darwin-x64" "15.9.7" + "@nrwl/nx-linux-arm-gnueabihf" "15.9.7" + "@nrwl/nx-linux-arm64-gnu" "15.9.7" + "@nrwl/nx-linux-arm64-musl" "15.9.7" + "@nrwl/nx-linux-x64-gnu" "15.9.7" + "@nrwl/nx-linux-x64-musl" "15.9.7" + "@nrwl/nx-win32-arm64-msvc" "15.9.7" + "@nrwl/nx-win32-x64-msvc" "15.9.7" + +ob1@0.73.10: + version "0.73.10" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.10.tgz#bf0a2e8922bb8687ddca82327c5cf209414a1bd4" + integrity sha512-aO6EYC+QRRCkZxVJhCWhLKgVjhNuD6Gu1riGjxrIm89CqLsmKgxzYDDEsktmKsoDeRdWGQM5EdMzXDl5xcVfsw== + +object-assign@^4, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.10.3, object-inspect@^1.12.3, object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - -object-inspect@^1.13.1: +object-inspect@^1.10.3, object-inspect@^1.13.1, object-inspect@^1.9.0: version "1.13.1" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== @@ -10261,38 +9309,43 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" + call-bind "^1.0.5" + define-properties "^1.2.1" has-symbols "^1.0.3" object-keys "^1.1.1" -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== +object.fromentries@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== dependencies: - isobject "^3.0.1" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" -object.values@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" - integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== +object.groupby@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + +object.values@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" on-finished@2.4.1: version "2.4.1" @@ -10355,17 +9408,17 @@ optionator@^0.8.1: type-check "~0.3.2" word-wrap "~1.2.3" -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" ora@^5.4.1: version "5.4.1" @@ -10382,24 +9435,11 @@ ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== - os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== -osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== - dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" - p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -10508,37 +9548,34 @@ p-waterfall@2.1.1: dependencies: p-reduce "^2.0.0" -pacote@13.6.2, pacote@^13.6.1: - version "13.6.2" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.6.2.tgz#0d444ba3618ab3e5cd330b451c22967bbd0ca48a" - integrity sha512-Gu8fU3GsvOPkak2CkbojR7vjs3k3P9cA6uazKTHdsdV0gpCEQq2opelnEv30KRQWgVzP5Vd/5umjcedma3MKtg== +pacote@15.1.1: + version "15.1.1" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.1.1.tgz#94d8c6e0605e04d427610b3aacb0357073978348" + integrity sha512-eeqEe77QrA6auZxNHIp+1TzHQ0HBKf5V6c8zcaYZ134EJe1lCi+fjXATkNiEEfbG+e50nu02GLvUtmZcGOYabQ== dependencies: - "@npmcli/git" "^3.0.0" - "@npmcli/installed-package-contents" "^1.0.7" - "@npmcli/promise-spawn" "^3.0.0" - "@npmcli/run-script" "^4.1.0" - cacache "^16.0.0" - chownr "^2.0.0" - fs-minipass "^2.1.0" - infer-owner "^1.0.4" - minipass "^3.1.6" - mkdirp "^1.0.4" - npm-package-arg "^9.0.0" - npm-packlist "^5.1.0" - npm-pick-manifest "^7.0.0" - npm-registry-fetch "^13.0.1" - proc-log "^2.0.0" - promise-retry "^2.0.1" - read-package-json "^5.0.0" - read-package-json-fast "^2.0.3" - rimraf "^3.0.2" - ssri "^9.0.0" + "@npmcli/git" "^4.0.0" + "@npmcli/installed-package-contents" "^2.0.1" + "@npmcli/promise-spawn" "^6.0.1" + "@npmcli/run-script" "^6.0.0" + cacache "^17.0.0" + fs-minipass "^3.0.0" + minipass "^4.0.0" + npm-package-arg "^10.0.0" + npm-packlist "^7.0.0" + npm-pick-manifest "^8.0.0" + npm-registry-fetch "^14.0.0" + proc-log "^3.0.0" + promise-retry "^2.0.1" + read-package-json "^6.0.0" + read-package-json-fast "^3.0.0" + sigstore "^1.0.0" + ssri "^10.0.0" tar "^6.1.11" pacote@^15.0.0, pacote@^15.0.8: - version "15.1.2" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.1.2.tgz#78b4c1403231fab368c752943f1969c6d8f026bb" - integrity sha512-EAGJrMiIjBTBB6tWGrx9hFJTOo14B3HSAoa/W9SawFEBhUqjxN7qqaFlGVF9jfY/mIri8Mb2xafmkRgWxYXxIQ== + version "15.2.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.2.0.tgz#0f0dfcc3e60c7b39121b2ac612bf8596e95344d3" + integrity sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA== dependencies: "@npmcli/git" "^4.0.0" "@npmcli/installed-package-contents" "^2.0.1" @@ -10546,7 +9583,7 @@ pacote@^15.0.0, pacote@^15.0.8: "@npmcli/run-script" "^6.0.0" cacache "^17.0.0" fs-minipass "^3.0.0" - minipass "^4.0.0" + minipass "^5.0.0" npm-package-arg "^10.0.0" npm-packlist "^7.0.0" npm-pick-manifest "^8.0.0" @@ -10617,11 +9654,6 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -10652,13 +9684,13 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.7.0.tgz#99c741a2cfbce782294a39994d63748b5a24f6db" - integrity sha512-UkZUeDjczjYRE495+9thsgcVgsaCPkaw80slmfVFgllxY+IO8ubTsOpFVjDPROBqJdHfVPUFRHPBV/WciOVfWg== +path-scurry@^1.10.1, path-scurry@^1.6.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== dependencies: - lru-cache "^9.0.0" - minipass "^5.0.0" + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-to-regexp@0.1.7: version "0.1.7" @@ -10677,6 +9709,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +peek-readable@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" + integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -10707,10 +9744,10 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pirates@^4.0.4, pirates@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== +pirates@^4.0.4, pirates@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== pkg-dir@^3.0.0: version "3.0.0" @@ -10726,15 +9763,10 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - postcss-selector-parser@^6.0.10: - version "6.0.11" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" - integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== + version "6.0.15" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.15.tgz#11cc2b21eebc0b99ea374ffb9887174855a01535" + integrity sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw== dependencies: cssesc "^3.0.0" util-deprecate "^1.0.2" @@ -10780,16 +9812,7 @@ pretty-format@^26.5.2, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" -pretty-format@^29.0.0, pretty-format@^29.5.0: - version "29.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.5.0.tgz#283134e74f70e2e3e7229336de0e4fce94ccde5a" - integrity sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw== - dependencies: - "@jest/schemas" "^29.4.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -pretty-format@^29.7.0: +pretty-format@^29.0.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== @@ -10813,11 +9836,6 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - promise-all-reject-late@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz#f8ebf13483e5ca91ad809ccc2fcf25f26f8643c2" @@ -10863,7 +9881,7 @@ promzard@^0.3.0: dependencies: read "1" -prop-types@*: +prop-types@^15.8.1: version "15.8.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== @@ -10902,9 +9920,9 @@ protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: long "^4.0.0" protobufjs@^7.2.4: - version "7.2.5" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.5.tgz#45d5c57387a6d29a17aab6846dcc283f9b8e7f2d" - integrity sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A== + version "7.2.6" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.2.6.tgz#4a0ccd79eb292717aacf07530a07e0ed20278215" + integrity sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -10946,21 +9964,21 @@ pump@^3.0.0: once "^1.3.1" punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== pure-rand@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.2.tgz#a9c2ddcae9b68d736a8163036f088a2781c8b306" - integrity sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ== + version "6.0.4" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.4.tgz#50b737f6a925468679bff00ad20eade53f37d5c7" + integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== -pvtsutils@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.2.tgz#9f8570d132cdd3c27ab7d51a2799239bf8d8d5de" - integrity sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ== +pvtsutils@^1.3.2, pvtsutils@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/pvtsutils/-/pvtsutils-1.3.5.tgz#b8705b437b7b134cd7fd858f025a23456f1ce910" + integrity sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA== dependencies: - tslib "^2.4.0" + tslib "^2.6.1" pvutils@^1.1.3: version "1.1.3" @@ -10979,6 +9997,13 @@ qs@6.11.0: dependencies: side-channel "^1.0.4" +qs@^6.11.2: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + query-string@^7.0.1: version "7.1.3" resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" @@ -11014,16 +10039,6 @@ raw-body@2.5.1: iconv-lite "0.4.24" unpipe "1.0.0" -rc@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - rdf-canonize@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/rdf-canonize/-/rdf-canonize-3.4.0.tgz#87f88342b173cc371d812a07de350f0c1aa9f058" @@ -11054,14 +10069,14 @@ react-is@^17.0.1: resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== -react-native-codegen@^0.71.5: - version "0.71.5" - resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.71.5.tgz#454a42a891cd4ca5fc436440d301044dc1349c14" - integrity sha512-rfsuc0zkuUuMjFnrT55I1mDZ+pBRp2zAiRwxck3m6qeGJBGK5OV5JH66eDQ4aa+3m0of316CqrJDRzVlYufzIg== +react-native-codegen@^0.71.6: + version "0.71.6" + resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.71.6.tgz#481a610c3af9135b09e1e031da032e7270e0cc1b" + integrity sha512-e5pR4VldIhEaFctfSAEgxbng0uG4gjBQxAHes3EKLdosH/Av90pQfSe9IDVdFIngvNPzt8Y14pNjrtqov/yNIg== dependencies: "@babel/parser" "^7.14.0" flow-parser "^0.185.0" - jscodeshift "^0.13.1" + jscodeshift "^0.14.0" nullthrows "^1.1.1" react-native-fs@^2.20.0: @@ -11073,16 +10088,16 @@ react-native-fs@^2.20.0: utf8 "^3.0.0" react-native-get-random-values@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/react-native-get-random-values/-/react-native-get-random-values-1.8.0.tgz#1cb4bd4bd3966a356e59697b8f372999fe97cb16" - integrity sha512-H/zghhun0T+UIJLmig3+ZuBCvF66rdbiWUfRSNS6kv5oDSpa1ZiVyvRWtuPesQpT8dXj+Bv7WJRQOUP+5TB1sA== + version "1.10.0" + resolved "https://registry.yarnpkg.com/react-native-get-random-values/-/react-native-get-random-values-1.10.0.tgz#c2c5f12a4ef8b1175145347b4a4b9f9a40d9ffc8" + integrity sha512-gZ1zbXhbb8+Jy9qYTV8c4Nf45/VB4g1jmXuavY5rPfUn7x3ok9Vl3FTl0dnE92Z4FFtfbUNNwtSfcmomdtWg+A== dependencies: fast-base64-decode "^1.0.0" -react-native-gradle-plugin@^0.71.17: - version "0.71.17" - resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.17.tgz#cf780a27270f0a32dca8184eff91555d7627dd00" - integrity sha512-OXXYgpISEqERwjSlaCiaQY6cTY5CH6j73gdkWpK0hedxtiWMWgH+i5TOi4hIGYitm9kQBeyDu+wim9fA8ROFJA== +react-native-gradle-plugin@^0.71.19: + version "0.71.19" + resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.19.tgz#3379e28341fcd189bc1f4691cefc84c1a4d7d232" + integrity sha512-1dVk9NwhoyKHCSxcrM6vY6cxmojeATsBobDicX0ZKr7DgUF2cBQRTKsimQFvzH8XhOVXyH8p4HyDSZNIFI8OlQ== react-native-securerandom@^0.1.1: version "0.1.1" @@ -11092,19 +10107,20 @@ react-native-securerandom@^0.1.1: base64-js "*" react-native@^0.71.4: - version "0.71.7" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.71.7.tgz#d0ae409f6ee4fc7e7a876b4ca9d8d28934133228" - integrity sha512-Id6iRLS581fJMFGbBl1jP5uSmjExtGOvw5Gvh7694zISXjsRAsFMmU+izs0pyCLqDBoHK7y4BT7WGPGw693nYw== + version "0.71.16" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.71.16.tgz#b9fc5b8e4523e85015e6c52da75d45840855bf42" + integrity sha512-fyeudppU0xATgGweyPVcOgYrhLAgBvvIEqUfG5wD+U0ZpVe3f7YQpDsqVOrD0ScomWmraFw634D4zFyenHMSAw== dependencies: "@jest/create-cache-key-function" "^29.2.1" - "@react-native-community/cli" "10.2.2" + "@react-native-community/cli" "10.2.6" "@react-native-community/cli-platform-android" "10.2.0" - "@react-native-community/cli-platform-ios" "10.2.1" + "@react-native-community/cli-platform-ios" "10.2.5" "@react-native/assets" "1.0.0" "@react-native/normalize-color" "2.1.0" "@react-native/polyfills" "2.0.0" abort-controller "^3.0.0" anser "^1.4.9" + ansi-regex "^5.0.0" base64-js "^1.1.2" deprecated-react-native-prop-types "^3.0.1" event-target-shim "^5.0.1" @@ -11112,16 +10128,16 @@ react-native@^0.71.4: jest-environment-node "^29.2.1" jsc-android "^250231.0.0" memoize-one "^5.0.0" - metro-react-native-babel-transformer "0.73.9" - metro-runtime "0.73.9" - metro-source-map "0.73.9" + metro-react-native-babel-transformer "0.73.10" + metro-runtime "0.73.10" + metro-source-map "0.73.10" mkdirp "^0.5.1" nullthrows "^1.1.1" pretty-format "^26.5.2" promise "^8.3.0" react-devtools-core "^4.26.1" - react-native-codegen "^0.71.5" - react-native-gradle-plugin "^0.71.17" + react-native-codegen "^0.71.6" + react-native-gradle-plugin "^0.71.19" react-refresh "^0.4.0" react-shallow-renderer "^16.15.0" regenerator-runtime "^0.13.2" @@ -11191,11 +10207,11 @@ read-package-json@^5.0.0: npm-normalize-package-bin "^2.0.0" read-package-json@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.1.tgz#566cb06bc05dbddefba4607e9096d5a9efbcd836" - integrity sha512-AaHqXxfAVa+fNL07x8iAghfKOds/XXsu7zoouIVsbm7PEbQ3nMWXlvjcbrNLjElnUHWQtAo4QEa0RXuvD4XlpA== + version "6.0.4" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" + integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== dependencies: - glob "^9.3.0" + glob "^10.2.2" json-parse-even-better-errors "^3.0.0" normalize-package-data "^5.0.0" npm-normalize-package-bin "^3.0.0" @@ -11252,7 +10268,7 @@ readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stre string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: +readable-stream@^2.2.2, readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -11265,15 +10281,12 @@ readable-stream@^2.0.6, readable-stream@^2.2.2, readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.3.0.tgz#0914d0c72db03b316c9733bb3461d64a3cc50cba" - integrity sha512-MuEnA0lbSi7JS8XM+WNJlWZkHAAdm7gETHdFK//Q/mChGyj2akEFtdLZh32jSdkWGbRwCW9pn6g3LWDdDeZnBQ== +readable-web-to-node-stream@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== dependencies: - abort-controller "^3.0.0" - buffer "^6.0.3" - events "^3.3.0" - process "^0.11.10" + readable-stream "^3.6.0" readline@^1.3.0: version "1.3.0" @@ -11285,12 +10298,12 @@ readonly-date@^1.0.0: resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== -recast@^0.20.4: - version "0.20.5" - resolved "https://registry.yarnpkg.com/recast/-/recast-0.20.5.tgz#8e2c6c96827a1b339c634dd232957d230553ceae" - integrity sha512-E5qICoPoNL4yU0H0NoBDntNB0Q5oMSNh9usFctYniLBluTthi3RsQVBXIJNbApOlvSwW/RGxIuokPcAc59J5fQ== +recast@^0.21.0: + version "0.21.5" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.21.5.tgz#e8cd22bb51bcd6130e54f87955d33a2b2e57b495" + integrity sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg== dependencies: - ast-types "0.14.2" + ast-types "0.15.2" esprima "~4.0.0" source-map "~0.6.1" tslib "^2.0.1" @@ -11324,14 +10337,14 @@ ref-struct-di@1.1.1, ref-struct-di@^1.1.0, ref-struct-di@^1.1.1: debug "^3.1.0" reflect-metadata@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" - integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + version "0.1.14" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.14.tgz#24cf721fe60677146bb77eeb0e1f9dece3d65859" + integrity sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A== regenerate-unicode-properties@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" - integrity sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ== + version "10.1.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== dependencies: regenerate "^1.4.2" @@ -11340,27 +10353,15 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.2: +regenerator-runtime@^0.13.2: version "0.13.11" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.4.3: - version "1.5.0" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" - integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - functions-have-names "^1.2.3" +regenerator-runtime@^0.14.0: + version "0.14.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" + integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw== regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: version "1.5.1" @@ -11390,16 +10391,6 @@ regjsparser@^0.9.1: dependencies: jsesc "~0.5.0" -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -11437,22 +10428,22 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== resolve.exports@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== -resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.1: - version "1.22.2" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== +resolve@^1.10.0, resolve@^1.14.2, resolve@^1.20.0, resolve@^1.22.4: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: - is-core-module "^2.11.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -11464,11 +10455,6 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -11479,17 +10465,10 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rfc4648@1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/rfc4648/-/rfc4648-1.4.0.tgz#c75b2856ad2e2d588b6ddb985d556f1f7f2a2abd" - integrity sha512-3qIzGhHlMHA6PoT6+cdPKZ+ZqtxkIvg8DZGKA5z6PQ33/uuhoJ+Ws/D/J9rXW6gXodgH8QYlz2UCl+sdUDmNIg== - -rimraf@^2.7.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" +rfc4648@1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/rfc4648/-/rfc4648-1.5.2.tgz#cf5dac417dd83e7f4debf52e3797a723c1373383" + integrity sha512-tLOizhR6YGovrEBLatX1sdcuhoSCXddw3mqNVAcKxGJ+J0hFeJ+SjeWCv5UPA/WU3YzWPPuCVYgXBKZUPGpKtg== rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" @@ -11537,19 +10516,19 @@ rxjs@^6.6.0: tslib "^1.9.0" rxjs@^7.2.0, rxjs@^7.5.5, rxjs@^7.8.0: - version "7.8.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" - integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== dependencies: tslib "^2.1.0" safe-array-concat@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" - integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.0.tgz#8d0cae9cb806d6d1c06e08ab13d847293ebe0692" + integrity sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" + call-bind "^1.0.5" + get-intrinsic "^1.2.2" has-symbols "^1.0.3" isarray "^2.0.5" @@ -11558,37 +10537,25 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + version "1.0.2" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.2.tgz#3ba32bdb3ea35f940ee87e5087c60ee786c3f6c5" + integrity sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ== dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" + call-bind "^1.0.5" + get-intrinsic "^1.2.2" is-regex "^1.1.4" -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" - "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - scheduler@^0.23.0: version "0.23.0" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" @@ -11596,18 +10563,11 @@ scheduler@^0.23.0: dependencies: loose-envify "^1.1.0" -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0: version "5.7.2" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@7.3.4: - version "7.3.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97" - integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw== - dependencies: - lru-cache "^6.0.0" - semver@7.3.8: version "7.3.8" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" @@ -11615,18 +10575,18 @@ semver@7.3.8: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: +semver@7.5.4, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + send@0.18.0: version "0.18.0" resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" @@ -11668,20 +10628,21 @@ serve-static@1.15.0, serve-static@^1.13.1: parseurl "~1.3.3" send "0.18.0" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== set-function-length@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" - integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + version "1.2.0" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.0.tgz#2f81dc6c16c7059bda5ab7c82c11f03a515ed8e1" + integrity sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w== dependencies: define-data-property "^1.1.1" - get-intrinsic "^1.2.1" + function-bind "^1.1.2" + get-intrinsic "^1.2.2" gopd "^1.0.1" - has-property-descriptors "^1.0.0" + has-property-descriptors "^1.0.1" set-function-name@^2.0.0: version "2.0.1" @@ -11692,16 +10653,6 @@ set-function-name@^2.0.0: functions-have-names "^1.2.3" has-property-descriptors "^1.0.0" -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -11712,6 +10663,14 @@ setprototypeof@1.2.0: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== +sha.js@^2.4.11: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shallow-clone@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" @@ -11762,14 +10721,21 @@ signal-exit@3.0.7, signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, s resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -sigstore@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.4.0.tgz#2e3a28c08b1b8246744c27cfb179c525c3f164d8" - integrity sha512-N7TRpSbFjY/TrFDg6yGAQSYBrQ5s6qmPiq4pD6fkv1LoyfMsLG0NwZWG2s5q+uttLHgyVyTa0Rogx2P78rN8kQ== +signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +sigstore@^1.0.0, sigstore@^1.3.0, sigstore@^1.4.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" + integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== dependencies: - "@sigstore/protobuf-specs" "^0.1.0" + "@sigstore/bundle" "^1.1.0" + "@sigstore/protobuf-specs" "^0.2.0" + "@sigstore/sign" "^1.0.0" + "@sigstore/tuf" "^1.0.3" make-fetch-happen "^11.0.1" - tuf-js "^1.1.3" sisteransi@^1.0.5: version "1.0.5" @@ -11781,11 +10747,6 @@ slash@3.0.0, slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - slice-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -11800,36 +10761,6 @@ smart-buffer@^4.2.0: resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - socks-proxy-agent@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" @@ -11854,17 +10785,6 @@ sort-keys@^2.0.0: dependencies: is-plain-obj "^1.0.0" -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.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" @@ -11881,11 +10801,6 @@ source-map-support@^0.5.16, source-map-support@~0.5.20: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - source-map@^0.5.6: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -11910,9 +10825,9 @@ spdx-correct@^3.0.0: spdx-license-ids "^3.0.0" spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + version "2.4.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz#c07a4ede25b16e4f78e6707bbd84b15a45c19c1b" + integrity sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw== spdx-expression-parse@^3.0.0: version "3.0.1" @@ -11923,22 +10838,15 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + version "3.0.16" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - split2@^3.0.0: version "3.2.2" resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" @@ -11966,11 +10874,11 @@ ssri@9.0.1, ssri@^9.0.0: minipass "^3.1.1" ssri@^10.0.0, ssri@^10.0.1: - version "10.0.3" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.3.tgz#7f83da39058ca1d599d174e9eee4237659710bf4" - integrity sha512-lJtX/BFPI/VEtxZmLfeh7pzisIs6micwZ3eruD3+ds9aPsXKlYpwDS2Q7omD6WC42WO9+bnUSzlMmfv8uK8meg== + version "10.0.5" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" + integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== dependencies: - minipass "^4.0.0" + minipass "^7.0.3" stack-utils@^2.0.3: version "2.0.6" @@ -11998,14 +10906,6 @@ static-eval@2.0.2: dependencies: escodegen "^1.8.1" -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" @@ -12039,16 +10939,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", 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" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -12057,7 +10948,16 @@ string-width@^1.0.1: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.matchall@^4.0.8: +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +string.prototype.matchall@^4.0.10: version "4.0.10" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== @@ -12072,15 +10972,6 @@ string.prototype.matchall@^4.0.8: set-function-name "^2.0.0" side-channel "^1.0.4" -string.prototype.trim@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" - integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - string.prototype.trim@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" @@ -12090,15 +10981,6 @@ string.prototype.trim@^1.2.8: define-properties "^1.2.0" es-abstract "^1.22.1" -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - string.prototype.trimend@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" @@ -12108,15 +10990,6 @@ string.prototype.trimend@^1.0.7: define-properties "^1.2.0" es-abstract "^1.22.1" -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - string.prototype.trimstart@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" @@ -12140,12 +11013,12 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", 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" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: - ansi-regex "^2.0.0" + ansi-regex "^5.0.1" strip-ansi@^5.0.0, strip-ansi@^5.2.0: version "5.2.0" @@ -12154,12 +11027,12 @@ strip-ansi@^5.0.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.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" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== dependencies: - ansi-regex "^5.0.1" + ansi-regex "^6.0.1" strip-bom@^3.0.0: version "3.0.0" @@ -12188,16 +11061,11 @@ strip-indent@^3.0.0: dependencies: min-indent "^1.0.0" -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +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" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== -strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - strnum@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" @@ -12212,6 +11080,14 @@ strong-log-transformer@2.1.0, strong-log-transformer@^2.1.0: minimist "^1.2.0" through "^2.3.4" +strtok3@^6.2.4: + version "6.3.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" + integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^4.1.0" + sudo-prompt@^9.0.0: version "9.2.1" resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.2.1.tgz#77efb84309c9ca489527a4e749f287e6bdd52afd" @@ -12248,14 +11124,6 @@ symbol-observable@^2.0.3: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== -synckit@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" - integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== - dependencies: - "@pkgr/utils" "^2.3.1" - tslib "^2.5.0" - table-layout@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" @@ -12294,27 +11162,14 @@ tar@6.1.11: mkdirp "^1.0.3" yallist "^4.0.0" -tar@^4.4.13: - version "4.4.19" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" - integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== - dependencies: - chownr "^1.1.4" - fs-minipass "^1.2.7" - minipass "^2.9.0" - minizlib "^1.3.3" - mkdirp "^0.5.5" - safe-buffer "^5.2.1" - yallist "^3.1.1" - tar@^6.1.11, tar@^6.1.2: - version "6.1.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.13.tgz#46e22529000f612180601a6fe0680e7da508847b" - integrity sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw== + version "6.2.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" + integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" - minipass "^4.0.0" + minipass "^5.0.0" minizlib "^2.1.1" mkdirp "^1.0.3" yallist "^4.0.0" @@ -12356,12 +11211,12 @@ tempy@1.0.0: unique-string "^2.0.0" terser@^5.15.0: - version "5.17.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.17.1.tgz#948f10830454761e2eeedc6debe45c532c83fd69" - integrity sha512-hVl35zClmpisy6oaoKALOpS0rDYLxRFLHhRuDlEGTKey9qHjS1w9GMORjuwIMt70Wan4lwsLYyWDVnWgF+KUEw== + version "5.27.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.27.0.tgz#70108689d9ab25fef61c4e93e808e9fd092bf20c" + integrity sha512-bi1HRwVRskAjheeYl291n3JC4GgO/Ty4z1nVs5AAsmonJulGxpSektecnNedrwK9C7vpvVtcX3cw00VSLt7U2A== dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" commander "^2.20.0" source-map-support "~0.5.20" @@ -12409,14 +11264,6 @@ through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -tiny-glob@^0.2.9: - version "0.2.9" - resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" - integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== - dependencies: - globalyzer "0.1.0" - globrex "^0.1.2" - tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -12441,21 +11288,6 @@ to-fast-properties@^2.0.0: resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - 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" @@ -12463,21 +11295,19 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - toidentifier@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +token-types@^4.1.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753" + integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + toml@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/toml/-/toml-3.0.0.tgz#342160f1af1904ec9d204d03a5d61222d762c5ee" @@ -12513,9 +11343,9 @@ ts-jest@^29.1.2: yargs-parser "^21.0.1" ts-node@^10.0.0, ts-node@^10.4.0: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + version "10.9.2" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.2.tgz#70f021c9e185bccdca820e26dc413805c101c71f" + integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== dependencies: "@cspotcode/source-map-support" "^0.8.0" "@tsconfig/node10" "^1.0.7" @@ -12536,10 +11366,10 @@ ts-typed-json@^0.3.2: resolved "https://registry.yarnpkg.com/ts-typed-json/-/ts-typed-json-0.3.2.tgz#f4f20f45950bae0a383857f7b0a94187eca1b56a" integrity sha512-Tdu3BWzaer7R5RvBIJcg9r8HrTZgpJmsX+1meXMJzYypbkj8NK2oJN0yvm4Dp/Iv6tzFa/L5jKRmEVTga6K3nA== -tsconfig-paths@^3.14.1: - version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" - integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== +tsconfig-paths@^3.15.0: + version "3.15.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" + integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== dependencies: "@types/json5" "^0.0.29" json5 "^1.0.2" @@ -12560,15 +11390,15 @@ tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" - integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.6.1, tslib@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== tslog@^4.8.2: - version "4.8.2" - resolved "https://registry.yarnpkg.com/tslog/-/tslog-4.8.2.tgz#dbb0c96249e387e8a711ae6e077330ba1ef102c9" - integrity sha512-eAKIRjxfSKYLs06r1wT7oou6Uv9VN6NW9g0JPidBlqQwPBBl5+84dm7r8zSOPVq1kyfEw1P6B3/FLSpZCorAgA== + version "4.9.2" + resolved "https://registry.yarnpkg.com/tslog/-/tslog-4.9.2.tgz#35de3a073784dfe3849caeaa028010c7a62b7f4a" + integrity sha512-wBM+LRJoNl34Bdu8mYEFxpvmOUedpNUwMNQB/NcuPIZKwdDde6xLHUev3bBjXQU7gdurX++X/YE7gLH8eXYsiQ== tsutils@^3.21.0: version "3.21.0" @@ -12584,13 +11414,14 @@ tsyringe@^4.8.0: dependencies: tslib "^1.9.3" -tuf-js@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.4.tgz#e85a936b16859c7fae23e5f040bc0f7b559b3192" - integrity sha512-Lw2JRM3HTYhEtQJM2Th3aNCPbnXirtWMl065BawwmM2pX6XStH/ZO9e8T2hh0zk/HUa+1i6j+Lv6eDitKTau6A== +tuf-js@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" + integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== dependencies: - "@tufjs/models" "1.0.3" - make-fetch-happen "^11.0.1" + "@tufjs/models" "1.0.4" + debug "^4.3.4" + make-fetch-happen "^11.1.1" type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" @@ -12652,9 +11483,9 @@ type-fest@^0.8.1: integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== type-fest@^3.2.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.9.0.tgz#36a9e46e6583649f9e6098b267bc577275e9e4f4" - integrity sha512-hR8JP2e8UiH7SME5JZjsobBlEiatFoxpzCP+R3ZeCo7kAaG1jXQE5X/buLzogM6GJu8le9Y4OcfNuIQX0rZskA== + version "3.13.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-3.13.1.tgz#bb744c1f0678bea7543a2d1ec24e83e68e8c8706" + integrity sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g== type-is@^1.6.4, type-is@~1.6.18: version "1.6.18" @@ -12803,16 +11634,6 @@ unicode-property-aliases-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - unique-filename@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" @@ -12849,9 +11670,9 @@ unique-string@^2.0.0: crypto-random-string "^2.0.0" universal-user-agent@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" - integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== + version "6.0.1" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" + integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== universalify@^0.1.0: version "0.1.2" @@ -12859,36 +11680,20 @@ universalify@^0.1.0: integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - upath@2.0.1, upath@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== -update-browserslist-db@^1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" - integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - update-browserslist-db@^1.0.13: version "1.0.13" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" @@ -12904,21 +11709,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - use-sync-external-store@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - utf8@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" @@ -12955,13 +11750,13 @@ v8-compile-cache@2.3.0: integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== 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" - integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + version "9.2.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" + integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" + convert-source-map "^2.0.0" validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" @@ -12992,10 +11787,10 @@ validate-npm-package-name@^5.0.0: dependencies: builtins "^5.0.0" -validator@^13.7.0: - version "13.9.0" - resolved "https://registry.yarnpkg.com/validator/-/validator-13.9.0.tgz#33e7b85b604f3bbce9bb1a05d5c3e22e1c2ff855" - integrity sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA== +validator@^13.9.0: + version "13.11.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.11.0.tgz#23ab3fd59290c61248364eabf4067f04955fbb1b" + integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== varint@^6.0.0: version "6.0.0" @@ -13044,16 +11839,16 @@ web-streams-polyfill@^3.0.3: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.2.tgz#32e26522e05128203a7de59519be3c648004343b" integrity sha512-3pRGuxRF5gpuZc0W+EpwQRmCD7gRqcDOMt688KmdlDAgAyaB1XlN0zq2njfDNm44XVdIouE7pZ6GzbdyH47uIQ== -webcrypto-core@^1.7.7: - version "1.7.7" - resolved "https://registry.yarnpkg.com/webcrypto-core/-/webcrypto-core-1.7.7.tgz#06f24b3498463e570fed64d7cab149e5437b162c" - integrity sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g== +webcrypto-core@^1.7.8: + version "1.7.8" + resolved "https://registry.yarnpkg.com/webcrypto-core/-/webcrypto-core-1.7.8.tgz#056918036e846c72cfebbb04052e283f57f1114a" + integrity sha512-eBR98r9nQXTqXt/yDRtInszPMjTaSAMJAFDg2AHsgrnczawT1asx9YNBX6k5p+MekbPF4+s/UJJrr88zsTqkSg== dependencies: - "@peculiar/asn1-schema" "^2.3.6" + "@peculiar/asn1-schema" "^2.3.8" "@peculiar/json-schema" "^1.1.12" asn1js "^3.0.1" - pvtsutils "^1.3.2" - tslib "^2.4.0" + pvtsutils "^1.3.5" + tslib "^2.6.2" webcrypto-shim@^0.1.4: version "0.1.7" @@ -13066,9 +11861,9 @@ webidl-conversions@^3.0.0: integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== whatwg-fetch@^3.0.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + version "3.6.20" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.20.tgz#580ce6d791facec91d37c72890995a0b48d31c70" + integrity sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg== whatwg-url@^5.0.0: version "5.0.0" @@ -13105,18 +11900,6 @@ which-typed-array@^1.1.11, which-typed-array@^1.1.13: gopd "^1.0.1" has-tostringtag "^1.0.0" -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" - which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -13132,24 +11915,19 @@ which@^2.0.1, which@^2.0.2: isexe "^2.0.0" which@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/which/-/which-3.0.0.tgz#a9efd016db59728758a390d23f1687b6e8f59f8e" - integrity sha512-nla//68K9NU6yRiwDY/Q8aU6siKlSs64aEC7+IV56QoAuyQT2ovsJcgGYGyqMOmI/CGN1BOR6mM5EN0FBO+zyQ== + version "3.0.1" + resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" + integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== dependencies: isexe "^2.0.0" -wide-align@^1.1.0, wide-align@^1.1.2, wide-align@^1.1.5: +wide-align@^1.1.2, wide-align@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: string-width "^1.0.2 || 2 || 3 || 4" -word-wrap@^1.2.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f" - integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA== - word-wrap@~1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" @@ -13168,24 +11946,33 @@ wordwrapjs@^4.0.0: reduce-flatten "^2.0.0" typical "^5.2.0" -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== +wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== dependencies: ansi-styles "^4.0.0" string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -13217,12 +12004,12 @@ write-file-atomic@^4.0.2: signal-exit "^3.0.7" write-file-atomic@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.0.tgz#54303f117e109bf3d540261125c8ea5a7320fab0" - integrity sha512-R7NYMnHSlV42K54lwY9lvW6MnSm1HSJqZL3xiSgi9E7//FYaI74r2G0rd+/X6VAMkHEdzxQaU5HUOXWUz5kA/w== + version "5.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" + integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== dependencies: imurmurhash "^0.1.4" - signal-exit "^3.0.7" + signal-exit "^4.0.1" write-json-file@^3.2.0: version "3.2.0" @@ -13285,7 +12072,7 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: +yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== @@ -13301,9 +12088,9 @@ yaml@^1.10.0: integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yaml@^2.1.3: - version "2.2.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.2.2.tgz#ec551ef37326e6d42872dad1970300f8eb83a073" - integrity sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA== + version "2.3.4" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== yargs-parser@20.2.4: version "20.2.4" @@ -13359,9 +12146,9 @@ yargs@^15.1.0: yargs-parser "^18.1.2" yargs@^17.3.1, yargs@^17.5.1, yargs@^17.6.2: - version "17.7.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" - integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== dependencies: cliui "^8.0.1" escalade "^3.1.1"