Skip to content

Commit

Permalink
transform verification response
Browse files Browse the repository at this point in the history
  • Loading branch information
jchartrand committed Jan 28, 2025
1 parent 69e30c5 commit 05d5ac2
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 36 deletions.
28 changes: 18 additions & 10 deletions src/Verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { getCredentialStatusChecker } from './credentialStatus.js';
import { addTrustedIssuersToVerificationResponse } from './issuerRegistries.js';

import { Credential } from './types/credential.js';
import { VerificationResponse, VerificationStep } from './types/result.js';
import { VerificationResponse, VerificationStep, PresentationVerificationResponse, PresentationSignatureResult } from './types/result.js';
import { VerifiablePresentation, PresentationError } from './types/presentation.js';

Check failure on line 12 in src/Verify.ts

View workflow job for this annotation

GitHub Actions / lint (18.x)

'PresentationError' is defined but never used

import { extractCredentialsFrom} from './extractCredentialsFrom.js';
Expand All @@ -32,7 +32,7 @@ export async function verifyPresentation({presentation, challenge = 'blah', unsi
unsignedPresentation? : boolean,
knownDIDRegistries: object,
reloadIssuerRegistry?: boolean}
): Promise<VerificationResponse> {
): Promise<PresentationVerificationResponse> {
try {
const credential = extractCredentialsFrom(presentation)?.find(
vc => vc.credentialStatus);
Expand All @@ -48,19 +48,26 @@ export async function verifyPresentation({presentation, challenge = 'blah', unsi
verifyMatchingIssuers: false
});

const transformedVCResults = await Promise.all(result.credentialResults.map(async (credentialResult:any) => {
const transformedCredentialResults = await Promise.all(result.credentialResults.map(async (credentialResult:any) => {
return transformResponse(credentialResult, credentialResult.credential, knownDIDRegistries, reloadIssuerRegistry)
}));

// take what we need from the presentation part of the result
let signature : PresentationSignatureResult;
if (unsignedPresentation) {
signature = 'unsigned'
} else {
signature = result.presentationResult.verified ? 'valid' : 'invalid'
}
const errors = result.error ? [{message: result.error, name: 'presentation_error'}] : null
const presentationResult = {signature, ...(errors && {errors} ) }

result.credentialResults = transformedVCResults

return result;
} catch (err) {
console.warn(err);

throw new Error(PresentationError.CouldNotBeVerified);
return {presentationResult, credentialResults: transformedCredentialResults, isFatal: false};
} catch (error) {
return {isFatal: true, errors: [{message: 'Could not verify presentation.', name: 'presentation_error', stackTrace: error}],
}
}
}


export async function verifyCredential({ credential, knownDIDRegistries, reloadIssuerRegistry = true }: { credential: Credential, knownDIDRegistries: object, reloadIssuerRegistry: boolean }): Promise<VerificationResponse> {
Expand Down Expand Up @@ -102,6 +109,7 @@ async function transformResponse(verificationResponse:any, credential:Credential
delete verificationResponse.results
delete verificationResponse.statusResult
delete verificationResponse.verified
delete verificationResponse.credentialId
verificationResponse.log = verificationResponse.log.filter((entry:VerificationStep)=>entry.id !== 'issuer_did_resolves')

// add things we always want in the response
Expand Down
22 changes: 20 additions & 2 deletions src/test-fixtures/expectedResults.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { VerificationResponse, VerificationStep } from "src/types/result";
import { VerificationResponse, VerificationStep, PresentationVerificationResponse } from "src/types/result";

const expectedPresentationResult = {
"isFatal": false,
"presentationResult": {
"signature": 'valid',
}
}
const expectedResult = {
"credential": {},
"isFatal": false,
Expand Down Expand Up @@ -56,6 +62,11 @@ const expectedResult = {
return expectedResultCopy;
}

const getCopyOfExpectedVPResult = () : PresentationVerificationResponse => {
return JSON.parse(JSON.stringify(expectedPresentationResult))
}


const getExpectedVerifiedResult = ({credential, withStatus }: {credential:object, withStatus:boolean}) : VerificationResponse => {
return getCopyOfExpectedResult(credential, withStatus);
}
Expand All @@ -72,8 +83,15 @@ const expectedResult = {
return expectedResult;
}

const getExpectedVerifiedPresentationResult = ({credentialResults}: {credentialResults:VerificationResponse[]}) : PresentationVerificationResponse => {
const expectedResult = getCopyOfExpectedVPResult();
expectedResult.credentialResults = credentialResults
return expectedResult;
}

export {
getExpectedVerifiedResult,
getExpectedUnverifiedResult,
getExpectedFatalResult
getExpectedFatalResult,
getExpectedVerifiedPresentationResult
}
18 changes: 17 additions & 1 deletion src/types/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
export interface VerificationError {
"message": string,
"name"?: string,
"stackTrace"?: string
"stackTrace"?: any
}

export interface VerificationStep {
Expand All @@ -20,6 +20,22 @@ export interface VerificationError {
"log"?: VerificationStep[]
}


const signatureOptions = ['valid', 'invalid', 'unsigned'] as const;
export type PresentationSignatureResult = typeof signatureOptions[number]; //'valid', 'invalid', 'unsigned'

Check failure on line 25 in src/types/result.ts

View workflow job for this annotation

GitHub Actions / lint (18.x)

Expected space or tab after '//' in comment

export interface PresentationResult {
"signature":PresentationSignatureResult,
"error"?: any
}

export interface PresentationVerificationResponse {
"isFatal": boolean,
"credentialResults"?: VerificationResponse[],
"presentationResult"?: PresentationResult,
"errors"?: VerificationError[]
}

export interface RegistryListResult {
foundInRegistries: string[]
registriesNotLoaded: RegistriesNotLoaded[]
Expand Down
70 changes: 48 additions & 22 deletions test/Verify.presentation.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import {
} from '../src/test-fixtures/vc.js'
import { knownDIDRegistries } from '../.knownDidRegistries.js';
import {
getExpectedVerifiedResult
getExpectedVerifiedResult,
getExpectedVerifiedPresentationResult
} from '../src/test-fixtures/expectedResults.js';

import { getSignedDIDAuth, verifyDIDAuth } from './didAuth.js';
Expand All @@ -22,7 +23,9 @@ const {expect} = chai;
const DISABLE_CONSOLE_WHEN_NO_ERRORS = false


describe('Verify', () => {
describe('Verify.verifyPresentation', () => {

const holder = 'did:ex:12345';

const originalLogFunction = console.log;
let output:string;
Expand All @@ -46,28 +49,51 @@ describe('Verify', () => {
}
});

describe('.verifyPresentation', () => {

describe('it returns as verified', () => {

it('when presentation is valid', async () => {
const firstVC : any = getVCv2DidWebWithValidStatus()
const secondVC : any = getVCv2ValidStatus()
const noProofVC : any = getVCv1NoProof()
const badIdVC : any = getVCv2NonURIId()
const verifiableCredential = [firstVC, secondVC, firstVC]
// const expectedResult = getExpectedVerifiedResult({credential: verifiableCredential, withStatus: true})
const presentation = await getSignedDIDAuth({verifiableCredential, holder: 'did:ex:12345'}) as VerifiablePresentation
// console.log(JSON.stringify(presentation, null, 2))
const result = await verifyPresentation({presentation, knownDIDRegistries})
//await verifyDIDAuth({presentation, challenge})
console.log("====================== verification result")
console.log(JSON.stringify(result,null,2))
expect(true)
})
/*
- vp signed
- vp unsigned
- passing in good challenge
- passing in bad challenge
- vp with bad vc
- vp with no vcs
*/


describe('it returns as verified', () => {

it.only('when signed presentation has one vc', async () => {
const singleVC : any = getVCv2ValidStatus()
const verifiableCredential= [singleVC]
const presentation = await getSignedDIDAuth({holder, verifiableCredential}) as VerifiablePresentation
const expectedVCResult = getExpectedVerifiedResult({credential:singleVC, withStatus: true})
const expectedPresentationResult = getExpectedVerifiedPresentationResult({credentialResults:[expectedVCResult]})

const result = await verifyPresentation({presentation, knownDIDRegistries})
console.log("====================== verification result")
console.log(JSON.stringify(result,null,2))
expect(result).to.deep.equalInAnyOrder(expectedPresentationResult)
})
})

it('when presentation is valid', async () => {
const firstVC : any = getVCv2DidWebWithValidStatus()
const secondVC : any = getVCv2ValidStatus()
const noProofVC : any = getVCv1NoProof()
const badIdVC : any = getVCv2NonURIId()
const verifiableCredential = [firstVC, secondVC, firstVC]
// const expectedResult = getExpectedVerifiedResult({credential: verifiableCredential, withStatus: true})
const presentation = await getSignedDIDAuth({verifiableCredential, holder: 'did:ex:12345'}) as VerifiablePresentation
// console.log(JSON.stringify(presentation, null, 2))
const result = await verifyPresentation({presentation, knownDIDRegistries})
//await verifyDIDAuth({presentation, challenge})
//console.log("====================== verification result")
//console.log(JSON.stringify(result,null,2))
expect(true)
})


})
})




2 changes: 1 addition & 1 deletion test/didAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const key = await Ed25519VerificationKey2020.generate(

const signingSuite = new Ed25519Signature2020({key});

export const getSignedDIDAuth = async ({holder, verifiableCredential}:{holder:string,verifiableCredential:any}):Promise<any> => {
export const getSignedDIDAuth = async ({holder, verifiableCredential}:{holder:string,verifiableCredential?:any}):Promise<any> => {
const presentation = createPresentation({holder, verifiableCredential});
const challenge = 'canbeanything33'
return await signPresentation({
Expand Down

0 comments on commit 05d5ac2

Please sign in to comment.