11/* eslint-disable prettier/prettier */
22import type { RestAgentModules , RestMultiTenantAgentModules } from '../../cliAgent'
33import type { Version } from '../examples'
4- import type { RecipientKeyOption , SchemaMetadata } from '../types'
4+ import type { CustomW3cJsonLdSignCredentialOptions , RecipientKeyOption , SafeW3cJsonLdVerifyCredentialOptions , SchemaMetadata } from '../types'
55import type { PolygonDidCreateOptions } from '@ayanworks/credo-polygon-w3c-module/build/dids'
66import type {
77 AcceptProofRequestOptions ,
@@ -15,7 +15,8 @@ import type {
1515 ProofExchangeRecordProps ,
1616 ProofsProtocolVersionType ,
1717 Routing ,
18- } from '@credo-ts/core'
18+ W3cJsonLdSignCredentialOptions ,
19+ W3cVerifiableCredential } from '@credo-ts/core'
1920import type { IndyVdrDidCreateOptions , IndyVdrDidCreateResult } from '@credo-ts/indy-vdr'
2021import type { QuestionAnswerRecord , ValidResponse } from '@credo-ts/question-answer'
2122import type { TenantRecord } from '@credo-ts/tenants'
@@ -27,6 +28,7 @@ import {
2728 parseIndyCredentialDefinitionId ,
2829 parseIndySchemaId ,
2930} from '@credo-ts/anoncreds'
31+ import { assertAskarWallet } from '@credo-ts/askar/build/utils/assertAskarWallet'
3032import {
3133 AcceptCredentialOfferOptions ,
3234 Agent ,
@@ -45,7 +47,9 @@ import {
4547 injectable ,
4648 createPeerDidDocumentFromServices ,
4749 PeerDidNumAlgo ,
48- } from '@credo-ts/core'
50+ W3cJsonLdVerifiableCredential ,
51+ W3cCredential ,
52+ ClaimFormat } from '@credo-ts/core'
4953import { QuestionAnswerRole , QuestionAnswerState } from '@credo-ts/question-answer'
5054import axios from 'axios'
5155import * as fs from 'fs'
@@ -89,7 +93,7 @@ import {
8993 CreateProofRequestOobOptions ,
9094 CreateOfferOobOptions ,
9195 CreateSchemaInput ,
92- } from '../types'
96+ VerifyDataOptions , SignDataOptions } from '../types'
9397
9498import { Body , Controller , Delete , Get , Post , Query , Route , Tags , Path , Example , Security , Response } from 'tsoa'
9599
@@ -1913,4 +1917,124 @@ export class MultiTenancyController extends Controller {
19131917 throw ErrorHandlingService . handle ( error )
19141918 }
19151919 }
1920+
1921+ /**
1922+ * Verify data using a key
1923+ *
1924+ * @param tenantId Tenant identifier
1925+ * @param request Verify options
1926+ * data - Data has to be in base64 format
1927+ * publicKeyBase58 - Public key in base58 format
1928+ * signature - Signature in base64 format
1929+ * @returns isValidSignature - true if signature is valid, false otherwise
1930+ */
1931+ @Security ( 'apiKey' )
1932+ @Post ( '/verify/:tenantId' )
1933+ public async verify ( @Path ( 'tenantId' ) tenantId : string , @Body ( ) request : VerifyDataOptions ) {
1934+ try {
1935+ const isValidSignature = await this . agent . modules . tenants . withTenantAgent ( { tenantId } , async ( tenantAgent ) => {
1936+ assertAskarWallet ( tenantAgent . context . wallet )
1937+ const isValidSignature = await tenantAgent . context . wallet . verify ( {
1938+ data : TypedArrayEncoder . fromBase64 ( request . data ) ,
1939+ key : Key . fromPublicKeyBase58 ( request . publicKeyBase58 , request . keyType ) ,
1940+ signature : TypedArrayEncoder . fromBase64 ( request . signature ) ,
1941+ } )
1942+ return isValidSignature
1943+ } )
1944+ return isValidSignature
1945+ } catch ( error ) {
1946+ throw ErrorHandlingService . handle ( error )
1947+ }
1948+ }
1949+
1950+ @Security ( 'apiKey' )
1951+ @Post ( '/credential/sign/:tenantId' )
1952+ public async signCredential (
1953+ @Path ( 'tenantId' ) tenantId : string ,
1954+ @Query ( 'storeCredential' ) storeCredential : boolean ,
1955+ @Query ( 'dataTypeToSign' ) dataTypeToSign : 'rawData' | 'jsonLd' ,
1956+ @Body ( ) data : CustomW3cJsonLdSignCredentialOptions | SignDataOptions | any
1957+ ) {
1958+ try {
1959+ return await this . agent . modules . tenants . withTenantAgent ( { tenantId } , async ( tenantAgent ) => {
1960+ // JSON-LD VC Signing
1961+ if ( dataTypeToSign === 'jsonLd' ) {
1962+ const credentialData = data as unknown as W3cJsonLdSignCredentialOptions
1963+ credentialData . format = ClaimFormat . LdpVc
1964+
1965+ const signedCredential = await tenantAgent . w3cCredentials . signCredential ( credentialData ) as W3cJsonLdVerifiableCredential
1966+
1967+ if ( storeCredential ) {
1968+ return await tenantAgent . w3cCredentials . storeCredential ( { credential : signedCredential } )
1969+ }
1970+
1971+ return signedCredential . toJson ( )
1972+ }
1973+
1974+ // Raw Data Signing
1975+ const rawData = data as SignDataOptions
1976+
1977+ if ( ! rawData . data ) throw new BadRequestError ( 'Missing "data" for raw data signing.' )
1978+
1979+ const hasDidOrMethod = rawData . did || rawData . method
1980+ const hasPublicKey = rawData . publicKeyBase58 && rawData . keyType
1981+
1982+ if ( ! hasDidOrMethod && ! hasPublicKey ) {
1983+ throw new BadRequestError ( 'Either (did or method) OR (publicKeyBase58 and keyType) must be provided.' )
1984+ }
1985+
1986+ let keyToUse : Key
1987+
1988+ if ( hasDidOrMethod ) {
1989+ const dids = await tenantAgent . dids . getCreatedDids ( {
1990+ method : rawData . method || undefined ,
1991+ did : rawData . did || undefined ,
1992+ } )
1993+
1994+ const verificationMethod = dids [ 0 ] ?. didDocument ?. verificationMethod ?. [ 0 ] ?. publicKeyBase58
1995+ if ( ! verificationMethod ) {
1996+ throw new BadRequestError ( 'No publicKeyBase58 found for the given DID or method.' )
1997+ }
1998+
1999+ keyToUse = Key . fromPublicKeyBase58 ( verificationMethod , rawData . keyType )
2000+ } else {
2001+ keyToUse = Key . fromPublicKeyBase58 ( rawData . publicKeyBase58 , rawData . keyType )
2002+ }
2003+
2004+ if ( ! keyToUse ) {
2005+ throw new Error ( 'Unable to construct signing key.' )
2006+ }
2007+
2008+ const signature = await tenantAgent . context . wallet . sign ( {
2009+ data : TypedArrayEncoder . fromBase64 ( rawData . data ) ,
2010+ key : keyToUse ,
2011+ } )
2012+
2013+ return TypedArrayEncoder . toBase64 ( signature )
2014+ } )
2015+ } catch ( error ) {
2016+ throw ErrorHandlingService . handle ( error )
2017+ }
2018+ }
2019+
2020+ @Security ( 'apiKey' )
2021+ @Post ( '/credential/verify/:tenantId' )
2022+ public async verifyCredential (
2023+ @Path ( 'tenantId' ) tenantId : string ,
2024+ @Body ( ) credentialToVerify : SafeW3cJsonLdVerifyCredentialOptions | any
2025+ ) {
2026+ let formattedCredential
2027+ try {
2028+ await this . agent . modules . tenants . withTenantAgent ( { tenantId } , async ( tenantAgent ) => {
2029+ const { credential, ...credentialOptions } = credentialToVerify
2030+ const transformedCredential = JsonTransformer . fromJSON ( credentialToVerify ?. credential , W3cJsonLdVerifiableCredential )
2031+ const signedCred = await tenantAgent . w3cCredentials . verifyCredential ( { credential : transformedCredential , ...credentialOptions } )
2032+ formattedCredential = signedCred
2033+ } )
2034+ return formattedCredential
2035+ } catch ( error ) {
2036+ throw ErrorHandlingService . handle ( error )
2037+ }
2038+ }
19162039}
2040+
0 commit comments