11import type { RestAgentModules , RestMultiTenantAgentModules } from '../../cliAgent'
22import type { Version } from '../examples'
3- import type { RecipientKeyOption , SchemaMetadata } from '../types'
3+ import type {
4+ CustomW3cJsonLdSignCredentialOptions ,
5+ RecipientKeyOption ,
6+ SafeW3cJsonLdVerifyCredentialOptions ,
7+ SchemaMetadata ,
8+ SignDataOptions ,
9+ } from '../types'
410import type { EthereumDidCreateOptions } from '@ayanworks/credo-ethr-module/build/dids'
511import type { PolygonDidCreateOptions } from '@ayanworks/credo-polygon-w3c-module/build/dids'
612import type {
@@ -48,6 +54,7 @@ import {
4854 injectable ,
4955 createPeerDidDocumentFromServices ,
5056 PeerDidNumAlgo ,
57+ W3cJsonLdVerifiableCredential ,
5158} from '@credo-ts/core'
5259import { QuestionAnswerRole , QuestionAnswerState } from '@credo-ts/question-answer'
5360import axios from 'axios'
@@ -68,7 +75,6 @@ import {
6875 WriteTransaction ,
6976 CreateProofRequestOobOptions ,
7077 CreateOfferOobOptions ,
71- SignDataOptions ,
7278 VerifyDataOptions ,
7379} from '../types'
7480
@@ -2157,16 +2163,56 @@ export class MultiTenancyController extends Controller {
21572163 @Post ( '/sign/:tenantId' )
21582164 public async sign (
21592165 @Path ( 'tenantId' ) tenantId : string ,
2160- @Body ( ) request : SignDataOptions ,
2166+ @Body ( ) request : CustomW3cJsonLdSignCredentialOptions | SignDataOptions | any ,
2167+ @Res ( ) badRequestError : TsoaResponse < 400 , { reason : string } > ,
21612168 @Res ( ) notFoundError : TsoaResponse < 404 , { reason : string } > ,
21622169 @Res ( ) internalServerError : TsoaResponse < 500 , { message : string } >
21632170 ) {
21642171 try {
21652172 const signature = await this . agent . modules . tenants . withTenantAgent ( { tenantId } , async ( tenantAgent ) => {
21662173 assertAskarWallet ( tenantAgent . context . wallet )
2174+
2175+ // Raw Data Signing
2176+ const rawData = request as SignDataOptions
2177+
2178+ if ( ! rawData . data ) return notFoundError ( 404 , { reason : `Missing "data" for raw data signing` } )
2179+
2180+ const hasDidOrMethod = rawData . did || rawData . method
2181+ const hasPublicKey = rawData . publicKeyBase58 && rawData . keyType
2182+
2183+ if ( ! hasDidOrMethod && ! hasPublicKey ) {
2184+ return badRequestError ( 400 , {
2185+ reason : `Either (did or method) OR (publicKeyBase58 and keyType) must be provided.` ,
2186+ } )
2187+ }
2188+
2189+ let keyToUse : Key
2190+
2191+ if ( hasDidOrMethod ) {
2192+ const dids = await tenantAgent . dids . getCreatedDids ( {
2193+ method : rawData . method || undefined ,
2194+ did : rawData . did || undefined ,
2195+ } )
2196+
2197+ const verificationMethod = dids [ 0 ] ?. didDocument ?. verificationMethod ?. [ 0 ] ?. publicKeyBase58
2198+ if ( ! verificationMethod ) {
2199+ return badRequestError ( 400 , {
2200+ reason : `No publicKeyBase58 found for the given DID or method.` ,
2201+ } )
2202+ }
2203+
2204+ keyToUse = Key . fromPublicKeyBase58 ( verificationMethod , rawData . keyType )
2205+ } else {
2206+ keyToUse = Key . fromPublicKeyBase58 ( rawData . publicKeyBase58 , rawData . keyType )
2207+ }
2208+
2209+ if ( ! keyToUse ) {
2210+ throw new Error ( 'Unable to construct signing key.' )
2211+ }
2212+
21672213 const signature = await tenantAgent . context . wallet . sign ( {
2168- data : TypedArrayEncoder . fromBase64 ( request . data ) ,
2169- key : Key . fromPublicKeyBase58 ( request . publicKeyBase58 , request . keyType ) ,
2214+ data : TypedArrayEncoder . fromBase64 ( rawData . data ) ,
2215+ key : keyToUse ,
21702216 } )
21712217 return TypedArrayEncoder . toBase64 ( signature )
21722218 } )
@@ -2194,15 +2240,48 @@ export class MultiTenancyController extends Controller {
21942240 public async verify (
21952241 @Path ( 'tenantId' ) tenantId : string ,
21962242 @Body ( ) request : VerifyDataOptions ,
2243+ @Res ( ) badRequestError : TsoaResponse < 400 , { reason : string } > ,
21972244 @Res ( ) notFoundError : TsoaResponse < 404 , { reason : string } > ,
21982245 @Res ( ) internalServerError : TsoaResponse < 500 , { message : string } >
21992246 ) {
22002247 try {
22012248 const isValidSignature = await this . agent . modules . tenants . withTenantAgent ( { tenantId } , async ( tenantAgent ) => {
22022249 assertAskarWallet ( tenantAgent . context . wallet )
2250+
2251+ const hasDidOrMethod = request . did || request . method
2252+ const hasPublicKey = request . publicKeyBase58 && request . keyType
2253+
2254+ if ( ! hasDidOrMethod && ! hasPublicKey ) {
2255+ return badRequestError ( 400 , {
2256+ reason : `Either (did or method) OR (publicKeyBase58 and keyType) must be provided.` ,
2257+ } )
2258+ }
2259+
2260+ let keyToUse : Key
2261+
2262+ if ( hasDidOrMethod ) {
2263+ const dids = await tenantAgent . dids . getCreatedDids ( {
2264+ method : request . method || undefined ,
2265+ did : request . did || undefined ,
2266+ } )
2267+ const verificationMethod = dids [ 0 ] ?. didDocument ?. verificationMethod ?. [ 0 ] ?. publicKeyBase58
2268+ if ( ! verificationMethod ) {
2269+ return badRequestError ( 400 , {
2270+ reason : `No publicKeyBase58 found for the given DID or method.` ,
2271+ } )
2272+ }
2273+ keyToUse = Key . fromPublicKeyBase58 ( verificationMethod , request . keyType )
2274+ } else {
2275+ keyToUse = Key . fromPublicKeyBase58 ( request . publicKeyBase58 , request . keyType )
2276+ }
2277+
2278+ if ( ! keyToUse ) {
2279+ throw new Error ( 'Unable to construct key.' )
2280+ }
2281+
22032282 const isValidSignature = await tenantAgent . context . wallet . verify ( {
22042283 data : TypedArrayEncoder . fromBase64 ( request . data ) ,
2205- key : Key . fromPublicKeyBase58 ( request . publicKeyBase58 , request . keyType ) ,
2284+ key : keyToUse ,
22062285 signature : TypedArrayEncoder . fromBase64 ( request . signature ) ,
22072286 } )
22082287 return isValidSignature
@@ -2215,4 +2294,32 @@ export class MultiTenancyController extends Controller {
22152294 return internalServerError ( 500 , { message : `something went wrong: ${ error } ` } )
22162295 }
22172296 }
2297+
2298+ @Security ( 'apiKey' )
2299+ @Post ( '/credential/verify/:tenantId' )
2300+ public async verifyCredential (
2301+ @Path ( 'tenantId' ) tenantId : string ,
2302+ @Body ( ) credentialToVerify : SafeW3cJsonLdVerifyCredentialOptions | any ,
2303+ @Res ( ) internalServerError : TsoaResponse < 500 , { message : string } >
2304+ ) {
2305+ let formattedCredential
2306+ try {
2307+ await this . agent . modules . tenants . withTenantAgent ( { tenantId } , async ( tenantAgent ) => {
2308+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2309+ const { credential, ...credentialOptions } = credentialToVerify
2310+ const transformedCredential = JsonTransformer . fromJSON (
2311+ credentialToVerify ?. credential ,
2312+ W3cJsonLdVerifiableCredential
2313+ )
2314+ const signedCred = await tenantAgent . w3cCredentials . verifyCredential ( {
2315+ credential : transformedCredential ,
2316+ ...credentialOptions ,
2317+ } )
2318+ formattedCredential = signedCred
2319+ } )
2320+ return formattedCredential
2321+ } catch ( error ) {
2322+ return internalServerError ( 500 , { message : `Something went wrong: ${ error } ` } )
2323+ }
2324+ }
22182325}
0 commit comments