diff --git a/package-lock.json b/package-lock.json index 34f08eda..b6a1a9d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@digicatapult/veritable-cloudagent", - "version": "0.4.0", + "version": "0.4.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@digicatapult/veritable-cloudagent", - "version": "0.4.0", + "version": "0.4.1", "license": "Apache-2.0", "dependencies": { "@aries-framework/anoncreds": "^0.4.0", diff --git a/package.json b/package.json index 16472015..869b5ff3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@digicatapult/veritable-cloudagent", - "version": "0.4.0", + "version": "0.4.1", "main": "build/index", "types": "build/index", "files": [ @@ -47,13 +47,11 @@ "@aries-framework/anoncreds-rs": "^0.4.0", "@aries-framework/askar": "^0.4.0", "@aries-framework/core": "^0.4.0", - "@aries-framework/node": "^0.4.0", "@hyperledger/anoncreds-nodejs": "^0.1.0", "@hyperledger/anoncreds-shared": "^0.1.0", "@hyperledger/aries-askar-nodejs": "^0.1.0", "@hyperledger/aries-askar-shared": "^0.1.0", - "@tsoa/runtime": "^4.1.3", "@types/ws": "^7.4.7", "body-parser": "^1.20.0", diff --git a/src/cliAgent.ts b/src/cliAgent.ts index 70156437..506d69c0 100644 --- a/src/cliAgent.ts +++ b/src/cliAgent.ts @@ -1,32 +1,19 @@ -import type { InitConfig } from '@aries-framework/core' -import type { WalletConfig } from '@aries-framework/core/build/types' +import type { InitConfig, WalletConfig } from '@aries-framework/core' -import { AnonCredsCredentialFormatService, AnonCredsModule } from '@aries-framework/anoncreds' -import { AnonCredsRsModule } from '@aries-framework/anoncreds-rs' -import { AskarModule } from '@aries-framework/askar' import { HttpOutboundTransport, WsOutboundTransport, LogLevel, Agent, - ConnectionsModule, - ProofsModule, - CredentialsModule, AutoAcceptCredential, AutoAcceptProof, - MediatorModule, - V2CredentialProtocol, } from '@aries-framework/core' - import { agentDependencies, HttpInboundTransport, WsInboundTransport } from '@aries-framework/node' -import { anoncreds } from '@hyperledger/anoncreds-nodejs' -import { ariesAskar } from '@hyperledger/aries-askar-nodejs' import { readFile } from 'fs/promises' import { setupServer } from './server' +import { getAgentModules, RestAgent } from './utils/agent' import { TsLogger } from './utils/logger' -import VeritableAnonCredsRegistry from './anoncreds' -import Ipfs from './ipfs' export type Transports = 'ws' | 'http' export type InboundTransport = { @@ -94,37 +81,18 @@ export async function runRestAgent(restConfig: AriesRestConfig) { logger, } - const agent = new Agent({ + const modules = getAgentModules({ + autoAcceptConnections, + autoAcceptProofs, + autoAcceptCredentials, + autoAcceptMediationRequests, + ipfsOrigin, + }) + + const agent: RestAgent = new Agent({ config: agentConfig, dependencies: agentDependencies, - modules: { - connections: new ConnectionsModule({ - autoAcceptConnections, - }), - proofs: new ProofsModule({ - autoAcceptProofs, - }), - credentials: new CredentialsModule<[V2CredentialProtocol<[AnonCredsCredentialFormatService]>]>({ - autoAcceptCredentials, - credentialProtocols: [ - new V2CredentialProtocol({ - credentialFormats: [new AnonCredsCredentialFormatService()], - }), - ], - }), - anoncreds: new AnonCredsModule({ - registries: [new VeritableAnonCredsRegistry(new Ipfs(ipfsOrigin))], - }), - anoncredsRs: new AnonCredsRsModule({ - anoncreds, - }), - askar: new AskarModule({ - ariesAskar, - }), - mediator: new MediatorModule({ - autoAcceptMediationRequests, - }), - }, + modules, }) // Register outbound transports @@ -140,6 +108,14 @@ export async function runRestAgent(restConfig: AriesRestConfig) { } await agent.initialize() + + const existingSecrets = await agent.modules.anoncreds.getLinkSecretIds() + if (existingSecrets.length === 0) { + await agent.modules.anoncreds.createLinkSecret({ + setAsDefault: true, + }) + } + const app = await setupServer(agent, { webhookUrl, port: adminPort, diff --git a/src/controllers/did/DidController.ts b/src/controllers/did/DidController.ts index 244404de..0a5770a9 100644 --- a/src/controllers/did/DidController.ts +++ b/src/controllers/did/DidController.ts @@ -1,10 +1,10 @@ -import type { DidResolutionResultProps } from '../types' +import type { DidCreateOptions, DidCreateResult, DidResolutionResultProps, ImportDidOptions } from '../types' -import { Agent } from '@aries-framework/core' -import { Controller, Example, Get, Path, Route, Tags } from 'tsoa' +import { Agent, AriesFrameworkError, TypedArrayEncoder } from '@aries-framework/core' +import { Body, Controller, Example, Get, Path, Post, Res, Route, Tags, TsoaResponse } from 'tsoa' import { injectable } from 'tsyringe' -import { Did, DidRecordExample } from '../examples' +import { Did, DidRecordExample, DidStateExample } from '../examples' @Tags('Dids') @Route('/dids') @@ -34,4 +34,60 @@ export class DidController extends Controller { return { ...resolveResult, didDocument: resolveResult.didDocument.toJSON() } } + + /** + * Import a Did to the Agent and return the did resolution result + * + * @param options + * @returns DidResolutionResultProps + */ + @Example(DidRecordExample) + @Post('/import') + public async importDid( + @Body() options: ImportDidOptions, + @Res() badRequestError: TsoaResponse<400, { reason: string }>, + @Res() internalServerError: TsoaResponse<500, { message: string }> + ) { + try { + const { privateKeys, ...rest } = options + await this.agent.dids.import({ + ...rest, + privateKeys: privateKeys?.map(({ keyType, privateKey }) => ({ + keyType, + privateKey: TypedArrayEncoder.fromString(privateKey), + })), + }) + return this.getDidRecordByDid(options.did) + } catch (error) { + if (error instanceof AriesFrameworkError) { + return badRequestError(400, { + reason: `Error importing Did - ${error.message}`, + }) + } + return internalServerError(500, { message: `something went wrong: ${error}` }) + } + } + + /** + * Create a Did and return the did resolution result + * + * @param options + * @returns DidResolutionResultProps + */ + @Example(DidStateExample) + @Post('/create') + public async createDid( + @Body() options: DidCreateOptions, + @Res() internalServerError: TsoaResponse<500, { message: string }> + ) { + const { didState } = await this.agent.dids.create(options) + + if (didState.state === 'failed') { + return internalServerError(500, { + message: `Error creating Did - ${didState.reason}`, + }) + } + + return didState + } } diff --git a/src/controllers/examples.ts b/src/controllers/examples.ts index 890fb757..4b77fd8a 100644 --- a/src/controllers/examples.ts +++ b/src/controllers/examples.ts @@ -120,6 +120,48 @@ export const DidRecordExample = { }, } +export const DidStateExample = { + state: 'finished' as const, + did: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + didDocument: { + '@context': [ + 'https://w3id.org/did/v1', + 'https://w3id.org/security/suites/ed25519-2018/v1', + 'https://w3id.org/security/suites/x25519-2019/v1', + ], + id: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + verificationMethod: [ + { + id: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + type: 'Ed25519VerificationKey2018', + controller: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + publicKeyBase58: 'ApexJxnhZHC6Ctq4fCoNHKYgu87HuRTZ7oSyfehG57zE', + }, + ], + authentication: [ + 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + ], + assertionMethod: [ + 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + ], + keyAgreement: [ + { + id: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6LSm5B4fB9NA55xB7PSeMYTMS9sf8uboJvyZBaDLLSZ7Ryd', + type: 'X25519KeyAgreementKey2019', + controller: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + publicKeyBase58: 'APzu8sLW4cND5j1g7i2W2qwPozNV6hkpgCrXqso2Q4Cs', + }, + ], + capabilityInvocation: [ + 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + ], + capabilityDelegation: [ + 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + ], + }, + secret: {}, +} + type OutOfBandRecordProperties = Omit export type OutOfBandInvitationProps = Omit< OutOfBandInvitationOptions, @@ -131,7 +173,7 @@ export interface OutOfBandRecordWithInvitationProps extends OutOfBandRecordPrope } export const outOfBandInvitationExample = { - '@type': 'https://didcomm.org/out-of-band/2.0/invitation', + '@type': 'did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation', '@id': 'd6472943-e5d0-4d95-8b48-790ed5a41931', label: 'Aries Test Agent', accept: ['didcomm/aip1', 'didcomm/aip2;env=rfc19'], @@ -170,7 +212,7 @@ export const CredentialExchangeRecordExample = { connectionId: 'ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b', }, metadata: { - '_internal/anoncredsCredential': { + '_internal/indyCredential': { credentialDefinitionId: 'q7ATwTYbQDgiigVijUAej:3:CL:318187:latest', schemaId: 'q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0', }, diff --git a/src/controllers/proofs/ProofController.ts b/src/controllers/proofs/ProofController.ts index 2d482468..24c8ca2a 100644 --- a/src/controllers/proofs/ProofController.ts +++ b/src/controllers/proofs/ProofController.ts @@ -1,43 +1,37 @@ import type { RestAgent } from '../../utils/agent' -import type { RequestProofOptionsProofRequestRestriction } from '../types' -import type { AnonCredsProofRequestRestriction } from '@aries-framework/anoncreds' +import type { AnonCredsRequestProofFormatOptions, AnonCredsProofRequestRestrictionOptions } from '../types' +import type { AnonCredsProofRequestRestriction, AnonCredsRequestProofFormat } from '@aries-framework/anoncreds' import type { ProofExchangeRecordProps } from '@aries-framework/core' import { Agent, RecordNotFoundError } from '@aries-framework/core' import { Body, Controller, Delete, Example, Get, Path, Post, Query, Res, Route, Tags, TsoaResponse } from 'tsoa' import { injectable } from 'tsyringe' +import { maybeMapValues } from '../../utils/helpers' import { ProofRecordExample, RecordId } from '../examples' -import { RequestProofOptions, RequestProofProposalOptions } from '../types' - -const maybeMapValues = ( - transform: (input: V) => U, - obj?: { - [key: string]: V - } -) => { - if (!obj) { - return obj - } - - return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, transform(value)])) -} - -const transformRequiredAttributes = (attributes?: string[]) => { +import { + RequestProofOptions, + AcceptProofProposalOptions, + AcceptProofRequestOptions, + ProposeProofOptions, + CreateProofRequestOptions, +} from '../types' + +const transformAttributeMarkers = (attributes?: { [key: string]: boolean }) => { if (!attributes) { return undefined } - return attributes.reduce<{ [key in `attr::${string}::marker`]: '1' }>( - (acc, attr) => ({ - [`attr::${attr}::marker`]: '1', + return Object.entries(attributes).reduce<{ [key in `attr::${string}::marker`]: '1' | '0' }>( + (acc, [attr, val]) => ({ + [`attr::${attr}::marker`]: val ? '1' : '0', ...acc, }), {} ) } -const transformRequiredAttributeValues = (attributeValues?: { [key in string]: string }) => { +const transformAttributeValues = (attributeValues?: { [key in string]: string }) => { if (!attributeValues) { return undefined } @@ -51,22 +45,44 @@ const transformRequiredAttributeValues = (attributeValues?: { [key in string]: s ) } -const transformRestriction = ( - restriction: RequestProofOptionsProofRequestRestriction -): AnonCredsProofRequestRestriction => ({ - schema_id: restriction.schemaId, - schema_issuer_id: restriction.schemaIssuerId, - schema_name: restriction.schemaName, - schema_version: restriction.schemaVersion, - issuer_id: restriction.issuerId, - cred_def_id: restriction.credDefId, - rev_reg_id: restriction.revRegId, - schema_issuer_did: restriction.schemaIssuerDid, - issuer_did: restriction.issuerDid, - ...transformRequiredAttributes(restriction.requiredAttributes), - ...transformRequiredAttributeValues(restriction.requiredAttributeValues), +const transformRestriction = ({ + attributeValues, + attributeMarkers, + ...others +}: AnonCredsProofRequestRestrictionOptions): AnonCredsProofRequestRestriction => ({ + ...transformAttributeMarkers(attributeMarkers), + ...transformAttributeValues(attributeValues), + ...others, }) +const transformProofFormat = ( + proofFormat?: AnonCredsRequestProofFormatOptions +): AnonCredsRequestProofFormat | undefined => { + if (!proofFormat) { + return undefined + } + + const { requested_attributes, requested_predicates, ...rest } = proofFormat + + return { + ...rest, + requested_attributes: maybeMapValues( + ({ restrictions, ...other }) => ({ + restrictions: restrictions?.map(transformRestriction), + ...other, + }), + requested_attributes + ), + requested_predicates: maybeMapValues( + ({ restrictions, ...other }) => ({ + restrictions: restrictions?.map(transformRestriction), + ...other, + }), + requested_predicates + ), + } +} + @Tags('Proofs') @Route('/proofs') @injectable() @@ -155,30 +171,18 @@ export class ProofController extends Controller { @Post('/propose-proof') @Example(ProofRecordExample) public async proposeProof( - @Body() proposal: RequestProofProposalOptions, + @Body() proposal: ProposeProofOptions, @Res() notFoundError: TsoaResponse<404, { reason: string }>, @Res() internalServerError: TsoaResponse<500, { message: string }> ) { - const { attributes, predicates, connectionId, comment } = proposal - try { - const proof = await this.agent.proofs.proposeProof({ - connectionId, - protocolVersion: 'v2', - proofFormats: { - anoncreds: { - attributes, - predicates, - }, - }, - comment, - }) + const proof = await this.agent.proofs.proposeProof(proposal) return proof.toJSON() } catch (error) { if (error instanceof RecordNotFoundError) { return notFoundError(404, { - reason: `connection with connectionId "${connectionId}" not found.`, + reason: `connection with connectionId "${proposal.connectionId}" not found.`, }) } return internalServerError(500, { message: `something went wrong: ${error}` }) @@ -198,23 +202,14 @@ export class ProofController extends Controller { public async acceptProposal( @Path('proofRecordId') proofRecordId: string, @Body() - proposal: { - request: { name?: string; version?: string } - comment?: string - }, + proposal: AcceptProofProposalOptions, @Res() notFoundError: TsoaResponse<404, { reason: string }>, @Res() internalServerError: TsoaResponse<500, { message: string }> ) { try { const proof = await this.agent.proofs.acceptProposal({ proofRecordId, - proofFormats: { - anoncreds: { - name: proposal.request.name, - version: proposal.request.version, - }, - }, - comment: proposal.comment, + ...proposal, }) return proof.toJSON() @@ -228,30 +223,31 @@ export class ProofController extends Controller { } } - // TODO: Represent out-of-band proof - // /** - // * Creates a presentation request not bound to any proposal or existing connection - // * - // * @param request - // * @returns ProofRequestMessageResponse - // */ - // @Post('/request-outofband-proof') - // @Example<{ proofUrl: string; proofRecord: ProofRecordProps }>({ - // proofUrl: 'https://example.com/proof-url', - // proofRecord: ProofRecordExample, - // }) - // public async requestProofOutOfBand(@Body() request: Omit) { - // const { proofRequestOptions, ...requestOptions } = request - - // const proof = await this.agent.proofs.createOutOfBandRequest(proofRequestOptions, requestOptions) - - // return { - // proofUrl: `${this.agent.config.endpoints[0]}/?d_m=${JsonEncoder.toBase64URL( - // proof.requestMessage.toJSON({ useLegacyDidSovPrefix: this.agent.config.useLegacyDidSovPrefix }) - // )}`, - // proofRecord: proof.proofRecord, - // } - // } + /** + * Creates a presentation request not bound to any proposal or existing connection + * + * @param request + * @returns ProofRequestMessageResponse + */ + @Post('/create-request') + @Example<{ message: object; proofRecord: ProofExchangeRecordProps }>({ + message: {}, + proofRecord: ProofRecordExample, + }) + public async createRequest(@Body() request: CreateProofRequestOptions) { + const { proofFormats, ...rest } = request + const { message, proofRecord } = await this.agent.proofs.createRequest({ + proofFormats: { + anoncreds: transformProofFormat(proofFormats.anoncreds), + }, + ...rest, + }) + + return { + message, + proofRecord: proofRecord, + } + } /** * Creates a presentation request bound to existing connection @@ -266,37 +262,14 @@ export class ProofController extends Controller { @Res() notFoundError: TsoaResponse<404, { reason: string }>, @Res() internalServerError: TsoaResponse<500, { message: string }> ) { - const { connectionId, proofRequestOptions } = request - + const { connectionId, proofFormats, ...rest } = request try { const proof = await this.agent.proofs.requestProof({ connectionId, - protocolVersion: 'v2', proofFormats: { - anoncreds: { - name: proofRequestOptions.name, - version: proofRequestOptions.version, - requested_attributes: maybeMapValues( - (attribute) => ({ - name: attribute.name, - names: attribute.names, - non_revoked: attribute.nonRevoked, - restrictions: attribute.restrictions?.map(transformRestriction), - }), - proofRequestOptions.requestedAttributes - ), - requested_predicates: maybeMapValues( - (predicate) => ({ - name: predicate.name, - p_type: predicate.pType, - p_value: predicate.pValue, - non_revoked: predicate.nonRevoked, - restrictions: predicate.restrictions?.map(transformRestriction), - }), - proofRequestOptions.requestedPredicates - ), - }, + anoncreds: transformProofFormat(proofFormats.anoncreds), }, + ...rest, }) return proof.toJSON() @@ -323,15 +296,11 @@ export class ProofController extends Controller { public async acceptRequest( @Path('proofRecordId') proofRecordId: string, @Body() - request: { - comment?: string - }, + request: AcceptProofRequestOptions, @Res() notFoundError: TsoaResponse<404, { reason: string }>, @Res() internalServerError: TsoaResponse<500, { message: string }> ) { try { - const { comment } = request - const retrievedCredentials = await this.agent.proofs.selectCredentialsForRequest({ proofRecordId, }) @@ -339,7 +308,7 @@ export class ProofController extends Controller { const proof = await this.agent.proofs.acceptRequest({ proofRecordId, proofFormats: retrievedCredentials.proofFormats, - comment, + ...request, }) return proof.toJSON() diff --git a/src/controllers/types.ts b/src/controllers/types.ts index cd6bae3f..269ecba6 100644 --- a/src/controllers/types.ts +++ b/src/controllers/types.ts @@ -1,12 +1,12 @@ import type { AnonCredsSchema, AnonCredsCredentialDefinition, - AnonCredsPresentationPreviewAttribute, - AnonCredsPresentationPreviewPredicate, AnonCredsNonRevokedInterval, AnonCredsPredicateType, - AnonCredsCredentialFormatService, AnonCredsCredentialFormat, + AnonCredsCredentialFormatService, + AnonCredsProofFormatService, + AnonCredsProofFormat, } from '@aries-framework/anoncreds' import type { AutoAcceptCredential, @@ -19,6 +19,12 @@ import type { DidDocumentMetadata, ProofExchangeRecord, V2CredentialProtocol, + V2ProofProtocol, + AutoAcceptProof, + ProofFormatPayload, + ProofsProtocolVersionType, + DidDocument, + KeyType, } from '@aries-framework/core' import type { DIDDocument } from 'did-resolver' @@ -48,16 +54,72 @@ export interface ProofRequestMessageResponse { type CredentialProtocols = [V2CredentialProtocol<[AnonCredsCredentialFormatService]>] type CredentialFormats = [AnonCredsCredentialFormat] +type ProofProtocols = [V2ProofProtocol<[AnonCredsProofFormatService]>] +type ProofFormats = [AnonCredsProofFormat] + +interface PrivateKey { + keyType: KeyType + privateKey: string +} + +export interface ImportDidOptions { + did: string + didDocument?: DidDocument + privateKeys?: PrivateKey[] + overwrite?: boolean +} + +export interface DidCreateOptions { + method?: string + did?: string + options?: { [x: string]: unknown } + secret?: { [x: string]: unknown } + didDocument?: DidDocument +} + +export interface DidOperationStateFinished { + state: 'finished' + did: string + secret?: { [x: string]: unknown } + didDocument: { [x: string]: unknown } +} +export interface DidOperationStateFailed { + state: 'failed' + did?: string + secret?: { [x: string]: unknown } + didDocument?: { [x: string]: unknown } + reason: string +} +export interface DidOperationStateWait { + state: 'wait' + did?: string + secret?: { [x: string]: unknown } + didDocument?: { [x: string]: unknown } +} +export interface DidOperationStateActionBase { + state: 'action' + action: string + did?: string + secret?: { [x: string]: unknown } + didDocument?: { [x: string]: unknown } +} + +export type DidCreateResult = DidOperationStateWait | DidOperationStateActionBase | DidOperationStateFinished + export interface ProposeCredentialOptions { protocolVersion: CredentialProtocolVersionType - credentialFormats: CredentialFormatPayload + credentialFormats: { + [key in CredentialFormats[number] as key['formatKey']]?: CredentialFormats[number]['credentialFormats']['createProposal'] + } autoAcceptCredential?: AutoAcceptCredential comment?: string connectionId: string } export interface AcceptCredentialProposalOptions { - credentialFormats: CredentialFormatPayload + credentialFormats?: { + [key in CredentialFormats[number] as key['formatKey']]?: CredentialFormats[number]['credentialFormats']['acceptProposal'] + } autoAcceptCredential?: AutoAcceptCredential comment?: string } @@ -131,51 +193,92 @@ export interface ConnectionInvitationSchema { imageUrl?: string } -export interface RequestProofOptionsProofRequestRestriction { - schemaId?: string - schemaIssuerId?: string - schemaName?: string - schemaVersion?: string - issuerId?: string - credDefId?: string - revRegId?: string - schemaIssuerDid?: string - issuerDid?: string - requiredAttributes?: string[] - requiredAttributeValues?: { [key: string]: string } +export interface ProposeProofOptions { + connectionId: string + protocolVersion: ProofsProtocolVersionType + proofFormats: ProofFormatPayload + goalCode?: string + parentThreadId?: string + autoAcceptProof?: AutoAcceptProof + comment?: string +} + +export interface AcceptProofProposalOptions { + proofFormats?: ProofFormatPayload + goalCode?: string + willConfirm?: boolean + autoAcceptProof?: AutoAcceptProof + comment?: string +} + +export interface AcceptProofRequestOptions { + useReturnRoute?: boolean + goalCode?: string + willConfirm?: boolean + autoAcceptProof?: AutoAcceptProof + comment?: string +} + +export interface AnonCredsProofRequestRestrictionOptions { + schema_id?: string + schema_issuer_id?: string + schema_name?: string + schema_version?: string + issuer_id?: string + cred_def_id?: string + rev_reg_id?: string + schema_issuer_did?: string + issuer_did?: string + attributeValues?: { + [key: string]: string + } + attributeMarkers?: { + [key: string]: boolean + } } -export interface RequestProofOptionsRequestedAttribute { +export interface AnonCredsRequestedAttributeOptions { name?: string names?: string[] - restrictions?: RequestProofOptionsProofRequestRestriction[] - nonRevoked?: AnonCredsNonRevokedInterval + restrictions?: AnonCredsProofRequestRestrictionOptions[] + non_revoked?: AnonCredsNonRevokedInterval } -export interface RequestProofOptionsRequestedPredicate { +export interface AnonCredsRequestedPredicateOptions { name: string - pType: AnonCredsPredicateType - pValue: number - restrictions?: RequestProofOptionsProofRequestRestriction[] - nonRevoked?: AnonCredsNonRevokedInterval + p_type: AnonCredsPredicateType + p_value: number + restrictions?: AnonCredsProofRequestRestrictionOptions[] + non_revoked?: AnonCredsNonRevokedInterval } -export interface RequestProofOptions { - connectionId: string - proofRequestOptions: { - name: string - version: string - requestedAttributes?: { [key: string]: RequestProofOptionsRequestedAttribute } - requestedPredicates?: { [key: string]: RequestProofOptionsRequestedPredicate } +export interface AnonCredsRequestProofFormatOptions { + name: string + version: string + non_revoked?: AnonCredsNonRevokedInterval + requested_attributes?: { + [key: string]: AnonCredsRequestedAttributeOptions + } + requested_predicates?: { + [key: string]: AnonCredsRequestedPredicateOptions } } -export interface RequestProofProposalOptions { - connectionId: string - attributes: AnonCredsPresentationPreviewAttribute[] - predicates: AnonCredsPresentationPreviewPredicate[] +export interface CreateProofRequestOptions { + protocolVersion: ProofsProtocolVersionType + proofFormats: { + [key in ProofFormats[number] as key['formatKey']]?: AnonCredsRequestProofFormatOptions + } + goalCode?: string + parentThreadId?: string + willConfirm?: boolean + autoAcceptProof?: AutoAcceptProof comment?: string } +export interface RequestProofOptions extends CreateProofRequestOptions { + connectionId: string +} + export interface AnonCredsSchemaResponse extends AnonCredsSchema { id: string } diff --git a/src/ipfs/__tests__/fixtures/ipfs.ts b/src/ipfs/__tests__/fixtures/ipfs.ts index 0aa6aada..bda0cb2d 100644 --- a/src/ipfs/__tests__/fixtures/ipfs.ts +++ b/src/ipfs/__tests__/fixtures/ipfs.ts @@ -37,7 +37,7 @@ export const withIpfsAddResponse = (responses: { code: number; cid: unknown; bod setGlobalDispatcher(mockAgent) const mockIpfs = mockAgent.get(`http://ipfs`) - for (const { code, cid, body } of responses) { + for (const { code, cid } of responses) { mockIpfs .intercept({ path: '/api/v0/add?cid-version=1', diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 5b0230b5..a9421246 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -163,11 +163,6 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "CredentialFormatPayload_CredentialFormats.createProposal_": { - "dataType": "refAlias", - "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"anoncreds":{"ref":"AnonCredsProposeCredentialFormat"}},"validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "AutoAcceptCredential": { "dataType": "refEnum", "enums": ["always","contentApproved","never"], @@ -177,7 +172,7 @@ const models: TsoaRoute.Models = { "dataType": "refObject", "properties": { "protocolVersion": {"ref":"CredentialProtocolVersionType_CredentialProtocols_","required":true}, - "credentialFormats": {"ref":"CredentialFormatPayload_CredentialFormats.createProposal_","required":true}, + "credentialFormats": {"dataType":"nestedObjectLiteral","nestedProperties":{"anoncreds":{"ref":"AnonCredsProposeCredentialFormat"}},"required":true}, "autoAcceptCredential": {"ref":"AutoAcceptCredential"}, "comment": {"dataType":"string"}, "connectionId": {"dataType":"string","required":true}, @@ -195,15 +190,10 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "CredentialFormatPayload_CredentialFormats.acceptProposal_": { - "dataType": "refAlias", - "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"anoncreds":{"ref":"AnonCredsAcceptProposalFormat"}},"validators":{}}, - }, - // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "AcceptCredentialProposalOptions": { "dataType": "refObject", "properties": { - "credentialFormats": {"ref":"CredentialFormatPayload_CredentialFormats.acceptProposal_","required":true}, + "credentialFormats": {"dataType":"nestedObjectLiteral","nestedProperties":{"anoncreds":{"ref":"AnonCredsAcceptProposalFormat"}}}, "autoAcceptCredential": {"ref":"AutoAcceptCredential"}, "comment": {"dataType":"string"}, }, @@ -374,6 +364,43 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "KeyType": { + "dataType": "refEnum", + "enums": ["ed25519","bls12381g1g2","bls12381g1","bls12381g2","x25519","p256","p384","p521"], + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "PrivateKey": { + "dataType": "refObject", + "properties": { + "keyType": {"ref":"KeyType","required":true}, + "privateKey": {"dataType":"string","required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "ImportDidOptions": { + "dataType": "refObject", + "properties": { + "did": {"dataType":"string","required":true}, + "didDocument": {"ref":"DidDocument"}, + "privateKeys": {"dataType":"array","array":{"dataType":"refObject","ref":"PrivateKey"}}, + "overwrite": {"dataType":"boolean"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "DidCreateOptions": { + "dataType": "refObject", + "properties": { + "method": {"dataType":"string"}, + "did": {"dataType":"string"}, + "options": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"}}, + "secret": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"any"}}, + "didDocument": {"ref":"DidDocument"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "HandshakeProtocol": { "dataType": "refEnum", "enums": ["https://didcomm.org/connections/1.0","https://didcomm.org/didexchange/1.0"], @@ -484,6 +511,11 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "ProofsProtocolVersionType_ProofProtocols_": { + "dataType": "refAlias", + "type": {"dataType":"string","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "AnonCredsPresentationPreviewAttribute": { "dataType": "refObject", "properties": { @@ -512,35 +544,68 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "RequestProofProposalOptions": { + "AnonCredsProposeProofFormat": { + "dataType": "refObject", + "properties": { + "name": {"dataType":"string"}, + "version": {"dataType":"string"}, + "attributes": {"dataType":"array","array":{"dataType":"refObject","ref":"AnonCredsPresentationPreviewAttribute"}}, + "predicates": {"dataType":"array","array":{"dataType":"refObject","ref":"AnonCredsPresentationPreviewPredicate"}}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "ProofFormatPayload_ProofFormats.createProposal_": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"anoncreds":{"ref":"AnonCredsProposeProofFormat"}},"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AutoAcceptProof": { + "dataType": "refEnum", + "enums": ["always","contentApproved","never"], + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "ProposeProofOptions": { "dataType": "refObject", "properties": { "connectionId": {"dataType":"string","required":true}, - "attributes": {"dataType":"array","array":{"dataType":"refObject","ref":"AnonCredsPresentationPreviewAttribute"},"required":true}, - "predicates": {"dataType":"array","array":{"dataType":"refObject","ref":"AnonCredsPresentationPreviewPredicate"},"required":true}, + "protocolVersion": {"ref":"ProofsProtocolVersionType_ProofProtocols_","required":true}, + "proofFormats": {"ref":"ProofFormatPayload_ProofFormats.createProposal_","required":true}, + "goalCode": {"dataType":"string"}, + "parentThreadId": {"dataType":"string"}, + "autoAcceptProof": {"ref":"AutoAcceptProof"}, "comment": {"dataType":"string"}, }, "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "RequestProofOptionsProofRequestRestriction": { + "ProofFormatPayload_ProofFormats.acceptProposal_": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"anoncreds":{"dataType":"nestedObjectLiteral","nestedProperties":{"version":{"dataType":"string"},"name":{"dataType":"string"}}}},"validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AcceptProofProposalOptions": { "dataType": "refObject", "properties": { - "schemaId": {"dataType":"string"}, - "schemaIssuerId": {"dataType":"string"}, - "schemaName": {"dataType":"string"}, - "schemaVersion": {"dataType":"string"}, - "issuerId": {"dataType":"string"}, - "credDefId": {"dataType":"string"}, - "revRegId": {"dataType":"string"}, - "schemaIssuerDid": {"dataType":"string"}, - "issuerDid": {"dataType":"string"}, - "requiredAttributes": {"dataType":"array","array":{"dataType":"string"}}, - "requiredAttributeValues": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"string"}}, + "proofFormats": {"ref":"ProofFormatPayload_ProofFormats.acceptProposal_"}, + "goalCode": {"dataType":"string"}, + "willConfirm": {"dataType":"boolean"}, + "autoAcceptProof": {"ref":"AutoAcceptProof"}, + "comment": {"dataType":"string"}, }, "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AgentMessage": { + "dataType": "refAlias", + "type": {"ref":"Record_string.unknown_","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "ProofExchangeRecord": { + "dataType": "refAlias", + "type": {"ref":"Record_string.unknown_","validators":{}}, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa "AnonCredsNonRevokedInterval": { "dataType": "refObject", "properties": { @@ -550,25 +615,69 @@ const models: TsoaRoute.Models = { "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "RequestProofOptionsRequestedAttribute": { + "AnonCredsProofRequestRestrictionOptions": { + "dataType": "refObject", + "properties": { + "schema_id": {"dataType":"string"}, + "schema_issuer_id": {"dataType":"string"}, + "schema_name": {"dataType":"string"}, + "schema_version": {"dataType":"string"}, + "issuer_id": {"dataType":"string"}, + "cred_def_id": {"dataType":"string"}, + "rev_reg_id": {"dataType":"string"}, + "schema_issuer_did": {"dataType":"string"}, + "issuer_did": {"dataType":"string"}, + "attributeValues": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"string"}}, + "attributeMarkers": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"dataType":"boolean"}}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AnonCredsRequestedAttributeOptions": { "dataType": "refObject", "properties": { "name": {"dataType":"string"}, "names": {"dataType":"array","array":{"dataType":"string"}}, - "restrictions": {"dataType":"array","array":{"dataType":"refObject","ref":"RequestProofOptionsProofRequestRestriction"}}, - "nonRevoked": {"ref":"AnonCredsNonRevokedInterval"}, + "restrictions": {"dataType":"array","array":{"dataType":"refObject","ref":"AnonCredsProofRequestRestrictionOptions"}}, + "non_revoked": {"ref":"AnonCredsNonRevokedInterval"}, }, "additionalProperties": false, }, // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa - "RequestProofOptionsRequestedPredicate": { + "AnonCredsRequestedPredicateOptions": { "dataType": "refObject", "properties": { "name": {"dataType":"string","required":true}, - "pType": {"ref":"AnonCredsPredicateType","required":true}, - "pValue": {"dataType":"double","required":true}, - "restrictions": {"dataType":"array","array":{"dataType":"refObject","ref":"RequestProofOptionsProofRequestRestriction"}}, - "nonRevoked": {"ref":"AnonCredsNonRevokedInterval"}, + "p_type": {"ref":"AnonCredsPredicateType","required":true}, + "p_value": {"dataType":"double","required":true}, + "restrictions": {"dataType":"array","array":{"dataType":"refObject","ref":"AnonCredsProofRequestRestrictionOptions"}}, + "non_revoked": {"ref":"AnonCredsNonRevokedInterval"}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AnonCredsRequestProofFormatOptions": { + "dataType": "refObject", + "properties": { + "name": {"dataType":"string","required":true}, + "version": {"dataType":"string","required":true}, + "non_revoked": {"ref":"AnonCredsNonRevokedInterval"}, + "requested_attributes": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"ref":"AnonCredsRequestedAttributeOptions"}}, + "requested_predicates": {"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"ref":"AnonCredsRequestedPredicateOptions"}}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "CreateProofRequestOptions": { + "dataType": "refObject", + "properties": { + "protocolVersion": {"ref":"ProofsProtocolVersionType_ProofProtocols_","required":true}, + "proofFormats": {"dataType":"nestedObjectLiteral","nestedProperties":{"anoncreds":{"ref":"AnonCredsRequestProofFormatOptions"}},"required":true}, + "goalCode": {"dataType":"string"}, + "parentThreadId": {"dataType":"string"}, + "willConfirm": {"dataType":"boolean"}, + "autoAcceptProof": {"ref":"AutoAcceptProof"}, + "comment": {"dataType":"string"}, }, "additionalProperties": false, }, @@ -576,8 +685,26 @@ const models: TsoaRoute.Models = { "RequestProofOptions": { "dataType": "refObject", "properties": { + "protocolVersion": {"ref":"ProofsProtocolVersionType_ProofProtocols_","required":true}, + "proofFormats": {"dataType":"nestedObjectLiteral","nestedProperties":{"anoncreds":{"ref":"AnonCredsRequestProofFormatOptions"}},"required":true}, + "goalCode": {"dataType":"string"}, + "parentThreadId": {"dataType":"string"}, + "willConfirm": {"dataType":"boolean"}, + "autoAcceptProof": {"ref":"AutoAcceptProof"}, + "comment": {"dataType":"string"}, "connectionId": {"dataType":"string","required":true}, - "proofRequestOptions": {"dataType":"nestedObjectLiteral","nestedProperties":{"requestedPredicates":{"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"ref":"RequestProofOptionsRequestedPredicate"}},"requestedAttributes":{"dataType":"nestedObjectLiteral","nestedProperties":{},"additionalProperties":{"ref":"RequestProofOptionsRequestedAttribute"}},"version":{"dataType":"string","required":true},"name":{"dataType":"string","required":true}},"required":true}, + }, + "additionalProperties": false, + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + "AcceptProofRequestOptions": { + "dataType": "refObject", + "properties": { + "useReturnRoute": {"dataType":"boolean"}, + "goalCode": {"dataType":"string"}, + "willConfirm": {"dataType":"boolean"}, + "autoAcceptProof": {"ref":"AutoAcceptProof"}, + "comment": {"dataType":"string"}, }, "additionalProperties": false, }, @@ -1327,6 +1454,69 @@ export function RegisterRoutes(app: express.Router) { } }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + app.post('/dids/import', + ...(fetchMiddlewares(DidController)), + ...(fetchMiddlewares(DidController.prototype.importDid)), + + async function DidController_importDid(request: any, response: any, next: any) { + const args = { + options: {"in":"body","name":"options","required":true,"ref":"ImportDidOptions"}, + badRequestError: {"in":"res","name":"400","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, + internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, + }; + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = getValidatedArgs(args, request, response); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(DidController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + + const promise = controller.importDid.apply(controller, validatedArgs as any); + promiseHandler(controller, promise, response, undefined, next); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + app.post('/dids/create', + ...(fetchMiddlewares(DidController)), + ...(fetchMiddlewares(DidController.prototype.createDid)), + + async function DidController_createDid(request: any, response: any, next: any) { + const args = { + options: {"in":"body","name":"options","required":true,"ref":"DidCreateOptions"}, + internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, + }; + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = getValidatedArgs(args, request, response); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(DidController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + + const promise = controller.createDid.apply(controller, validatedArgs as any); + promiseHandler(controller, promise, response, undefined, next); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.get('/oob', ...(fetchMiddlewares(OutOfBandController)), ...(fetchMiddlewares(OutOfBandController.prototype.getAllOutOfBandRecords)), @@ -1709,7 +1899,7 @@ export function RegisterRoutes(app: express.Router) { async function ProofController_proposeProof(request: any, response: any, next: any) { const args = { - proposal: {"in":"body","name":"proposal","required":true,"ref":"RequestProofProposalOptions"}, + proposal: {"in":"body","name":"proposal","required":true,"ref":"ProposeProofOptions"}, notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; @@ -1742,7 +1932,7 @@ export function RegisterRoutes(app: express.Router) { async function ProofController_acceptProposal(request: any, response: any, next: any) { const args = { proofRecordId: {"in":"path","name":"proofRecordId","required":true,"dataType":"string"}, - proposal: {"in":"body","name":"proposal","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"comment":{"dataType":"string"},"request":{"dataType":"nestedObjectLiteral","nestedProperties":{"version":{"dataType":"string"},"name":{"dataType":"string"}},"required":true}}}, + proposal: {"in":"body","name":"proposal","required":true,"ref":"AcceptProofProposalOptions"}, notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; @@ -1768,6 +1958,36 @@ export function RegisterRoutes(app: express.Router) { } }); // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + app.post('/proofs/create-request', + ...(fetchMiddlewares(ProofController)), + ...(fetchMiddlewares(ProofController.prototype.createRequest)), + + async function ProofController_createRequest(request: any, response: any, next: any) { + const args = { + request: {"in":"body","name":"request","required":true,"ref":"CreateProofRequestOptions"}, + }; + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = getValidatedArgs(args, request, response); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(ProofController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + + const promise = controller.createRequest.apply(controller, validatedArgs as any); + promiseHandler(controller, promise, response, undefined, next); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa app.post('/proofs/request-proof', ...(fetchMiddlewares(ProofController)), ...(fetchMiddlewares(ProofController.prototype.requestProof)), @@ -1807,7 +2027,7 @@ export function RegisterRoutes(app: express.Router) { async function ProofController_acceptRequest(request: any, response: any, next: any) { const args = { proofRecordId: {"in":"path","name":"proofRecordId","required":true,"dataType":"string"}, - request: {"in":"body","name":"request","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"comment":{"dataType":"string"}}}, + request: {"in":"body","name":"request","required":true,"ref":"AcceptProofRequestOptions"}, notFoundError: {"in":"res","name":"404","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"reason":{"dataType":"string","required":true}}}, internalServerError: {"in":"res","name":"500","required":true,"dataType":"nestedObjectLiteral","nestedProperties":{"message":{"dataType":"string","required":true}}}, }; diff --git a/src/routes/swagger.json b/src/routes/swagger.json index f6dd8e0a..928c922e 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -292,15 +292,6 @@ "type": "object", "additionalProperties": false }, - "CredentialFormatPayload_CredentialFormats.createProposal_": { - "properties": { - "anoncreds": { - "$ref": "#/components/schemas/AnonCredsProposeCredentialFormat" - } - }, - "type": "object", - "description": "Get the payload for a specific method from a list of CredentialFormat interfaces and a method" - }, "AutoAcceptCredential": { "description": "Typing of the state for auto acceptance", "enum": [ @@ -316,7 +307,12 @@ "$ref": "#/components/schemas/CredentialProtocolVersionType_CredentialProtocols_" }, "credentialFormats": { - "$ref": "#/components/schemas/CredentialFormatPayload_CredentialFormats.createProposal_" + "properties": { + "anoncreds": { + "$ref": "#/components/schemas/AnonCredsProposeCredentialFormat" + } + }, + "type": "object" }, "autoAcceptCredential": { "$ref": "#/components/schemas/AutoAcceptCredential" @@ -358,19 +354,15 @@ "type": "object", "additionalProperties": false }, - "CredentialFormatPayload_CredentialFormats.acceptProposal_": { - "properties": { - "anoncreds": { - "$ref": "#/components/schemas/AnonCredsAcceptProposalFormat" - } - }, - "type": "object", - "description": "Get the payload for a specific method from a list of CredentialFormat interfaces and a method" - }, "AcceptCredentialProposalOptions": { "properties": { "credentialFormats": { - "$ref": "#/components/schemas/CredentialFormatPayload_CredentialFormats.acceptProposal_" + "properties": { + "anoncreds": { + "$ref": "#/components/schemas/AnonCredsAcceptProposalFormat" + } + }, + "type": "object" }, "autoAcceptCredential": { "$ref": "#/components/schemas/AutoAcceptCredential" @@ -379,9 +371,6 @@ "type": "string" } }, - "required": [ - "credentialFormats" - ], "type": "object", "additionalProperties": false }, @@ -690,6 +679,84 @@ "type": "object", "additionalProperties": false }, + "KeyType": { + "enum": [ + "ed25519", + "bls12381g1g2", + "bls12381g1", + "bls12381g2", + "x25519", + "p256", + "p384", + "p521" + ], + "type": "string" + }, + "PrivateKey": { + "properties": { + "keyType": { + "$ref": "#/components/schemas/KeyType" + }, + "privateKey": { + "type": "string" + } + }, + "required": [ + "keyType", + "privateKey" + ], + "type": "object", + "additionalProperties": false + }, + "ImportDidOptions": { + "properties": { + "did": { + "type": "string" + }, + "didDocument": { + "$ref": "#/components/schemas/DidDocument" + }, + "privateKeys": { + "items": { + "$ref": "#/components/schemas/PrivateKey" + }, + "type": "array" + }, + "overwrite": { + "type": "boolean" + } + }, + "required": [ + "did" + ], + "type": "object", + "additionalProperties": false + }, + "DidCreateOptions": { + "properties": { + "method": { + "type": "string" + }, + "did": { + "type": "string" + }, + "options": { + "properties": {}, + "additionalProperties": {}, + "type": "object" + }, + "secret": { + "properties": {}, + "additionalProperties": {}, + "type": "object" + }, + "didDocument": { + "$ref": "#/components/schemas/DidDocument" + } + }, + "type": "object", + "additionalProperties": false + }, "HandshakeProtocol": { "enum": [ "https://didcomm.org/connections/1.0", @@ -999,6 +1066,10 @@ "type": "object", "additionalProperties": false }, + "ProofsProtocolVersionType_ProofProtocols_": { + "type": "string", + "description": "Get the supported protocol versions based on the provided proof protocols." + }, "AnonCredsPresentationPreviewAttribute": { "properties": { "name": { @@ -1057,9 +1128,13 @@ "type": "object", "additionalProperties": false }, - "RequestProofProposalOptions": { + "AnonCredsProposeProofFormat": { + "description": "Interface for creating an anoncreds proof proposal.", "properties": { - "connectionId": { + "name": { + "type": "string" + }, + "version": { "type": "string" }, "attributes": { @@ -1073,6 +1148,48 @@ "$ref": "#/components/schemas/AnonCredsPresentationPreviewPredicate" }, "type": "array" + } + }, + "type": "object", + "additionalProperties": false + }, + "ProofFormatPayload_ProofFormats.createProposal_": { + "properties": { + "anoncreds": { + "$ref": "#/components/schemas/AnonCredsProposeProofFormat" + } + }, + "type": "object", + "description": "Get the payload for a specific method from a list of ProofFormat interfaces and a method" + }, + "AutoAcceptProof": { + "description": "Typing of the state for auto acceptance", + "enum": [ + "always", + "contentApproved", + "never" + ], + "type": "string" + }, + "ProposeProofOptions": { + "properties": { + "connectionId": { + "type": "string" + }, + "protocolVersion": { + "$ref": "#/components/schemas/ProofsProtocolVersionType_ProofProtocols_" + }, + "proofFormats": { + "$ref": "#/components/schemas/ProofFormatPayload_ProofFormats.createProposal_" + }, + "goalCode": { + "type": "string" + }, + "parentThreadId": { + "type": "string" + }, + "autoAcceptProof": { + "$ref": "#/components/schemas/AutoAcceptProof" }, "comment": { "type": "string" @@ -1080,73 +1197,118 @@ }, "required": [ "connectionId", - "attributes", - "predicates" + "protocolVersion", + "proofFormats" ], "type": "object", "additionalProperties": false }, - "RequestProofOptionsProofRequestRestriction": { + "ProofFormatPayload_ProofFormats.acceptProposal_": { "properties": { - "schemaId": { + "anoncreds": { + "properties": { + "version": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "type": "object" + } + }, + "type": "object", + "description": "Get the payload for a specific method from a list of ProofFormat interfaces and a method" + }, + "AcceptProofProposalOptions": { + "properties": { + "proofFormats": { + "$ref": "#/components/schemas/ProofFormatPayload_ProofFormats.acceptProposal_" + }, + "goalCode": { "type": "string" }, - "schemaIssuerId": { + "willConfirm": { + "type": "boolean" + }, + "autoAcceptProof": { + "$ref": "#/components/schemas/AutoAcceptProof" + }, + "comment": { "type": "string" + } + }, + "type": "object", + "additionalProperties": false + }, + "AgentMessage": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "ProofExchangeRecord": { + "$ref": "#/components/schemas/Record_string.unknown_" + }, + "AnonCredsNonRevokedInterval": { + "properties": { + "from": { + "type": "number", + "format": "double" }, - "schemaName": { + "to": { + "type": "number", + "format": "double" + } + }, + "type": "object", + "additionalProperties": false + }, + "AnonCredsProofRequestRestrictionOptions": { + "properties": { + "schema_id": { "type": "string" }, - "schemaVersion": { + "schema_issuer_id": { "type": "string" }, - "issuerId": { + "schema_name": { "type": "string" }, - "credDefId": { + "schema_version": { "type": "string" }, - "revRegId": { + "issuer_id": { "type": "string" }, - "schemaIssuerDid": { + "cred_def_id": { "type": "string" }, - "issuerDid": { + "rev_reg_id": { "type": "string" }, - "requiredAttributes": { - "items": { - "type": "string" - }, - "type": "array" + "schema_issuer_did": { + "type": "string" + }, + "issuer_did": { + "type": "string" }, - "requiredAttributeValues": { + "attributeValues": { "properties": {}, "additionalProperties": { "type": "string" }, "type": "object" - } - }, - "type": "object", - "additionalProperties": false - }, - "AnonCredsNonRevokedInterval": { - "properties": { - "from": { - "type": "number", - "format": "double" }, - "to": { - "type": "number", - "format": "double" + "attributeMarkers": { + "properties": {}, + "additionalProperties": { + "type": "boolean" + }, + "type": "object" } }, "type": "object", "additionalProperties": false }, - "RequestProofOptionsRequestedAttribute": { + "AnonCredsRequestedAttributeOptions": { "properties": { "name": { "type": "string" @@ -1159,86 +1321,174 @@ }, "restrictions": { "items": { - "$ref": "#/components/schemas/RequestProofOptionsProofRequestRestriction" + "$ref": "#/components/schemas/AnonCredsProofRequestRestrictionOptions" }, "type": "array" }, - "nonRevoked": { + "non_revoked": { "$ref": "#/components/schemas/AnonCredsNonRevokedInterval" } }, "type": "object", "additionalProperties": false }, - "RequestProofOptionsRequestedPredicate": { + "AnonCredsRequestedPredicateOptions": { "properties": { "name": { "type": "string" }, - "pType": { + "p_type": { "$ref": "#/components/schemas/AnonCredsPredicateType" }, - "pValue": { + "p_value": { "type": "number", "format": "double" }, "restrictions": { "items": { - "$ref": "#/components/schemas/RequestProofOptionsProofRequestRestriction" + "$ref": "#/components/schemas/AnonCredsProofRequestRestrictionOptions" }, "type": "array" }, - "nonRevoked": { + "non_revoked": { "$ref": "#/components/schemas/AnonCredsNonRevokedInterval" } }, "required": [ "name", - "pType", - "pValue" + "p_type", + "p_value" ], "type": "object", "additionalProperties": false }, - "RequestProofOptions": { + "AnonCredsRequestProofFormatOptions": { "properties": { - "connectionId": { + "name": { + "type": "string" + }, + "version": { "type": "string" }, - "proofRequestOptions": { + "non_revoked": { + "$ref": "#/components/schemas/AnonCredsNonRevokedInterval" + }, + "requested_attributes": { + "properties": {}, + "additionalProperties": { + "$ref": "#/components/schemas/AnonCredsRequestedAttributeOptions" + }, + "type": "object" + }, + "requested_predicates": { + "properties": {}, + "additionalProperties": { + "$ref": "#/components/schemas/AnonCredsRequestedPredicateOptions" + }, + "type": "object" + } + }, + "required": [ + "name", + "version" + ], + "type": "object", + "additionalProperties": false + }, + "CreateProofRequestOptions": { + "properties": { + "protocolVersion": { + "$ref": "#/components/schemas/ProofsProtocolVersionType_ProofProtocols_" + }, + "proofFormats": { "properties": { - "requestedPredicates": { - "properties": {}, - "additionalProperties": { - "$ref": "#/components/schemas/RequestProofOptionsRequestedPredicate" - }, - "type": "object" - }, - "requestedAttributes": { - "properties": {}, - "additionalProperties": { - "$ref": "#/components/schemas/RequestProofOptionsRequestedAttribute" - }, - "type": "object" - }, - "version": { - "type": "string" - }, - "name": { - "type": "string" + "anoncreds": { + "$ref": "#/components/schemas/AnonCredsRequestProofFormatOptions" + } + }, + "type": "object" + }, + "goalCode": { + "type": "string" + }, + "parentThreadId": { + "type": "string" + }, + "willConfirm": { + "type": "boolean" + }, + "autoAcceptProof": { + "$ref": "#/components/schemas/AutoAcceptProof" + }, + "comment": { + "type": "string" + } + }, + "required": [ + "protocolVersion", + "proofFormats" + ], + "type": "object", + "additionalProperties": false + }, + "RequestProofOptions": { + "properties": { + "protocolVersion": { + "$ref": "#/components/schemas/ProofsProtocolVersionType_ProofProtocols_" + }, + "proofFormats": { + "properties": { + "anoncreds": { + "$ref": "#/components/schemas/AnonCredsRequestProofFormatOptions" } }, - "required": [ - "version", - "name" - ], "type": "object" + }, + "goalCode": { + "type": "string" + }, + "parentThreadId": { + "type": "string" + }, + "willConfirm": { + "type": "boolean" + }, + "autoAcceptProof": { + "$ref": "#/components/schemas/AutoAcceptProof" + }, + "comment": { + "type": "string" + }, + "connectionId": { + "type": "string" + } + }, + "required": [ + "protocolVersion", + "proofFormats", + "connectionId" + ], + "type": "object", + "additionalProperties": false + }, + "AcceptProofRequestOptions": { + "properties": { + "useReturnRoute": { + "type": "boolean" + }, + "goalCode": { + "type": "string" + }, + "willConfirm": { + "type": "boolean" + }, + "autoAcceptProof": { + "$ref": "#/components/schemas/AutoAcceptProof" + }, + "comment": { + "type": "string" } }, - "required": [ - "connectionId", - "proofRequestOptions" - ], "type": "object", "additionalProperties": false } @@ -1835,7 +2085,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -1906,7 +2156,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -2060,7 +2310,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -2151,7 +2401,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -2252,7 +2502,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -2325,7 +2575,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -2416,7 +2666,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -2517,7 +2767,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -2618,7 +2868,7 @@ "connectionId": "ac6d0fdd-0db8-4f52-8a3d-de7ff8ddc14b" }, "metadata": { - "_internal/anoncredsCredential": { + "_internal/indyCredential": { "credentialDefinitionId": "q7ATwTYbQDgiigVijUAej:3:CL:318187:latest", "schemaId": "q7ATwTYbQDgiigVijUAej:2:Employee Badge:1.0" } @@ -3226,6 +3476,212 @@ ] } }, + "/dids/import": { + "post": { + "operationId": "ImportDid", + "responses": { + "200": { + "description": "DidResolutionResultProps", + "content": { + "application/json": { + "schema": {}, + "examples": { + "Example 1": { + "value": { + "didDocument": { + "@context": [ + "https://w3id.org/did/v1", + "https://w3id.org/security/suites/ed25519-2018/v1", + "https://w3id.org/security/suites/x25519-2019/v1" + ], + "id": "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL", + "verificationMethod": [ + { + "id": "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL", + "type": "Ed25519VerificationKey2018", + "controller": "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL", + "publicKeyBase58": "6fioC1zcDPyPEL19pXRS2E4iJ46zH7xP6uSgAaPdwDrx" + } + ], + "authentication": [ + "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL" + ], + "assertionMethod": [ + "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL" + ], + "capabilityInvocation": [ + "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL" + ], + "capabilityDelegation": [ + "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL" + ], + "keyAgreement": [ + { + "id": "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6LSrdqo4M24WRDJj1h2hXxgtDTyzjjKCiyapYVgrhwZAySn", + "type": "X25519KeyAgreementKey2019", + "controller": "did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL", + "publicKeyBase58": "FxfdY3DCQxVZddKGAtSjZdFW9bCCW7oRwZn1NFJ2Tbg2" + } + ] + }, + "didDocumentMetadata": {}, + "didResolutionMetadata": { + "contentType": "application/did+ld+json" + } + } + } + } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { + "properties": { + "reason": { + "type": "string" + } + }, + "required": [ + "reason" + ], + "type": "object" + } + } + } + }, + "500": { + "description": "", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + } + } + }, + "description": "Import a Did to the Agent and return the did resolution result", + "tags": [ + "Dids" + ], + "security": [], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ImportDidOptions" + } + } + } + } + } + }, + "/dids/create": { + "post": { + "operationId": "CreateDid", + "responses": { + "200": { + "description": "DidResolutionResultProps", + "content": { + "application/json": { + "schema": {}, + "examples": { + "Example 1": { + "value": { + "did": "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc", + "didDocument": { + "@context": [ + "https://w3id.org/did/v1", + "https://w3id.org/security/suites/ed25519-2018/v1", + "https://w3id.org/security/suites/x25519-2019/v1" + ], + "id": "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc", + "verificationMethod": [ + { + "id": "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc", + "type": "Ed25519VerificationKey2018", + "controller": "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc", + "publicKeyBase58": "ApexJxnhZHC6Ctq4fCoNHKYgu87HuRTZ7oSyfehG57zE" + } + ], + "authentication": [ + "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc" + ], + "assertionMethod": [ + "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc" + ], + "keyAgreement": [ + { + "id": "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6LSm5B4fB9NA55xB7PSeMYTMS9sf8uboJvyZBaDLLSZ7Ryd", + "type": "X25519KeyAgreementKey2019", + "controller": "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc", + "publicKeyBase58": "APzu8sLW4cND5j1g7i2W2qwPozNV6hkpgCrXqso2Q4Cs" + } + ], + "capabilityInvocation": [ + "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc" + ], + "capabilityDelegation": [ + "did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc" + ] + }, + "secret": {} + } + } + } + } + } + }, + "500": { + "description": "", + "content": { + "application/json": { + "schema": { + "properties": { + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + } + } + }, + "description": "Create a Did and return the did resolution result", + "tags": [ + "Dids" + ], + "security": [], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DidCreateOptions" + } + } + } + } + } + }, "/oob": { "get": { "operationId": "GetAllOutOfBandRecords", @@ -3253,7 +3709,7 @@ ] }, "outOfBandInvitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -3327,7 +3783,7 @@ ] }, "outOfBandInvitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -3475,7 +3931,7 @@ "value": { "invitationUrl": "string", "invitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -3508,7 +3964,7 @@ ] }, "outOfBandInvitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -3594,7 +4050,7 @@ "Example 1": { "value": { "invitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -3627,7 +4083,7 @@ ] }, "outOfBandInvitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -3818,7 +4274,7 @@ ] }, "outOfBandInvitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -3926,7 +4382,7 @@ ] }, "outOfBandInvitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -4034,7 +4490,7 @@ ] }, "outOfBandInvitation": { - "@type": "https://didcomm.org/out-of-band/2.0/invitation", + "@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/out-of-band/1.1/invitation", "@id": "d6472943-e5d0-4d95-8b48-790ed5a41931", "label": "Aries Test Agent", "accept": [ @@ -4407,7 +4863,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RequestProofProposalOptions" + "$ref": "#/components/schemas/ProposeProofOptions" } } } @@ -4494,26 +4950,66 @@ "content": { "application/json": { "schema": { - "properties": { - "comment": { - "type": "string" + "$ref": "#/components/schemas/AcceptProofProposalOptions" + } + } + } + } + } + }, + "/proofs/create-request": { + "post": { + "operationId": "CreateRequest", + "responses": { + "200": { + "description": "ProofRequestMessageResponse", + "content": { + "application/json": { + "schema": { + "properties": { + "proofRecord": { + "$ref": "#/components/schemas/ProofExchangeRecord" + }, + "message": { + "$ref": "#/components/schemas/AgentMessage" + } }, - "request": { - "properties": { - "version": { - "type": "string" - }, - "name": { - "type": "string" + "required": [ + "proofRecord", + "message" + ], + "type": "object" + }, + "examples": { + "Example 1": { + "value": { + "message": {}, + "proofRecord": { + "id": "821f9b26-ad04-4f56-89b6-e2ef9c72b36e", + "protocolVersion": "v2", + "threadId": "0019d466-5eea-4269-8c40-031b4896c5b7", + "connectionId": "2aecf74c-3073-4f98-9acb-92415d096834", + "createdAt": "2022-01-01T00:00:00.000Z" } - }, - "type": "object" + } } - }, - "required": [ - "request" - ], - "type": "object" + } + } + } + } + }, + "description": "Creates a presentation request not bound to any proposal or existing connection", + "tags": [ + "Proofs" + ], + "security": [], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateProofRequestOptions" } } } @@ -4678,12 +5174,7 @@ "content": { "application/json": { "schema": { - "properties": { - "comment": { - "type": "string" - } - }, - "type": "object" + "$ref": "#/components/schemas/AcceptProofRequestOptions" } } } diff --git a/src/utils/agent.ts b/src/utils/agent.ts index 110adb66..a3480f41 100644 --- a/src/utils/agent.ts +++ b/src/utils/agent.ts @@ -1,10 +1,15 @@ -import { AnonCredsCredentialFormatService, AnonCredsProofFormatService } from '@aries-framework/anoncreds' -import { V2CredentialProtocol, V2ProofProtocol } from '@aries-framework/core' +import type { ModulesMap } from '@aries-framework/core' -import { AnonCredsModule } from '@aries-framework/anoncreds' +import { + AnonCredsCredentialFormatService, + AnonCredsProofFormatService, + AnonCredsModule, +} from '@aries-framework/anoncreds' import { AnonCredsRsModule } from '@aries-framework/anoncreds-rs' import { AskarModule } from '@aries-framework/askar' import { + V2CredentialProtocol, + V2ProofProtocol, Agent, AutoAcceptCredential, AutoAcceptProof, @@ -24,23 +29,79 @@ import { TsLogger } from './logger' import VeritableAnonCredsRegistry from '../anoncreds' import Ipfs from '../ipfs' -export type RestAgent = Agent<{ +export interface RestAgentModules extends ModulesMap { connections: ConnectionsModule proofs: ProofsModule<[V2ProofProtocol<[AnonCredsProofFormatService]>]> credentials: CredentialsModule<[V2CredentialProtocol<[AnonCredsCredentialFormatService]>]> - anoncredsRs: AnonCredsRsModule anoncreds: AnonCredsModule - askar: AskarModule - mediator: MediatorModule -}> +} + +export type RestAgent< + modules extends RestAgentModules = { + connections: ConnectionsModule + proofs: ProofsModule<[V2ProofProtocol<[AnonCredsProofFormatService]>]> + credentials: CredentialsModule<[V2CredentialProtocol]> + anoncreds: AnonCredsModule + } +> = Agent export const genesisPath = process.env.GENESIS_TXN_PATH ? path.resolve(process.env.GENESIS_TXN_PATH) : path.join(__dirname, '../../../../network/genesis/local-genesis.txn') +export const getAgentModules = (options: { + autoAcceptConnections: boolean + autoAcceptProofs: AutoAcceptProof + autoAcceptCredentials: AutoAcceptCredential + autoAcceptMediationRequests: boolean + ipfsOrigin: string +}): RestAgentModules => { + return { + connections: new ConnectionsModule({ + autoAcceptConnections: options.autoAcceptConnections, + }), + proofs: new ProofsModule({ + autoAcceptProofs: options.autoAcceptProofs, + proofProtocols: [ + new V2ProofProtocol({ + proofFormats: [new AnonCredsProofFormatService()], + }), + ], + }), + credentials: new CredentialsModule({ + autoAcceptCredentials: options.autoAcceptCredentials, + credentialProtocols: [ + new V2CredentialProtocol({ + credentialFormats: [new AnonCredsCredentialFormatService()], + }), + ], + }), + anoncreds: new AnonCredsModule({ + registries: [new VeritableAnonCredsRegistry(new Ipfs(options.ipfsOrigin))], + }), + anoncredsRs: new AnonCredsRsModule({ + anoncreds, + }), + askar: new AskarModule({ + ariesAskar, + }), + mediator: new MediatorModule({ + autoAcceptMediationRequests: options.autoAcceptMediationRequests, + }), + } +} + export const setupAgent = async ({ name, endpoints, port }: { name: string; endpoints: string[]; port: number }) => { const logger = new TsLogger(LogLevel.debug) + const modules = getAgentModules({ + autoAcceptConnections: true, + autoAcceptProofs: AutoAcceptProof.ContentApproved, + autoAcceptCredentials: AutoAcceptCredential.ContentApproved, + autoAcceptMediationRequests: true, + ipfsOrigin: 'http://localhost:5001', + }) + const agent = new Agent({ config: { label: name, @@ -51,34 +112,7 @@ export const setupAgent = async ({ name, endpoints, port }: { name: string; endp autoUpdateStorageOnStartup: true, }, dependencies: agentDependencies, - modules: { - connections: new ConnectionsModule({ - autoAcceptConnections: true, - }), - proofs: new ProofsModule({ - autoAcceptProofs: AutoAcceptProof.ContentApproved, - }), - credentials: new CredentialsModule<[V2CredentialProtocol<[AnonCredsCredentialFormatService]>]>({ - autoAcceptCredentials: AutoAcceptCredential.ContentApproved, - credentialProtocols: [ - new V2CredentialProtocol({ - credentialFormats: [new AnonCredsCredentialFormatService()], - }), - ], - }), - anoncredsRs: new AnonCredsRsModule({ - anoncreds, - }), - anoncreds: new AnonCredsModule({ - registries: [new VeritableAnonCredsRegistry(new Ipfs('http://localhost:5001'))], - }), - askar: new AskarModule({ - ariesAskar, - }), - mediator: new MediatorModule({ - autoAcceptMediationRequests: true, - }), - }, + modules, }) const httpInbound = new HttpInboundTransport({ diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index a66b4a69..620f053c 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -1,6 +1,19 @@ import { JsonTransformer } from '@aries-framework/core' import { JsonEncoder } from '@aries-framework/core/build/utils/JsonEncoder' +export function maybeMapValues( + transform: (input: V) => U, + obj?: { + [key: string]: V + } +) { + if (!obj) { + return obj + } + + return Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, transform(value)])) +} + export function objectToJson(result: T) { const serialized = JsonTransformer.serialize(result) return JsonEncoder.fromString(serialized) diff --git a/tests/credential.test.ts b/tests/credential.test.ts index 9b2e60aa..a0e1c201 100644 --- a/tests/credential.test.ts +++ b/tests/credential.test.ts @@ -1,3 +1,4 @@ +import type { AcceptCredentialProposalOptions, ProposeCredentialOptions } from '../src/controllers/types' import { describe, before, after, afterEach, test } from 'mocha' import { expect, use as chaiUse, Assertion as assertion } from 'chai' import chaiAssertionsCount from 'chai-assertions-count' @@ -164,9 +165,9 @@ describe('CredentialController', () => { proposeCredentialStub.resolves(testCredential) const getResult = (): Promise => proposeCredentialStub.firstCall.returnValue - const proposalRequest = { + const proposalRequest: ProposeCredentialOptions = { connectionId: '000000aa-aa00-00a0-aa00-000a0aa00000', - protocolVersion: 'v1', + protocolVersion: 'v2', credentialFormats: { anoncreds: { credentialDefinitionId: 'WghBqNdoFjaYh6F5N9eBF:3:CL:3210:test', @@ -204,7 +205,7 @@ describe('CredentialController', () => { const acceptProposalStub = stub(bobAgent.credentials, 'acceptProposal') acceptProposalStub.resolves(testCredential) const getResult = (): Promise => acceptProposalStub.firstCall.returnValue - const proposalRequest = { + const proposalRequest: AcceptCredentialProposalOptions = { credentialFormats: { anoncreds: { credentialDefinitionId: 'WghBqNdoFjaYh6F5N9eBF:3:CL:3210:test', @@ -216,6 +217,8 @@ describe('CredentialController', () => { ], }, }, + autoAcceptCredential: 'always' as AutoAcceptCredential, + comment: 'test', } const response = await request(app) diff --git a/tests/did.test.ts b/tests/did.test.ts index e61e3982..4179d550 100644 --- a/tests/did.test.ts +++ b/tests/did.test.ts @@ -1,23 +1,30 @@ -import { describe, before, after, afterEach, test } from 'mocha' -import { expect } from 'chai' -import { restore as sinonRestore } from 'sinon' - -import type { Agent } from '@aries-framework/core' +import type { Agent, DidCreateResult } from '@aries-framework/core' import type { Server } from 'net' +import { describe, before, after, afterEach, test } from 'mocha' +import { expect } from 'chai' +import { restore as sinonRestore, stub } from 'sinon' import request from 'supertest' +import { KeyType } from '@aries-framework/core' + import { startServer } from '../src' -import { getTestAgent } from './utils/helpers' +import { getTestAgent, getTestDidCreate, getTestDidDocument, objectToJson } from './utils/helpers' +import { DidCreateOptions, ImportDidOptions } from '../src/controllers/types' describe('DidController', () => { let app: Server let aliceAgent: Agent + let testDidDocument: Record + let testDidCreate: DidCreateResult before(async () => { aliceAgent = await getTestAgent('Did REST Agent Test Alice', 3999) app = await startServer(aliceAgent, { port: 3000 }) + + testDidDocument = getTestDidDocument() + testDidCreate = getTestDidCreate() }) afterEach(() => { @@ -30,42 +37,7 @@ describe('DidController', () => { const response = await request(app).get(`/dids/${did}`) expect(response.statusCode).to.be.equal(200) - expect(response.body.didDocument).to.deep.equal({ - '@context': [ - 'https://w3id.org/did/v1', - 'https://w3id.org/security/suites/ed25519-2018/v1', - 'https://w3id.org/security/suites/x25519-2019/v1', - ], - id: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', - verificationMethod: [ - { - id: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', - type: 'Ed25519VerificationKey2018', - controller: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', - publicKeyBase58: '6fioC1zcDPyPEL19pXRS2E4iJ46zH7xP6uSgAaPdwDrx', - }, - ], - authentication: [ - 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', - ], - assertionMethod: [ - 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', - ], - keyAgreement: [ - { - id: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6LSrdqo4M24WRDJj1h2hXxgtDTyzjjKCiyapYVgrhwZAySn', - type: 'X25519KeyAgreementKey2019', - controller: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', - publicKeyBase58: 'FxfdY3DCQxVZddKGAtSjZdFW9bCCW7oRwZn1NFJ2Tbg2', - }, - ], - capabilityInvocation: [ - 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', - ], - capabilityDelegation: [ - 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', - ], - }) + expect(response.body.didDocument).to.deep.equal(testDidDocument) }) test('should give 500 when did document record is not found', async () => { @@ -74,6 +46,57 @@ describe('DidController', () => { }) }) + describe('Import Did', () => { + test('should return did document after importing Did', async () => { + const importRequest: ImportDidOptions = { did: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL' } + const response = await request(app).post(`/dids/import`).send(importRequest) + + expect(response.statusCode).to.equal(200) + expect(response.body.didDocument).to.deep.equal(testDidDocument) + }) + + test('should give 400 for an invalid Did', async () => { + const importRequest: ImportDidOptions = { did: 'did:key:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' } + const response = await request(app).post(`/dids/import`).send(importRequest) + + expect(response.statusCode).to.equal(400) + }) + }) + + describe('Create Did', () => { + const createRequest: DidCreateOptions = { + method: 'key', + options: { + keyType: KeyType.Ed25519, + }, + } + + test('should return did document after creating Did', async () => { + const createStub = stub(aliceAgent.dids, 'create').resolves(testDidCreate) + const getResult = (): Promise => createStub.firstCall.returnValue + + const response = await request(app).post(`/dids/create`).send(createRequest) + + expect(createStub.calledWithMatch(createRequest)).equals(true) + + expect(response.statusCode).to.equal(200) + + const result = await getResult() + expect(response.body).to.deep.equal(objectToJson(result.didState)) + }) + + test('should give 400 for an invalid Did method', async () => { + const createRequest: DidCreateOptions = { + method: 'foo', + options: { + keyType: KeyType.Ed25519, + }, + } + const response = await request(app).post(`/dids/create`).send(createRequest) + expect(response.statusCode).to.equal(500) + }) + }) + after(async () => { await aliceAgent.shutdown() await aliceAgent.wallet.delete() diff --git a/tests/proof.test.ts b/tests/proof.test.ts index d651e6b9..5056fed9 100644 --- a/tests/proof.test.ts +++ b/tests/proof.test.ts @@ -1,13 +1,18 @@ +import type { + AcceptProofProposalOptions, + CreateProofRequestOptions, + ProposeProofOptions, + RequestProofOptions, +} from '../src/controllers/types' +import type { Agent, ProofStateChangedEvent } from '@aries-framework/core' +import type { Server } from 'net' + import { describe, before, beforeEach, after, afterEach, test } from 'mocha' import { expect, use as chaiUse, Assertion as assertion } from 'chai' import chaiAssertionsCount from 'chai-assertions-count' -import { stub, match, restore as sinonRestore } from 'sinon' - -import type { RequestProofProposalOptions } from '../src/controllers/types' -import type { Agent, ProofStateChangedEvent } from '@aries-framework/core' -import type { Server } from 'net' +import { stub, restore as sinonRestore } from 'sinon' -import { ProofEventTypes, ProofExchangeRecord, ProofState } from '@aries-framework/core' +import { AgentMessage, ProofEventTypes, ProofExchangeRecord, ProofState } from '@aries-framework/core' import request from 'supertest' import WebSocket from 'ws' @@ -21,6 +26,7 @@ describe('ProofController', () => { let app: Server let aliceAgent: Agent let bobAgent: Agent + let testMessage: AgentMessage let testProof: ProofExchangeRecord before(async () => { @@ -29,6 +35,7 @@ describe('ProofController', () => { app = await startServer(bobAgent, { port: 3033 }) testProof = getTestProof() + testMessage = new AgentMessage() }) beforeEach(() => { @@ -106,15 +113,20 @@ describe('ProofController', () => { }) describe('Propose proof', () => { - const proposalRequest: RequestProofProposalOptions = { + const proposalRequest: ProposeProofOptions = { connectionId: '123456aa-aa78-90a1-aa23-456a7da89010', - attributes: [ - { - name: 'test', - credentialDefinitionId: 'WghBqNdoFjaYh6F5N9eBF:3:CL:3210:test', + protocolVersion: 'v2', + proofFormats: { + anoncreds: { + attributes: [ + { + name: 'test', + credentialDefinitionId: 'WghBqNdoFjaYh6F5N9eBF:3:CL:3210:test', + }, + ], + predicates: [], }, - ], - predicates: [], + }, comment: 'test', } test('should return proof record', async () => { @@ -124,19 +136,7 @@ describe('ProofController', () => { const response = await request(app).post('/proofs/propose-proof').send(proposalRequest) - expect( - proposeProofStub.calledWithMatch({ - connectionId: proposalRequest.connectionId, - protocolVersion: 'v2', - proofFormats: { - anoncreds: { - attributes: proposalRequest.attributes, - predicates: proposalRequest.predicates, - }, - }, - comment: proposalRequest.comment, - }) - ).equals(true) + expect(proposeProofStub.calledWithMatch(proposalRequest)).equals(true) expect(response.statusCode).to.be.equal(200) expect(response.body).to.deep.equal(objectToJson(await getResult())) }) @@ -149,10 +149,12 @@ describe('ProofController', () => { }) describe('Accept proof proposal', () => { - const acceptRequest = { - request: { - name: 'string', - version: 'string', + const acceptRequest: AcceptProofProposalOptions = { + proofFormats: { + anoncreds: { + name: 'string', + version: 'string', + }, }, comment: 'string', } @@ -167,13 +169,7 @@ describe('ProofController', () => { expect( acceptProposalStub.calledWithMatch({ proofRecordId: testProof.id, - proofFormats: { - anoncreds: { - name: acceptRequest.request.name, - version: acceptRequest.request.version, - }, - }, - comment: acceptRequest.comment, + ...acceptRequest, }) ).equals(true) expect(response.statusCode).to.be.equal(200) @@ -187,69 +183,73 @@ describe('ProofController', () => { }) }) - // TODO: how to do out-of-band proof - describe.skip('Request out of band proof', () => { - test('should return proof record', async () => { - const response = await request(app) - .post(`/proofs/request-outofband-proof`) - .send({ - proofRequestOptions: { - name: 'string', - version: '1.0', - requestedAttributes: { - additionalProp1: { - name: 'string', - }, + describe('Request out of band proof', () => { + const proofRequest: CreateProofRequestOptions = { + protocolVersion: 'v2', + proofFormats: { + anoncreds: { + name: 'string', + version: '1.0', + requested_attributes: { + additionalProp1: { + name: 'string', }, }, - }) + }, + }, + } - expect(response.statusCode).to.be.equal(200) - expect(response.body.proofUrl).to.not.be.undefined - expect(response.body.proofRecord).to.not.be.undefined + test('should return proof record', async () => { + const mockValue = { message: testMessage, proofRecord: testProof } + const createRequestStub = stub(bobAgent.proofs, 'createRequest') + createRequestStub.resolves(mockValue) + const getResult = (): Promise => createRequestStub.firstCall.returnValue + + const response = await request(app).post(`/proofs/create-request`).send(proofRequest) + + expect(response.statusCode).to.equal(200) + + const result = await getResult() + expect(response.body.message).to.deep.equal(objectToJson(result.message)) + expect(response.body.proofRecord).to.deep.equal(objectToJson(result.proofRecord)) }) }) describe('Request proof', () => { - const requestProofSimple = { + const requestProofRequest: RequestProofOptions = { connectionId: 'string', - proofRequestOptions: { - name: 'string', - version: '1.0', - requestedAttributes: { - additionalProp1: { - name: 'string', + protocolVersion: 'v2', + proofFormats: { + anoncreds: { + name: 'string', + version: '1.0', + requested_attributes: { + additionalProp1: { + name: 'string', + }, }, }, - requestedPredicates: {}, }, } - const requestProofWthAttrRestrictions = { + const requestProofRequestWithAttr: RequestProofOptions = { connectionId: 'string', - proofRequestOptions: { - name: 'string', - version: '1.0', - requestedAttributes: { - additionalProp1: { - name: 'string', - restrictions: [ - { - schemaId: 'schemaId', - schemaIssuerId: 'schemaIssuerId', - schemaName: 'schemaName', - schemaVersion: 'schemaVersion', - issuerId: 'issuerId', - credDefId: 'credDefId', - revRegId: 'revRegId', - schemaIssuerDid: 'schemaIssuerDid', - issuerDid: 'issuerDid', - requiredAttributes: ['a', 'b'], - requiredAttributeValues: { c: 'd', e: 'f' }, - }, - ], + protocolVersion: 'v2', + proofFormats: { + anoncreds: { + name: 'string', + version: '1.0', + requested_attributes: { + additionalProp1: { + name: 'string', + restrictions: [ + { + attributeMarkers: { a: true, b: false }, + attributeValues: { c: 'd', e: 'f' }, + }, + ], + }, }, }, - requestedPredicates: {}, }, } @@ -258,7 +258,7 @@ describe('ProofController', () => { requestProofStub.resolves(testProof) const getResult = (): Promise => requestProofStub.firstCall.returnValue - const response = await request(app).post(`/proofs/request-proof`).send(requestProofSimple) + const response = await request(app).post(`/proofs/request-proof`).send(requestProofRequest) expect(response.statusCode).to.be.equal(200) expect(response.body).to.deep.equal(objectToJson(await getResult())) @@ -268,7 +268,7 @@ describe('ProofController', () => { const requestProofStub = stub(bobAgent.proofs, 'requestProof') requestProofStub.resolves(testProof) - const response = await request(app).post(`/proofs/request-proof`).send(requestProofWthAttrRestrictions) + const response = await request(app).post(`/proofs/request-proof`).send(requestProofRequestWithAttr) expect(response.statusCode).to.be.equal(200) expect( @@ -284,24 +284,14 @@ describe('ProofController', () => { name: 'string', restrictions: [ { - schema_id: 'schemaId', - schema_issuer_id: 'schemaIssuerId', - schema_name: 'schemaName', - schema_version: 'schemaVersion', - issuer_id: 'issuerId', - cred_def_id: 'credDefId', - rev_reg_id: 'revRegId', - schema_issuer_did: 'schemaIssuerDid', - issuer_did: 'issuerDid', 'attr::a::marker': '1', - 'attr::b::marker': '1', + 'attr::b::marker': '0', 'attr::c::value': 'd', 'attr::e::value': 'f', }, ], }, }, - requested_predicates: {}, }, }, }) @@ -309,7 +299,7 @@ describe('ProofController', () => { }) test('should give 404 not found when connection is not found', async () => { - const response = await request(app).post(`/proofs/request-proof`).send(requestProofSimple) + const response = await request(app).post(`/proofs/request-proof`).send(requestProofRequest) expect(response.statusCode).to.be.equal(404) }) diff --git a/tests/utils/helpers.ts b/tests/utils/helpers.ts index 96d464ba..f63184e7 100644 --- a/tests/utils/helpers.ts +++ b/tests/utils/helpers.ts @@ -1,5 +1,5 @@ import type { AnonCredsSchema, AnonCredsCredentialDefinition } from '@aries-framework/anoncreds' -import type { ConnectionRecordProps } from '@aries-framework/core' +import type { ConnectionRecordProps, DidCreateResult } from '@aries-framework/core' import { AgentMessage, @@ -12,6 +12,7 @@ import { ProofExchangeRecord, OutOfBandInvitation, ConnectionInvitationMessage, + DidDocument, } from '@aries-framework/core' import { JsonEncoder } from '@aries-framework/core/build/utils/JsonEncoder' import { randomUUID } from 'crypto' @@ -387,3 +388,92 @@ export function getTestConnection({ theirLabel, }) } +export function getTestDidDocument() { + return { + '@context': [ + 'https://w3id.org/did/v1', + 'https://w3id.org/security/suites/ed25519-2018/v1', + 'https://w3id.org/security/suites/x25519-2019/v1', + ], + id: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', + verificationMethod: [ + { + id: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', + type: 'Ed25519VerificationKey2018', + controller: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', + publicKeyBase58: '6fioC1zcDPyPEL19pXRS2E4iJ46zH7xP6uSgAaPdwDrx', + }, + ], + authentication: [ + 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', + ], + assertionMethod: [ + 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', + ], + keyAgreement: [ + { + id: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6LSrdqo4M24WRDJj1h2hXxgtDTyzjjKCiyapYVgrhwZAySn', + type: 'X25519KeyAgreementKey2019', + controller: 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', + publicKeyBase58: 'FxfdY3DCQxVZddKGAtSjZdFW9bCCW7oRwZn1NFJ2Tbg2', + }, + ], + capabilityInvocation: [ + 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', + ], + capabilityDelegation: [ + 'did:key:z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL#z6Mkk7yqnGF3YwTrLpqrW6PGsKci7dNqh1CjnvMbzrMerSeL', + ], + } as { [x: string]: unknown } +} + +export function getTestDidCreate() { + return { + didDocumentMetadata: {}, + didRegistrationMetadata: {}, + didState: { + state: 'finished', + did: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + didDocument: JsonTransformer.fromJSON( + { + '@context': [ + 'https://w3id.org/did/v1', + 'https://w3id.org/security/suites/ed25519-2018/v1', + 'https://w3id.org/security/suites/x25519-2019/v1', + ], + id: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + verificationMethod: [ + { + id: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + type: 'Ed25519VerificationKey2018', + controller: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + publicKeyBase58: 'ApexJxnhZHC6Ctq4fCoNHKYgu87HuRTZ7oSyfehG57zE', + }, + ], + authentication: [ + 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + ], + assertionMethod: [ + 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + ], + keyAgreement: [ + { + id: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6LSm5B4fB9NA55xB7PSeMYTMS9sf8uboJvyZBaDLLSZ7Ryd', + type: 'X25519KeyAgreementKey2019', + controller: 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + publicKeyBase58: 'APzu8sLW4cND5j1g7i2W2qwPozNV6hkpgCrXqso2Q4Cs', + }, + ], + capabilityInvocation: [ + 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + ], + capabilityDelegation: [ + 'did:key:z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc#z6MkpGuzuD38tpgZKPfmLmmD8R6gihP9KJhuopMuVvfGzLmc', + ], + }, + DidDocument + ), + secret: {}, + }, + } as DidCreateResult +}