Skip to content

Commit

Permalink
Add more basic VCDM validation checks for input to /issue.
Browse files Browse the repository at this point in the history
  • Loading branch information
dlongley committed Jul 18, 2024
1 parent 7336b04 commit 6bd1c1f
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 2 deletions.
103 changes: 101 additions & 2 deletions schemas/bedrock-vc-issuer.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,72 @@ export const statusListOptions = {
items: statusListConfig
};

const vcdmType = {
title: 'VCDM Type',
oneOf: [{
type: 'string'
}, {
type: 'array',
items: {
minItems: 1,
items: {
type: ['string']
}
}
}]
};

const vcdmObject = {
title: 'VCDM Object',
type: 'object',
additionalProperties: true,
properties: {
id: {
type: 'string'
},
type: vcdmType
}
};

const vcdmTypedObject = {
...vcdmObject,
required: ['type']
};

const vcdmObjectOrReference = {
title: 'VCDM Object or Reference',
oneOf: [vcdmObject, {
type: 'string'
}]
};

const vcdmObjectSet = {
title: 'VCDM Object Set',
oneOf: [vcdmObject, {
type: 'array',
minItems: 1,
items: vcdmObject
}]
};

const vcdmObjectOrReferenceSet = {
title: 'VCDM Object or Reference Set',
oneOf: [vcdmObjectOrReference, {
type: 'array',
minItems: 1,
items: vcdmObjectOrReference
}]
};

const vcdmTypedObjectSet = {
title: 'VCDM Typed Object Set',
oneOf: [vcdmTypedObject, {
type: 'array',
minItems: 1,
items: vcdmTypedObject
}]
};

export const issueCredentialBody = {
title: 'Issue Credential',
type: 'object',
Expand All @@ -258,9 +324,42 @@ export const issueCredentialBody = {
credential: {
type: 'object',
additionalProperties: true,
required: ['@context'],
required: ['@context', 'type'],
properties: {
'@context': context
'@context': context,
type: vcdmType,
confidenceMethod: vcdmTypedObjectSet,
credentialSchema: vcdmTypedObjectSet,
credentialStatus: vcdmTypedObjectSet,
credentialSubject: vcdmObjectOrReferenceSet,
description: {
type: 'string'
},
evidence: vcdmTypedObjectSet,
// `issuer` skipped, handled internally during issuance
name: {
type: 'string'
},
proof: vcdmTypedObjectSet,
refreshService: vcdmTypedObjectSet,
relatedResource: vcdmObjectSet,
renderMethod: vcdmTypedObjectSet,
termsOfUse: vcdmTypedObjectSet,
validFrom: {
// FIXME: improve date validation
type: 'string'
},
validUntil: {
// FIXME: improve date validation
type: 'string'
},
// VC 1.1 properties
issuanceDate: {
type: 'string'
},
expirationDate: {
type: 'string'
}
}
}
}
Expand Down
27 changes: 27 additions & 0 deletions test/mocha/assertions/issueWithoutStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,32 @@ export function testIssueWithoutStatus({suiteName, algorithm, issueOptions}) {
should.exist(error);
error.data.type.should.equal('ValidationError');
});

it('fails to issue a VC missing a "credentialSchema" type', async () => {
const credential = klona(mockCredentialV2);
// `type` is not present, so a validation error should occur
credential.credentialSchema = {
id: 'https://example.com#schema'
};

let error;
try {
const zcapClient = helpers.createZcapClient({capabilityAgent});
await zcapClient.write({
url: `${noStatusListIssuerId}/credentials/issue`,
capability: noStatusListIssuerRootZcap,
json: {credential}
});
} catch(e) {
error = e;
}
should.exist(error);
error.data.name.should.equal('ValidationError');
should.exist(error.data.details?.errors?.[0]);
const typeError = error.data.details.errors[0];
typeError.name.should.equal('ValidationError');
typeError.details.path.should.equal('.credential.credentialSchema');
typeError.details.params.missingProperty.should.equal('type');
});
});
}

0 comments on commit 6bd1c1f

Please sign in to comment.