From cd77eb05c526628a582306ecc9affab05461373d Mon Sep 17 00:00:00 2001 From: whitneypurdum Date: Fri, 8 Jul 2022 09:10:05 +0100 Subject: [PATCH] feat(verifyVc): update ew-credentials version and use to resolve credentials --- .../classes/modules_claims.ClaimsService.md | 16 ++--- ...les_claims.CredentialVerificationResult.md | 26 ++++++++ docs/api/modules/modules_claims.md | 1 + package-lock.json | 55 +++++++++-------- package.json | 6 +- src/errors/error-messages.ts | 3 +- src/modules/claims/claims.service.ts | 61 +++++++++++-------- src/modules/claims/claims.types.ts | 8 +++ 8 files changed, 112 insertions(+), 64 deletions(-) create mode 100644 docs/api/interfaces/modules_claims.CredentialVerificationResult.md diff --git a/docs/api/classes/modules_claims.ClaimsService.md b/docs/api/classes/modules_claims.ClaimsService.md index 38ec58ab..a73a3435 100644 --- a/docs/api/classes/modules_claims.ClaimsService.md +++ b/docs/api/classes/modules_claims.ClaimsService.md @@ -696,7 +696,7 @@ ___ ### resolveCredentialAndVerify -▸ **resolveCredentialAndVerify**(`subjectDID`, `roleNamespace`): `Promise`<`void`\> +▸ **resolveCredentialAndVerify**(`subjectDID`, `roleNamespace`): `Promise`<[`CredentialVerificationResult`](../interfaces/modules_claims.CredentialVerificationResult.md)\> Resolve a credential from storage and verify its proof/signature and its issuer's authority @@ -709,7 +709,7 @@ Resolve a credential from storage and verify its proof/signature and its issuer' #### Returns -`Promise`<`void`\> +`Promise`<[`CredentialVerificationResult`](../interfaces/modules_claims.CredentialVerificationResult.md)\> void. Returns "Proof Not Verified" error if VC not verified. Returns error if issuer not verified @@ -794,7 +794,7 @@ ___ ### verifyOffChainClaim -▸ **verifyOffChainClaim**(`subjectDID`, `roleNamespace`): `Promise`<`void`\> +▸ **verifyOffChainClaim**(`subjectDID`, `roleNamespace`): `Promise`<[`CredentialVerificationResult`](../interfaces/modules_claims.CredentialVerificationResult.md)\> Verifies: - That off-chain claim was issued by authorized issuer @@ -809,15 +809,15 @@ Verifies: #### Returns -`Promise`<`void`\> +`Promise`<[`CredentialVerificationResult`](../interfaces/modules_claims.CredentialVerificationResult.md)\> -void. Returns "Proof Not Verified" error if VC not verified. Returns error if issuer not verified +Boolean indicating if verified and array of error messages ___ ### verifyVc -▸ **verifyVc**(`vc`): `Promise`<`void`\> +▸ **verifyVc**(`vc`): `Promise`<[`CredentialVerificationResult`](../interfaces/modules_claims.CredentialVerificationResult.md)\> Verifies: - That credential proof is valid @@ -831,9 +831,9 @@ Verifies: #### Returns -`Promise`<`void`\> +`Promise`<[`CredentialVerificationResult`](../interfaces/modules_claims.CredentialVerificationResult.md)\> -void. Returns "Proof Not Verified" error if VC not verified. Returns error if issuer not verified +Boolean indicating if verified and array of error messages ___ diff --git a/docs/api/interfaces/modules_claims.CredentialVerificationResult.md b/docs/api/interfaces/modules_claims.CredentialVerificationResult.md new file mode 100644 index 00000000..bfdab223 --- /dev/null +++ b/docs/api/interfaces/modules_claims.CredentialVerificationResult.md @@ -0,0 +1,26 @@ +# Interface: CredentialVerificationResult + +[modules/claims](../modules/modules_claims.md).CredentialVerificationResult + +## Table of contents + +### Properties + +- [errors](modules_claims.CredentialVerificationResult.md#errors) +- [isVerified](modules_claims.CredentialVerificationResult.md#isverified) + +## Properties + +### errors + +• **errors**: `string`[] + +Verification errors + +___ + +### isVerified + +• **isVerified**: `boolean` + +Verifies if a claim has been successfully verified diff --git a/docs/api/modules/modules_claims.md b/docs/api/modules/modules_claims.md index 33444d2d..a99f7ccd 100644 --- a/docs/api/modules/modules_claims.md +++ b/docs/api/modules/modules_claims.md @@ -19,6 +19,7 @@ - [ClaimRevocationDetailsResult](../interfaces/modules_claims.ClaimRevocationDetailsResult.md) - [CreateClaimRequestOptions](../interfaces/modules_claims.CreateClaimRequestOptions.md) - [CreateSelfSignedClaimOptions](../interfaces/modules_claims.CreateSelfSignedClaimOptions.md) +- [CredentialVerificationResult](../interfaces/modules_claims.CredentialVerificationResult.md) - [DeleteClaimOptions](../interfaces/modules_claims.DeleteClaimOptions.md) - [GetClaimsByIssuerOptions](../interfaces/modules_claims.GetClaimsByIssuerOptions.md) - [GetClaimsByRequesterOptions](../interfaces/modules_claims.GetClaimsByRequesterOptions.md) diff --git a/package-lock.json b/package-lock.json index a4c28da2..a290a9c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,11 +8,11 @@ "version": "6.0.0-alpha.27", "license": "GPL-3.0-or-later", "dependencies": { - "@energyweb/credential-governance": "^1.0.1-alpha.174.0", + "@energyweb/credential-governance": "^1.0.1-alpha.181.0", "@energyweb/ekc": "^0.6.6", - "@energyweb/onchain-claims": "^1.0.1-alpha.174.0", + "@energyweb/onchain-claims": "^1.0.1-alpha.181.0", "@energyweb/staking-pool": "^1.0.0-rc.14", - "@energyweb/vc-verification": "^1.0.1-alpha.174.0", + "@energyweb/vc-verification": "^1.0.1-alpha.181.0", "@ensdomains/ens": "^0.6.2", "@ew-did-registry/claims": "^0.6.3-alpha.682.0", "@ew-did-registry/credentials-interface": "^0.6.3-alpha.682.0", @@ -1873,9 +1873,9 @@ } }, "node_modules/@energyweb/credential-governance": { - "version": "1.0.1-alpha.179.0", - "resolved": "https://registry.npmjs.org/@energyweb/credential-governance/-/credential-governance-1.0.1-alpha.179.0.tgz", - "integrity": "sha512-ts3yF/DaOeMGxmaYMxIS+bpYcBVKneDmg+lPz8Ju6e9bXwZbd0tWsKV8KNCoq6K9dzSUY68Yu20LaXOaBa15pw==", + "version": "1.0.1-alpha.181.0", + "resolved": "https://registry.npmjs.org/@energyweb/credential-governance/-/credential-governance-1.0.1-alpha.181.0.tgz", + "integrity": "sha512-0WGHHRcJ4DK9eoBQ6Cbe3/4f+swttgxDnmh9Is//MKXV3vShiOGwSRpBzCIg+lFPbLYw3VeSnLFGgDwW5zFD9w==", "dependencies": { "@ew-did-registry/did": "0.6.3-alpha.682.0", "ethers": "^5.6.1" @@ -2640,11 +2640,11 @@ "integrity": "sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==" }, "node_modules/@energyweb/onchain-claims": { - "version": "1.0.1-alpha.179.0", - "resolved": "https://registry.npmjs.org/@energyweb/onchain-claims/-/onchain-claims-1.0.1-alpha.179.0.tgz", - "integrity": "sha512-aqwfCI3BkEo8Qi5jG5jvX1Gku7DMkd17F5Wk3Nny9uUXoMOmLftQIC3IKabIGbEo6BKxAGDyne7cv901Xe6Imw==", + "version": "1.0.1-alpha.181.0", + "resolved": "https://registry.npmjs.org/@energyweb/onchain-claims/-/onchain-claims-1.0.1-alpha.181.0.tgz", + "integrity": "sha512-GOKYLTbSCDYTr1G2PehJ/iMyVxLfJxe6OP6heqVjp7Nk1CMQMV46AX5R0hcXwJzZmF22f0eEkuKB/q4Ndyu48w==", "dependencies": { - "@energyweb/credential-governance": "1.0.1-alpha.179.0", + "@energyweb/credential-governance": "1.0.1-alpha.181.0", "@ew-did-registry/did": "0.6.3-alpha.682.0", "@ew-did-registry/did-ethr-resolver": "0.6.3-alpha.682.0", "@poanet/solidity-flattener": "^3.0.7", @@ -2682,12 +2682,13 @@ "integrity": "sha512-+cNYvQwTKFMbKVqvVHGzcZbW+z1/pKTyQIYDDC3PaX5L0NAOshI/ZXAsrZRqp/6xEdWsm9f6u549ZLvCEUgNLw==" }, "node_modules/@energyweb/vc-verification": { - "version": "1.0.1-alpha.179.0", - "resolved": "https://registry.npmjs.org/@energyweb/vc-verification/-/vc-verification-1.0.1-alpha.179.0.tgz", - "integrity": "sha512-/calcm6+RbHkLG+m+rZzwRjwvvOkuAjoPZ5oqnBm92JiyS/13gRGuEaM1L6rpOQ3/LvK62vMyRZytV2AX2uVNg==", + "version": "1.0.1-alpha.181.0", + "resolved": "https://registry.npmjs.org/@energyweb/vc-verification/-/vc-verification-1.0.1-alpha.181.0.tgz", + "integrity": "sha512-pUN7HxJ3ixc5jWsKL3sZMrEq5di0F7Cl9kqpXNP8uituwL+p/Mgs/z9aceWOjbe/nuwEnXM5H2BTOI5HMfA9gg==", + "license": "GPL-3.0-or-later", "dependencies": { - "@energyweb/credential-governance": "1.0.1-alpha.179.0", - "@energyweb/onchain-claims": "1.0.1-alpha.179.0", + "@energyweb/credential-governance": "1.0.1-alpha.181.0", + "@energyweb/onchain-claims": "1.0.1-alpha.181.0", "@ew-did-registry/claims": "0.6.3-alpha.682.0", "@ew-did-registry/did-ethr-resolver": "0.6.3-alpha.682.0", "@ew-did-registry/did-ipfs-store": "0.6.3-alpha.682.0", @@ -33098,9 +33099,9 @@ "optional": true }, "@energyweb/credential-governance": { - "version": "1.0.1-alpha.179.0", - "resolved": "https://registry.npmjs.org/@energyweb/credential-governance/-/credential-governance-1.0.1-alpha.179.0.tgz", - "integrity": "sha512-ts3yF/DaOeMGxmaYMxIS+bpYcBVKneDmg+lPz8Ju6e9bXwZbd0tWsKV8KNCoq6K9dzSUY68Yu20LaXOaBa15pw==", + "version": "1.0.1-alpha.181.0", + "resolved": "https://registry.npmjs.org/@energyweb/credential-governance/-/credential-governance-1.0.1-alpha.181.0.tgz", + "integrity": "sha512-0WGHHRcJ4DK9eoBQ6Cbe3/4f+swttgxDnmh9Is//MKXV3vShiOGwSRpBzCIg+lFPbLYw3VeSnLFGgDwW5zFD9w==", "requires": { "@ew-did-registry/did": "0.6.3-alpha.682.0", "ethers": "^5.6.1" @@ -33551,11 +33552,11 @@ } }, "@energyweb/onchain-claims": { - "version": "1.0.1-alpha.179.0", - "resolved": "https://registry.npmjs.org/@energyweb/onchain-claims/-/onchain-claims-1.0.1-alpha.179.0.tgz", - "integrity": "sha512-aqwfCI3BkEo8Qi5jG5jvX1Gku7DMkd17F5Wk3Nny9uUXoMOmLftQIC3IKabIGbEo6BKxAGDyne7cv901Xe6Imw==", + "version": "1.0.1-alpha.181.0", + "resolved": "https://registry.npmjs.org/@energyweb/onchain-claims/-/onchain-claims-1.0.1-alpha.181.0.tgz", + "integrity": "sha512-GOKYLTbSCDYTr1G2PehJ/iMyVxLfJxe6OP6heqVjp7Nk1CMQMV46AX5R0hcXwJzZmF22f0eEkuKB/q4Ndyu48w==", "requires": { - "@energyweb/credential-governance": "1.0.1-alpha.179.0", + "@energyweb/credential-governance": "1.0.1-alpha.181.0", "@ew-did-registry/did": "0.6.3-alpha.682.0", "@ew-did-registry/did-ethr-resolver": "0.6.3-alpha.682.0", "@poanet/solidity-flattener": "^3.0.7", @@ -33582,12 +33583,12 @@ "integrity": "sha512-+cNYvQwTKFMbKVqvVHGzcZbW+z1/pKTyQIYDDC3PaX5L0NAOshI/ZXAsrZRqp/6xEdWsm9f6u549ZLvCEUgNLw==" }, "@energyweb/vc-verification": { - "version": "1.0.1-alpha.179.0", - "resolved": "https://registry.npmjs.org/@energyweb/vc-verification/-/vc-verification-1.0.1-alpha.179.0.tgz", - "integrity": "sha512-/calcm6+RbHkLG+m+rZzwRjwvvOkuAjoPZ5oqnBm92JiyS/13gRGuEaM1L6rpOQ3/LvK62vMyRZytV2AX2uVNg==", + "version": "1.0.1-alpha.181.0", + "resolved": "https://registry.npmjs.org/@energyweb/vc-verification/-/vc-verification-1.0.1-alpha.181.0.tgz", + "integrity": "sha512-pUN7HxJ3ixc5jWsKL3sZMrEq5di0F7Cl9kqpXNP8uituwL+p/Mgs/z9aceWOjbe/nuwEnXM5H2BTOI5HMfA9gg==", "requires": { - "@energyweb/credential-governance": "1.0.1-alpha.179.0", - "@energyweb/onchain-claims": "1.0.1-alpha.179.0", + "@energyweb/credential-governance": "1.0.1-alpha.181.0", + "@energyweb/onchain-claims": "1.0.1-alpha.181.0", "@ew-did-registry/claims": "0.6.3-alpha.682.0", "@ew-did-registry/did-ethr-resolver": "0.6.3-alpha.682.0", "@ew-did-registry/did-ipfs-store": "0.6.3-alpha.682.0", diff --git a/package.json b/package.json index ccb8d87c..c9667d52 100644 --- a/package.json +++ b/package.json @@ -63,11 +63,11 @@ "npm": ">= 6.0.0" }, "dependencies": { - "@energyweb/credential-governance": "^1.0.1-alpha.174.0", + "@energyweb/credential-governance": "^1.0.1-alpha.181.0", "@energyweb/ekc": "^0.6.6", - "@energyweb/onchain-claims": "^1.0.1-alpha.174.0", + "@energyweb/onchain-claims": "^1.0.1-alpha.181.0", "@energyweb/staking-pool": "^1.0.0-rc.14", - "@energyweb/vc-verification": "^1.0.1-alpha.174.0", + "@energyweb/vc-verification": "^1.0.1-alpha.181.0", "@ensdomains/ens": "^0.6.2", "@ew-did-registry/claims": "^0.6.3-alpha.682.0", "@ew-did-registry/credentials-interface": "^0.6.3-alpha.682.0", diff --git a/src/errors/error-messages.ts b/src/errors/error-messages.ts index f360f141..3e6fa0d6 100644 --- a/src/errors/error-messages.ts +++ b/src/errors/error-messages.ts @@ -33,5 +33,6 @@ export enum ERROR_MESSAGES { REVOKE_CLAIM_NOT_FOUND = 'Could not find claim to revoke', DID_DOCUMENT_NOT_UPDATED = 'DID Document was not updated', PROOF_NOT_VERIFIED = 'Proof not verified', - OFFCHAIN_ISSUER_NOT_AUTHORIZED = 'Issuer of OffChain Claim is not authorized' + OFFCHAIN_ISSUER_NOT_AUTHORIZED = 'Issuer of OffChain Claim is not authorized', + NO_CLAIM_RESOLVED = 'No claim found for given DID and role' } diff --git a/src/modules/claims/claims.service.ts b/src/modules/claims/claims.service.ts index bafdeafc..c0a2e0c6 100644 --- a/src/modules/claims/claims.service.ts +++ b/src/modules/claims/claims.service.ts @@ -61,6 +61,7 @@ import { GetRevocationClaimDetailsResult, ClaimRevocationDetailsResult, GetClaimsByRevokerOptions, + CredentialVerificationResult, } from './claims.types'; import { CredentialResolver, @@ -1413,17 +1414,29 @@ export class ClaimsService { * - That credential was issued by authorized issuer * * @param {VerifiableCredential - ): Promise { + ): Promise { + const errors: string[] = []; const issuerDID = this._signerService.did; - if (!(await this._verifiableCredentialService.verify(vc))) { - throw new Error(ERROR_MESSAGES.PROOF_NOT_VERIFIED); + const proofVerified = await this._verifiableCredentialService.verify(vc) + if (!proofVerified) { + errors.push(ERROR_MESSAGES.PROOF_NOT_VERIFIED); } const role = vc.credentialSubject.role.namespace; - await this._vcIssuerVerifier.verifyIssuer(issuerDID, role); + let issuerVerified = true; + try { + await this._vcIssuerVerifier.verifyIssuer(issuerDID, role); + } catch(e) { + issuerVerified = false; + errors.push((e as Error).message) + } + return { + errors, + isVerified: proofVerified && issuerVerified + } } /** @@ -1433,27 +1446,27 @@ export class ClaimsService { * * @param subjectDID The DID to try to resolve a credential for * @param roleNamesapce The role to try to get a credential for. Should be a full role namespace (for example, "myrole.roles.myorg.auth.ewc") - * @return void. Returns "Proof Not Verified" error if VC not verified. Returns error if issuer not verified + * @return Boolean indicating if verified and array of error messages */ - async verifyOffChainClaim(subjectDID: string, roleNamespace: string): Promise { + async verifyOffChainClaim(subjectDID: string, roleNamespace: string): Promise { const errors: string[] = []; const issuerDID = this._signerService.did; const claimIssuerVerifier = new ClaimIssuerVerification(this._signerService.provider, this._didRegistry.registrySettings, this._credentialResolver, this._issuerResolver); const issuerVerified = await claimIssuerVerifier.verifyIssuer(issuerDID, roleNamespace); - //let claimVerified if (!issuerVerified) { errors.push(ERROR_MESSAGES.OFFCHAIN_ISSUER_NOT_AUTHORIZED) } + let proofVerified = true; try { await claimIssuerVerifier.verifyIssuance(subjectDID, roleNamespace); } catch (e) { - //claimVerified = false; - errors.push(JSON.stringify(e)); + proofVerified = false; + errors.push((e as Error).message); } - // return { - // errors: offChainVerificationErrofs, - // verified: claimVerified && issuerVerified - // } + return { + errors: errors, + isVerified: proofVerified && issuerVerified + } } /** @@ -1463,18 +1476,16 @@ export class ClaimsService { * @param roleNamesapce The role to try to get a credential for. Should be a full role namespace (for example, "myrole.roles.myorg.auth.ewc") * @return void. Returns "Proof Not Verified" error if VC not verified. Returns error if issuer not verified */ - - async resolveCredentialAndVerify(subjectDID: string, roleNamespace: string): Promise { - /* - ...some code to resolve the credential - if (foundOffChainClaim) { - return verifyOffChainClaim(offChainClaim); - } - if (foundVc) { - return verifyVc(vc); + async resolveCredentialAndVerify(subjectDID: string, roleNamespace: string): Promise { + const resolvedCredential = await this._credentialResolver.getCredential(subjectDID, roleNamespace); + if (!resolvedCredential) { + return { + isVerified: false, + errors: [ERROR_MESSAGES.NO_CLAIM_RESOLVED] + } } - */ - + const credentialIsOffChain = resolvedCredential?.issuedToken; + return credentialIsOffChain ? this.verifyOffChainClaim(subjectDID, roleNamespace) : this.verifyVc(resolvedCredential as VerifiableCredential); } /** diff --git a/src/modules/claims/claims.types.ts b/src/modules/claims/claims.types.ts index bc35c640..dde5079c 100644 --- a/src/modules/claims/claims.types.ts +++ b/src/modules/claims/claims.types.ts @@ -429,3 +429,11 @@ export interface ClaimRevocationDetailsResult { revoker: string; timestamp: number; } + +export interface CredentialVerificationResult { + /** Verifies if a claim has been successfully verified */ + isVerified: boolean; + + /** Verification errors */ + errors: string[]; +} \ No newline at end of file