diff --git a/src/controllers/multi-tenancy/MultiTenancyController.ts b/src/controllers/multi-tenancy/MultiTenancyController.ts index 739463d8..1383c773 100644 --- a/src/controllers/multi-tenancy/MultiTenancyController.ts +++ b/src/controllers/multi-tenancy/MultiTenancyController.ts @@ -1,7 +1,7 @@ /* eslint-disable prettier/prettier */ import type { RestAgentModules, RestMultiTenantAgentModules } from '../../cliAgent' import type { Version } from '../examples' -import type { RecipientKeyOption, SchemaMetadata } from '../types' +import type { RecipientKeyOption, SafeW3cJsonLdVerifyCredentialOptions, SchemaMetadata } from '../types' import type { PolygonDidCreateOptions } from '@ayanworks/credo-polygon-w3c-module/build/dids' import type { AcceptProofRequestOptions, @@ -15,7 +15,8 @@ import type { ProofExchangeRecordProps, ProofsProtocolVersionType, Routing, -} from '@credo-ts/core' + W3cJsonLdSignCredentialOptions, + W3cVerifiableCredential} from '@credo-ts/core' import type { IndyVdrDidCreateOptions, IndyVdrDidCreateResult } from '@credo-ts/indy-vdr' import type { QuestionAnswerRecord, ValidResponse } from '@credo-ts/question-answer' import type { TenantRecord } from '@credo-ts/tenants' @@ -27,6 +28,7 @@ import { parseIndyCredentialDefinitionId, parseIndySchemaId, } from '@credo-ts/anoncreds' +import { assertAskarWallet } from '@credo-ts/askar/build/utils/assertAskarWallet' import { AcceptCredentialOfferOptions, Agent, @@ -45,7 +47,9 @@ import { injectable, createPeerDidDocumentFromServices, PeerDidNumAlgo, -} from '@credo-ts/core' + W3cJsonLdVerifiableCredential, + W3cCredential, + ClaimFormat} from '@credo-ts/core' import { QuestionAnswerRole, QuestionAnswerState } from '@credo-ts/question-answer' import axios from 'axios' import * as fs from 'fs' @@ -89,7 +93,7 @@ import { CreateProofRequestOobOptions, CreateOfferOobOptions, CreateSchemaInput, -} from '../types' + VerifyDataOptions , SignDataOptions } from '../types' import { Body, Controller, Delete, Get, Post, Query, Route, Tags, Path, Example, Security, Response } from 'tsoa' @@ -1913,4 +1917,110 @@ export class MultiTenancyController extends Controller { throw ErrorHandlingService.handle(error) } } + + + /** + * Sign data using a key + * + * @param tenantId Tenant identifier + * @param request Sign options + * data - Data has to be in base64 format + * publicKeyBase58 - Public key in base58 format + * @returns Signature in base64 format + */ + @Security('apiKey') + @Post('/sign/:tenantId') + public async sign(@Path('tenantId') tenantId: string, @Body() request: SignDataOptions) { + try { + const signature = await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { + // assertAskarWallet(tenantAgent.context.wallet) + + // tenantAgent.w3cCredentials + + const signature = await tenantAgent.context.wallet.sign({ + data: TypedArrayEncoder.fromBase64(request.data), + key: Key.fromPublicKeyBase58(request.publicKeyBase58, request.keyType), + }) + return TypedArrayEncoder.toBase64(signature) + }) + return signature + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } + + /** + * Verify data using a key + * + * @param tenantId Tenant identifier + * @param request Verify options + * data - Data has to be in base64 format + * publicKeyBase58 - Public key in base58 format + * signature - Signature in base64 format + * @returns isValidSignature - true if signature is valid, false otherwise + */ + @Security('apiKey') + @Post('/verify/:tenantId') + public async verify(@Path('tenantId') tenantId: string, @Body() request: VerifyDataOptions) { + try { + const isValidSignature = await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { + assertAskarWallet(tenantAgent.context.wallet) + const isValidSignature = await tenantAgent.context.wallet.verify({ + data: TypedArrayEncoder.fromBase64(request.data), + key: Key.fromPublicKeyBase58(request.publicKeyBase58, request.keyType), + signature: TypedArrayEncoder.fromBase64(request.signature), + }) + return isValidSignature + }) + return isValidSignature + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } + + @Security('apiKey') + @Post('/credential/sign/:tenantId') + public async signCredential( + @Path('tenantId') tenantId: string, + @Query('storeCredential') storeCredential: boolean, + @Body() credentialToSign: W3cJsonLdSignCredentialOptions | any + ) { + let storedCredential + let formattedCredential + try { + await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { + credentialToSign.format = ClaimFormat.LdpVc + + const signedCred = await tenantAgent.w3cCredentials.signCredential(credentialToSign) as W3cJsonLdVerifiableCredential + formattedCredential = signedCred.toJson() + if (storeCredential) { + storedCredential = await tenantAgent.w3cCredentials.storeCredential({ credential: signedCred }) + } + }) + return storedCredential ?? formattedCredential + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } + + @Security('apiKey') + @Post('/credential/verify/:tenantId') + public async verifyCredential( + @Path('tenantId') tenantId: string, + @Body() credentialToVerify: SafeW3cJsonLdVerifyCredentialOptions | any + ) { + let formattedCredential + try { + await this.agent.modules.tenants.withTenantAgent({ tenantId }, async (tenantAgent) => { + const {credential, ...credentialOptions}= credentialToVerify + const transformedCredential = JsonTransformer.fromJSON(credentialToVerify?.credential, W3cJsonLdVerifiableCredential) + const signedCred = await tenantAgent.w3cCredentials.verifyCredential({credential: transformedCredential, ...credentialOptions}) + formattedCredential = signedCred + }) + return formattedCredential + } catch (error) { + throw ErrorHandlingService.handle(error) + } + } } + diff --git a/src/controllers/types.ts b/src/controllers/types.ts index 3753d6f2..f3acb079 100644 --- a/src/controllers/types.ts +++ b/src/controllers/types.ts @@ -25,8 +25,13 @@ import type { Attachment, KeyType, JsonLdCredentialFormat, + JsonObject, + W3cJsonLdVerifyCredentialOptions, + DataIntegrityProofOptions, } from '@credo-ts/core' +import type { SingleOrArray } from '@credo-ts/core/build/utils' import type { DIDDocument } from 'did-resolver' +import { LinkedDataProofOptions } from '@credo-ts/core/build/modules/vc/data-integrity/models/LinkedDataProof' export type TenantConfig = Pick & { walletConfig: Pick @@ -37,10 +42,6 @@ export interface AgentInfo { endpoints: string[] isInitialized: boolean publicDid: void - // publicDid?: { - // did: string - // verkey: string - // } } export interface AgentMessageType { @@ -388,3 +389,33 @@ export interface SchemaMetadata { * @example "ea4e5e69-fc04-465a-90d2-9f8ff78aa71d" */ export type ThreadId = string + +export type SignDataOptions = { + data: string + keyType: KeyType + publicKeyBase58: string +} + +export type VerifyDataOptions = { + data: string + keyType: KeyType + publicKeyBase58: string + signature: string +} + +export interface jsonLdCredentialOptions { + '@context': Array + type: Array + credentialSubject: SingleOrArray + proofType: string +} + +export interface credentialPayloadToSign { + issuerDID: string + method: string + credential: jsonLdCredentialOptions // TODO: add support for other credential format +} +export interface SafeW3cJsonLdVerifyCredentialOptions extends W3cJsonLdVerifyCredentialOptions { + // Ommited due to issues with TSOA + proof: SingleOrArray | DataIntegrityProofOptions> +} \ No newline at end of file diff --git a/src/routes/routes.ts b/src/routes/routes.ts index 4566e855..c2294d13 100644 --- a/src/routes/routes.ts +++ b/src/routes/routes.ts @@ -693,6 +693,205 @@ const models: TsoaRoute.Models = { "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"content":{"dataType":"string","required":true}},"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 + "SignDataOptions": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"publicKeyBase58":{"dataType":"string","required":true},"keyType":{"ref":"KeyType","required":true},"data":{"dataType":"string","required":true}},"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 + "VerifyDataOptions": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"signature":{"dataType":"string","required":true},"publicKeyBase58":{"dataType":"string","required":true},"keyType":{"ref":"KeyType","required":true},"data":{"dataType":"string","required":true}},"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 + "ClaimFormat.LdpVc": { + "dataType": "refEnum", + "enums": ["ldp_vc"], + }, + // 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 + "ProofPurpose": { + "dataType": "refAlias", + "type": {"dataType":"any","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 + "ClaimFormat": { + "dataType": "refEnum", + "enums": ["jwt","jwt_vc","jwt_vp","ldp","ldp_vc","ldp_vp","di","di_vc","di_vp","vc+sd-jwt"], + }, + // 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 + "W3cIssuer": { + "dataType": "refObject", + "properties": { + "id": {"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 + "W3cCredentialSubject": { + "dataType": "refObject", + "properties": { + "id": {"dataType":"string"}, + "claims": {"ref":"Record_string.unknown_"}, + }, + "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 + "SingleOrArray_W3cCredentialSubject_": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"ref":"W3cCredentialSubject"},{"dataType":"array","array":{"dataType":"refObject","ref":"W3cCredentialSubject"}}],"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 + "W3cCredentialSchema": { + "dataType": "refObject", + "properties": { + "id": {"dataType":"string","required":true}, + "type": {"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 + "SingleOrArray_W3cCredentialSchema_": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"ref":"W3cCredentialSchema"},{"dataType":"array","array":{"dataType":"refObject","ref":"W3cCredentialSchema"}}],"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 + "W3cCredentialStatus": { + "dataType": "refObject", + "properties": { + "id": {"dataType":"string","required":true}, + "type": {"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 + "W3cCredential": { + "dataType": "refObject", + "properties": { + "context": {"dataType":"array","array":{"dataType":"union","subSchemas":[{"dataType":"string"},{"ref":"JsonObject"}]},"required":true}, + "id": {"dataType":"string"}, + "type": {"dataType":"array","array":{"dataType":"string"},"required":true}, + "issuer": {"dataType":"union","subSchemas":[{"dataType":"string"},{"ref":"W3cIssuer"}],"required":true}, + "issuanceDate": {"dataType":"string","required":true}, + "expirationDate": {"dataType":"string"}, + "credentialSubject": {"ref":"SingleOrArray_W3cCredentialSubject_","required":true}, + "credentialSchema": {"ref":"SingleOrArray_W3cCredentialSchema_"}, + "credentialStatus": {"ref":"W3cCredentialStatus"}, + }, + "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 + "W3cJsonLdSignCredentialOptions": { + "dataType": "refObject", + "properties": { + "format": {"ref":"ClaimFormat.LdpVc","required":true}, + "credential": {"ref":"W3cCredential","required":true}, + "verificationMethod": {"dataType":"string","required":true}, + "proofType": {"dataType":"string","required":true}, + "proofPurpose": {"ref":"ProofPurpose"}, + "created": {"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 + "Pick_LinkedDataProofOptions.Exclude_keyofLinkedDataProofOptions.cryptosuite__": { + "dataType": "refAlias", + "type": {"dataType":"nestedObjectLiteral","nestedProperties":{"type":{"dataType":"string","required":true},"proofPurpose":{"dataType":"string","required":true},"verificationMethod":{"dataType":"string","required":true},"created":{"dataType":"string","required":true},"domain":{"dataType":"string"},"challenge":{"dataType":"string"},"jws":{"dataType":"string"},"proofValue":{"dataType":"string"},"nonce":{"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 + "Omit_LinkedDataProofOptions.cryptosuite_": { + "dataType": "refAlias", + "type": {"ref":"Pick_LinkedDataProofOptions.Exclude_keyofLinkedDataProofOptions.cryptosuite__","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 + "DataIntegrityProofOptions": { + "dataType": "refObject", + "properties": { + "type": {"dataType":"string","required":true}, + "cryptosuite": {"dataType":"string","required":true}, + "verificationMethod": {"dataType":"string","required":true}, + "proofPurpose": {"dataType":"string","required":true}, + "domain": {"dataType":"string"}, + "challenge": {"dataType":"string"}, + "nonce": {"dataType":"string"}, + "created": {"dataType":"string"}, + "expires": {"dataType":"string"}, + "proofValue": {"dataType":"string"}, + "previousProof": {"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 + "SingleOrArray_Omit_LinkedDataProofOptions.cryptosuite_-or-DataIntegrityProofOptions_": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"dataType":"union","subSchemas":[{"ref":"Omit_LinkedDataProofOptions.cryptosuite_"},{"ref":"DataIntegrityProofOptions"}]},{"dataType":"array","array":{"dataType":"union","subSchemas":[{"ref":"Omit_LinkedDataProofOptions.cryptosuite_"},{"ref":"DataIntegrityProofOptions"}]}}],"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 + "LinkedDataProof": { + "dataType": "refObject", + "properties": { + "type": {"dataType":"string","required":true}, + "proofPurpose": {"dataType":"string","required":true}, + "verificationMethod": {"dataType":"string","required":true}, + "created": {"dataType":"string","required":true}, + "domain": {"dataType":"string"}, + "challenge": {"dataType":"string"}, + "jws": {"dataType":"string"}, + "proofValue": {"dataType":"string"}, + "nonce": {"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 + "DataIntegrityProof": { + "dataType": "refObject", + "properties": { + "type": {"dataType":"string","required":true}, + "cryptosuite": {"dataType":"string","required":true}, + "proofPurpose": {"dataType":"string","required":true}, + "verificationMethod": {"dataType":"string","required":true}, + "domain": {"dataType":"string"}, + "challenge": {"dataType":"string"}, + "nonce": {"dataType":"string"}, + "created": {"dataType":"string"}, + "expires": {"dataType":"string"}, + "proofValue": {"dataType":"string"}, + "previousProof": {"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 + "SingleOrArray_LinkedDataProof-or-DataIntegrityProof_": { + "dataType": "refAlias", + "type": {"dataType":"union","subSchemas":[{"dataType":"union","subSchemas":[{"ref":"LinkedDataProof"},{"ref":"DataIntegrityProof"}]},{"dataType":"array","array":{"dataType":"union","subSchemas":[{"ref":"LinkedDataProof"},{"ref":"DataIntegrityProof"}]}}],"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 + "W3cJsonLdVerifiableCredential": { + "dataType": "refObject", + "properties": { + "context": {"dataType":"array","array":{"dataType":"union","subSchemas":[{"dataType":"string"},{"ref":"JsonObject"}]},"required":true}, + "id": {"dataType":"string"}, + "type": {"dataType":"array","array":{"dataType":"string"},"required":true}, + "issuer": {"dataType":"union","subSchemas":[{"dataType":"string"},{"ref":"W3cIssuer"}],"required":true}, + "issuanceDate": {"dataType":"string","required":true}, + "expirationDate": {"dataType":"string"}, + "credentialSubject": {"ref":"SingleOrArray_W3cCredentialSubject_","required":true}, + "credentialSchema": {"ref":"SingleOrArray_W3cCredentialSchema_"}, + "credentialStatus": {"ref":"W3cCredentialStatus"}, + "proof": {"ref":"SingleOrArray_LinkedDataProof-or-DataIntegrityProof_","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 + "SafeW3cJsonLdVerifyCredentialOptions": { + "dataType": "refObject", + "properties": { + "credential": {"ref":"W3cJsonLdVerifiableCredential","required":true}, + "verifyCredentialStatus": {"dataType":"boolean"}, + "proofPurpose": {"ref":"ProofPurpose"}, + "proof": {"ref":"SingleOrArray_Omit_LinkedDataProofOptions.cryptosuite_-or-DataIntegrityProofOptions_","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 "DidRegistrationSecretOptions": { "dataType": "refAlias", "type": {"ref":"Record_string.unknown_","validators":{}}, @@ -3546,6 +3745,155 @@ export function RegisterRoutes(app: 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('/multi-tenancy/sign/:tenantId', + authenticateMiddleware([{"apiKey":[]}]), + ...(fetchMiddlewares(MultiTenancyController)), + ...(fetchMiddlewares(MultiTenancyController.prototype.sign)), + + async function MultiTenancyController_sign(request: ExRequest, response: ExResponse, next: any) { + const args: Record = { + tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, + request: {"in":"body","name":"request","required":true,"ref":"SignDataOptions"}, + }; + + // 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 = templateService.getValidatedArgs({ args, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(MultiTenancyController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'sign', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } 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('/multi-tenancy/verify/:tenantId', + authenticateMiddleware([{"apiKey":[]}]), + ...(fetchMiddlewares(MultiTenancyController)), + ...(fetchMiddlewares(MultiTenancyController.prototype.verify)), + + async function MultiTenancyController_verify(request: ExRequest, response: ExResponse, next: any) { + const args: Record = { + tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, + request: {"in":"body","name":"request","required":true,"ref":"VerifyDataOptions"}, + }; + + // 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 = templateService.getValidatedArgs({ args, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(MultiTenancyController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'verify', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } 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('/multi-tenancy/credential/sign/:tenantId', + authenticateMiddleware([{"apiKey":[]}]), + ...(fetchMiddlewares(MultiTenancyController)), + ...(fetchMiddlewares(MultiTenancyController.prototype.signCredential)), + + async function MultiTenancyController_signCredential(request: ExRequest, response: ExResponse, next: any) { + const args: Record = { + tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, + storeCredential: {"in":"query","name":"storeCredential","required":true,"dataType":"boolean"}, + credentialToSign: {"in":"body","name":"credentialToSign","required":true,"dataType":"union","subSchemas":[{"ref":"W3cJsonLdSignCredentialOptions"},{"dataType":"any"}]}, + }; + + // 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 = templateService.getValidatedArgs({ args, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(MultiTenancyController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'signCredential', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } 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('/multi-tenancy/credential/verify/:tenantId', + authenticateMiddleware([{"apiKey":[]}]), + ...(fetchMiddlewares(MultiTenancyController)), + ...(fetchMiddlewares(MultiTenancyController.prototype.verifyCredential)), + + async function MultiTenancyController_verifyCredential(request: ExRequest, response: ExResponse, next: any) { + const args: Record = { + tenantId: {"in":"path","name":"tenantId","required":true,"dataType":"string"}, + credentialToVerify: {"in":"body","name":"credentialToVerify","required":true,"dataType":"union","subSchemas":[{"ref":"SafeW3cJsonLdVerifyCredentialOptions"},{"dataType":"any"}]}, + }; + + // 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 = templateService.getValidatedArgs({ args, request, response }); + + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get(MultiTenancyController); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + + await templateService.apiHandler({ + methodName: 'verifyCredential', + controller, + response, + next, + validatedArgs, + successStatus: undefined, + }); + } 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('/transactions/endorse', authenticateMiddleware([{"apiKey":[]}]), ...(fetchMiddlewares(EndorserTransactionController)), diff --git a/src/routes/swagger.json b/src/routes/swagger.json index 8eea6fe5..c872bd20 100644 --- a/src/routes/swagger.json +++ b/src/routes/swagger.json @@ -1625,6 +1625,562 @@ "type": "object", "description": "Construct a type with a set of properties K of type T" }, + "SignDataOptions": { + "properties": { + "publicKeyBase58": { + "type": "string" + }, + "keyType": { + "$ref": "#/components/schemas/KeyType" + }, + "data": { + "type": "string" + } + }, + "required": [ + "publicKeyBase58", + "keyType", + "data" + ], + "type": "object" + }, + "VerifyDataOptions": { + "properties": { + "signature": { + "type": "string" + }, + "publicKeyBase58": { + "type": "string" + }, + "keyType": { + "$ref": "#/components/schemas/KeyType" + }, + "data": { + "type": "string" + } + }, + "required": [ + "signature", + "publicKeyBase58", + "keyType", + "data" + ], + "type": "object" + }, + "ClaimFormat.LdpVc": { + "enum": [ + "ldp_vc" + ], + "type": "string" + }, + "ProofPurpose": {}, + "ClaimFormat": { + "description": "Defines the claim format based on the formats registered in\n[DIF Claim Format Registry](https://identity.foundation/claim-format-registry/).", + "enum": [ + "jwt", + "jwt_vc", + "jwt_vp", + "ldp", + "ldp_vc", + "ldp_vp", + "di", + "di_vc", + "di_vp", + "vc+sd-jwt" + ], + "type": "string" + }, + "W3cIssuer": { + "properties": { + "id": { + "type": "string" + } + }, + "required": [ + "id" + ], + "type": "object", + "additionalProperties": false + }, + "W3cCredentialSubject": { + "properties": { + "id": { + "type": "string" + }, + "claims": { + "$ref": "#/components/schemas/Record_string.unknown_" + } + }, + "type": "object", + "additionalProperties": false + }, + "SingleOrArray_W3cCredentialSubject_": { + "anyOf": [ + { + "$ref": "#/components/schemas/W3cCredentialSubject" + }, + { + "items": { + "$ref": "#/components/schemas/W3cCredentialSubject" + }, + "type": "array" + } + ] + }, + "W3cCredentialSchema": { + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "SingleOrArray_W3cCredentialSchema_": { + "anyOf": [ + { + "$ref": "#/components/schemas/W3cCredentialSchema" + }, + { + "items": { + "$ref": "#/components/schemas/W3cCredentialSchema" + }, + "type": "array" + } + ] + }, + "W3cCredentialStatus": { + "properties": { + "id": { + "type": "string" + }, + "type": { + "type": "string" + } + }, + "required": [ + "id", + "type" + ], + "type": "object", + "additionalProperties": false + }, + "W3cCredential": { + "properties": { + "context": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/JsonObject" + } + ] + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "type": { + "items": { + "type": "string" + }, + "type": "array" + }, + "issuer": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/W3cIssuer" + } + ] + }, + "issuanceDate": { + "type": "string" + }, + "expirationDate": { + "type": "string" + }, + "credentialSubject": { + "$ref": "#/components/schemas/SingleOrArray_W3cCredentialSubject_" + }, + "credentialSchema": { + "$ref": "#/components/schemas/SingleOrArray_W3cCredentialSchema_" + }, + "credentialStatus": { + "$ref": "#/components/schemas/W3cCredentialStatus" + } + }, + "required": [ + "context", + "type", + "issuer", + "issuanceDate", + "credentialSubject" + ], + "type": "object", + "additionalProperties": false + }, + "W3cJsonLdSignCredentialOptions": { + "properties": { + "format": { + "$ref": "#/components/schemas/ClaimFormat.LdpVc", + "description": "The format of the credential to be signed. Must be either `jwt_vc` or `ldp_vc`." + }, + "credential": { + "$ref": "#/components/schemas/W3cCredential", + "description": "The credential to be signed." + }, + "verificationMethod": { + "type": "string", + "description": "URI of the verificationMethod to be used for signing the credential.\n\nMust be a valid did url pointing to a key." + }, + "proofType": { + "type": "string", + "description": "The proofType to be used for signing the credential.\n\nMust be a valid Linked Data Signature suite." + }, + "proofPurpose": { + "$ref": "#/components/schemas/ProofPurpose" + }, + "created": { + "type": "string" + } + }, + "required": [ + "format", + "credential", + "verificationMethod", + "proofType" + ], + "type": "object", + "additionalProperties": false + }, + "Pick_LinkedDataProofOptions.Exclude_keyofLinkedDataProofOptions.cryptosuite__": { + "properties": { + "type": { + "type": "string" + }, + "proofPurpose": { + "type": "string" + }, + "verificationMethod": { + "type": "string" + }, + "created": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "challenge": { + "type": "string" + }, + "jws": { + "type": "string" + }, + "proofValue": { + "type": "string" + }, + "nonce": { + "type": "string" + } + }, + "required": [ + "type", + "proofPurpose", + "verificationMethod", + "created" + ], + "type": "object", + "description": "From T, pick a set of properties whose keys are in the union K" + }, + "Omit_LinkedDataProofOptions.cryptosuite_": { + "$ref": "#/components/schemas/Pick_LinkedDataProofOptions.Exclude_keyofLinkedDataProofOptions.cryptosuite__", + "description": "Construct a type with the properties of T except for those in type K." + }, + "DataIntegrityProofOptions": { + "properties": { + "type": { + "type": "string" + }, + "cryptosuite": { + "type": "string" + }, + "verificationMethod": { + "type": "string" + }, + "proofPurpose": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "challenge": { + "type": "string" + }, + "nonce": { + "type": "string" + }, + "created": { + "type": "string" + }, + "expires": { + "type": "string" + }, + "proofValue": { + "type": "string" + }, + "previousProof": { + "type": "string" + } + }, + "required": [ + "type", + "cryptosuite", + "verificationMethod", + "proofPurpose" + ], + "type": "object", + "additionalProperties": false + }, + "SingleOrArray_Omit_LinkedDataProofOptions.cryptosuite_-or-DataIntegrityProofOptions_": { + "anyOf": [ + { + "anyOf": [ + { + "$ref": "#/components/schemas/Omit_LinkedDataProofOptions.cryptosuite_" + }, + { + "$ref": "#/components/schemas/DataIntegrityProofOptions" + } + ] + }, + { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/Omit_LinkedDataProofOptions.cryptosuite_" + }, + { + "$ref": "#/components/schemas/DataIntegrityProofOptions" + } + ] + }, + "type": "array" + } + ] + }, + "LinkedDataProof": { + "description": "Linked Data Proof", + "properties": { + "type": { + "type": "string" + }, + "proofPurpose": { + "type": "string" + }, + "verificationMethod": { + "type": "string" + }, + "created": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "challenge": { + "type": "string" + }, + "jws": { + "type": "string" + }, + "proofValue": { + "type": "string" + }, + "nonce": { + "type": "string" + } + }, + "required": [ + "type", + "proofPurpose", + "verificationMethod", + "created" + ], + "type": "object", + "additionalProperties": false + }, + "DataIntegrityProof": { + "description": "Linked Data Proof", + "properties": { + "type": { + "type": "string" + }, + "cryptosuite": { + "type": "string" + }, + "proofPurpose": { + "type": "string" + }, + "verificationMethod": { + "type": "string" + }, + "domain": { + "type": "string" + }, + "challenge": { + "type": "string" + }, + "nonce": { + "type": "string" + }, + "created": { + "type": "string" + }, + "expires": { + "type": "string" + }, + "proofValue": { + "type": "string" + }, + "previousProof": { + "type": "string" + } + }, + "required": [ + "type", + "cryptosuite", + "proofPurpose", + "verificationMethod" + ], + "type": "object", + "additionalProperties": false + }, + "SingleOrArray_LinkedDataProof-or-DataIntegrityProof_": { + "anyOf": [ + { + "anyOf": [ + { + "$ref": "#/components/schemas/LinkedDataProof" + }, + { + "$ref": "#/components/schemas/DataIntegrityProof" + } + ] + }, + { + "items": { + "anyOf": [ + { + "$ref": "#/components/schemas/LinkedDataProof" + }, + { + "$ref": "#/components/schemas/DataIntegrityProof" + } + ] + }, + "type": "array" + } + ] + }, + "W3cJsonLdVerifiableCredential": { + "properties": { + "context": { + "items": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/JsonObject" + } + ] + }, + "type": "array" + }, + "id": { + "type": "string" + }, + "type": { + "items": { + "type": "string" + }, + "type": "array" + }, + "issuer": { + "anyOf": [ + { + "type": "string" + }, + { + "$ref": "#/components/schemas/W3cIssuer" + } + ] + }, + "issuanceDate": { + "type": "string" + }, + "expirationDate": { + "type": "string" + }, + "credentialSubject": { + "$ref": "#/components/schemas/SingleOrArray_W3cCredentialSubject_" + }, + "credentialSchema": { + "$ref": "#/components/schemas/SingleOrArray_W3cCredentialSchema_" + }, + "credentialStatus": { + "$ref": "#/components/schemas/W3cCredentialStatus" + }, + "proof": { + "$ref": "#/components/schemas/SingleOrArray_LinkedDataProof-or-DataIntegrityProof_" + } + }, + "required": [ + "context", + "type", + "issuer", + "issuanceDate", + "credentialSubject", + "proof" + ], + "type": "object", + "additionalProperties": false + }, + "SafeW3cJsonLdVerifyCredentialOptions": { + "properties": { + "credential": { + "$ref": "#/components/schemas/W3cJsonLdVerifiableCredential" + }, + "verifyCredentialStatus": { + "type": "boolean", + "description": "Whether to verify the credentialStatus, if present." + }, + "proofPurpose": { + "$ref": "#/components/schemas/ProofPurpose" + }, + "proof": { + "$ref": "#/components/schemas/SingleOrArray_Omit_LinkedDataProofOptions.cryptosuite_-or-DataIntegrityProofOptions_" + } + }, + "required": [ + "credential", + "proof" + ], + "type": "object", + "additionalProperties": false + }, "DidRegistrationSecretOptions": { "$ref": "#/components/schemas/Record_string.unknown_" }, @@ -6336,6 +6892,208 @@ } } }, + "/multi-tenancy/sign/{tenantId}": { + "post": { + "operationId": "Sign", + "responses": { + "200": { + "description": "Signature in base64 format", + "content": { + "application/json": { + "schema": { + "type": "string" + } + } + } + } + }, + "description": "Sign data using a key", + "tags": [ + "MultiTenancy" + ], + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "description": "Tenant identifier", + "in": "path", + "name": "tenantId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Sign options\ndata - Data has to be in base64 format\npublicKeyBase58 - Public key in base58 format", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SignDataOptions", + "description": "Sign options\ndata - Data has to be in base64 format\npublicKeyBase58 - Public key in base58 format" + } + } + } + } + } + }, + "/multi-tenancy/verify/{tenantId}": { + "post": { + "operationId": "Verify", + "responses": { + "200": { + "description": "isValidSignature - true if signature is valid, false otherwise", + "content": { + "application/json": { + "schema": { + "type": "boolean" + } + } + } + } + }, + "description": "Verify data using a key", + "tags": [ + "MultiTenancy" + ], + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "description": "Tenant identifier", + "in": "path", + "name": "tenantId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "description": "Verify options\ndata - Data has to be in base64 format\npublicKeyBase58 - Public key in base58 format\nsignature - Signature in base64 format", + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VerifyDataOptions", + "description": "Verify options\ndata - Data has to be in base64 format\npublicKeyBase58 - Public key in base58 format\nsignature - Signature in base64 format" + } + } + } + } + } + }, + "/multi-tenancy/credential/sign/{tenantId}": { + "post": { + "operationId": "SignCredential", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "tags": [ + "MultiTenancy" + ], + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "in": "path", + "name": "tenantId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "in": "query", + "name": "storeCredential", + "required": true, + "schema": { + "type": "boolean" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/W3cJsonLdSignCredentialOptions" + }, + {} + ] + } + } + } + } + } + }, + "/multi-tenancy/credential/verify/{tenantId}": { + "post": { + "operationId": "VerifyCredential", + "responses": { + "200": { + "description": "Ok", + "content": { + "application/json": { + "schema": {} + } + } + } + }, + "tags": [ + "MultiTenancy" + ], + "security": [ + { + "apiKey": [] + } + ], + "parameters": [ + { + "in": "path", + "name": "tenantId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/SafeW3cJsonLdVerifyCredentialOptions" + }, + {} + ] + } + } + } + } + } + }, "/transactions/endorse": { "post": { "operationId": "EndorserTransaction",