import { PresentationValidationOptions } from '../shared/dto/validationOptions.dto.js'; import { CredentialFormat, CredentialFormatTuple, VPTokenData, } from './presentation/vpTokenCredentialsExtractor.js'; import { isKeyDid } from '../shared/utils.js'; import { EbsiPresentationValidator } from './presentation/ebsiPresentationValidator.js'; import { ValidationResult } from '../shared/dto/validationResult.dto.js'; import { EbsiWrapper } from '../shared/middleware/ebsiWrapper.js'; import { VerifiablePresentationValidator } from './presentation/verifiablePresentationValidator.js'; import { DecodedVerifiableCredentialDto } from '../shared/dto/decodedVerifiableCredential.dto.js'; import { DidDocumentResolver } from '../resolvers/didDocumentResolver.js'; import { DidPublicKeyResolver } from '../resolvers/didPublicKeyResolver.js'; import { SignatureValidator } from './credential/signatureValidator.js'; import { DcqlPresentation } from './presentation/dcqlPresentation.js'; import { DCQLQuery } from '../shared/dto/dcqlQuery.dto.js'; export interface PresentationValidator { validate( presentation: DcqlPresentation, audience: string, ): Promise; } export class PresentationValidatorFactory { create( presentation: DcqlPresentation, vpTokenData: VPTokenData, opts: PresentationValidationOptions, ): PresentationValidator { if ( this.isEbsiPresentation( presentation, vpTokenData.vpTokenIssuer, vpTokenData.verifiableCredentials, vpTokenData.verifiableCredentialsDecoded, opts.dcqlQuery, ) ) { const ebsiWrapper = new EbsiWrapper(); return new EbsiPresentationValidator(ebsiWrapper, opts); } return new VerifiablePresentationValidator( opts, vpTokenData, new DidPublicKeyResolver(new DidDocumentResolver()), new SignatureValidator(), ); } private isEbsiPresentation( presentation: DcqlPresentation, vpHolder: string, credentialFormatTuples: CredentialFormatTuple[], decodedCredentials: DecodedVerifiableCredentialDto[], dcqlQuery?: DCQLQuery, ): boolean { if ( dcqlQuery?.credentials.some( ({ id }) => !presentation[id]?.every( (vp) => typeof vp === 'string' && !vp.includes('~'), ), ) ) { return false; } if ( credentialFormatTuples.some( (credential) => credential.format === CredentialFormat.JSON, ) ) { return false; } const notEbsiCredential = decodedCredentials.find( (credential) => !credential.iss.startsWith('did:ebsi'), ); return !(notEbsiCredential || !isKeyDid(vpHolder)); } }