Skip to content

Commit

Permalink
Merge pull request #1927 from blockchain-certificates/feat/proof-purpose
Browse files Browse the repository at this point in the history
feat(VerifiableCredential): validate credential subject
  • Loading branch information
lemoustachiste authored Dec 12, 2024
2 parents f523173 + f71b625 commit 7f5b72c
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/domain/verifier/useCases/validateVerifiableCredential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,22 @@ function validateDateRFC3339StringFormat (date: string, propertyName: string): v
}
}

function validateCredentialSubject (credentialSubject: any): void {
if (typeof credentialSubject !== 'object') {
throw new Error('`credentialSubject` must be an object');
}

if (Array.isArray(credentialSubject) && credentialSubject.length === 0) {
throw new Error('`credentialSubject` cannot be an empty array');
}

if (Array.isArray(credentialSubject)) {
credentialSubject.forEach(subject => {
validateCredentialSubject(subject);
});
}
}

function validateCredentialStatus (certificateCredentialStatus: VCCredentialStatus | VCCredentialStatus[]): void {
const statuses = Array.isArray(certificateCredentialStatus) ? certificateCredentialStatus : [certificateCredentialStatus];
statuses.forEach(status => {
Expand Down Expand Up @@ -133,6 +149,8 @@ export default function validateVerifiableCredential (credential: BlockcertsV3 |
throw new Error('`credentialSubject` must be defined');
}

validateCredentialSubject(credential.credentialSubject);

validateType(credential.type);
validateContext(credential['@context'], credential.type);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,57 @@ describe('domain verifier validateVerifiableCredential test suite', function ()
});
});

describe('validateCredentialSubject method', function () {
describe('given the credentialSubject is an invalid type', function () {
const invalidCredentialSubjectTypes = [
'string', 10, true
];
invalidCredentialSubjectTypes.forEach(function (type) {
it(`should throw an error when the credentialSubject is a ${typeof type}`, function () {
const fixture = { ...validFixture, credentialSubject: type };
expect(function () {
validateVerifiableCredential(fixture);
}).toThrow('`credentialSubject` must be an object');
});
});
});

describe('given the credentialSubject is a falsy value', function () {
const falsyValues = [null, undefined];
falsyValues.forEach(function (value) {
it(`should throw an error when ${value}`, function () {
const fixture = { ...validFixture, credentialSubject: value };
expect(function () {
validateVerifiableCredential(fixture);
}).toThrow('`credentialSubject` must be defined');
});
});
});

describe('given the credentialSubject is an empty array', function () {
it('should throw an error', function () {
const fixture = { ...validFixture, credentialSubject: [] };
expect(function () {
validateVerifiableCredential(fixture);
}).toThrow('`credentialSubject` cannot be an empty array');
});
});

describe('given the credentialSubject is an array of invalid types', function () {
const invalidCredentialSubjectTypes = [
'string', 10, true
];
invalidCredentialSubjectTypes.forEach(function (type) {
it(`should throw an error when the credentialSubject item is a ${typeof type}`, function () {
const fixture = { ...validFixture, credentialSubject: [type] };
expect(function () {
validateVerifiableCredential(fixture);
}).toThrow('`credentialSubject` must be an object');
});
});
});
});

describe('validateCredentialStatus method', function () {
describe('when the credentialStatus property is defined', function () {
describe('when the property is an object but the id is not defined', function () {
Expand Down

0 comments on commit 7f5b72c

Please sign in to comment.