From ebd46c0b7fbe5f30f1f945891ab90ba1aba57caf Mon Sep 17 00:00:00 2001 From: JGiter Date: Thu, 21 Jul 2022 11:23:08 +0300 Subject: [PATCH] fix(claims): dont reregister onchain claim --- e2e/claims.service.e2e.ts | 48 +++++++++++++++++++++++++--- package-lock.json | 4 +-- src/modules/claims/claims.service.ts | 47 ++++++++++++++------------- src/modules/claims/claims.types.ts | 10 ++---- 4 files changed, 72 insertions(+), 37 deletions(-) diff --git a/e2e/claims.service.e2e.ts b/e2e/claims.service.e2e.ts index de30b719..9992a4c1 100644 --- a/e2e/claims.service.e2e.ts +++ b/e2e/claims.service.e2e.ts @@ -371,7 +371,7 @@ describe('Сlaim tests', () => { namespace: claimType, version: version.toString(), }, - issuerFields, + issuerFields: issuerFields || [], }); expect(vpObject.verifiableCredential[0].issuer).toEqual( signerService.didHex @@ -415,7 +415,9 @@ describe('Сlaim tests', () => { expect(requester).toEqual(requesterDID); expect(claimIssuer).toEqual([issuerDID]); - if (registrationTypes.includes(RegistrationTypes.OnChain)) { + if ( + registrationTypes.includes(RegistrationTypes.OnChain) + ) { expect(onChainProof).toHaveLength(132); if (expirationTimestamp || roleDefinitionValidityPeriod) { @@ -691,8 +693,6 @@ describe('Сlaim tests', () => { }; test('should be able to issue and publish onchain', async () => { - mockGetClaimsBySubject.mockImplementationOnce(() => [role1Claim]); // to verify requesting - await enrolAndIssue(rootOwner, staticIssuer, { subjectDID: rootOwnerDID, claimType, @@ -747,6 +747,46 @@ describe('Сlaim tests', () => { await claimsService.hasOnChainRole(rootOwnerDID, claimType, version) ).toBe(false); }); + + test('should be able to issue when role registered onchain', async () => { + await enrolAndIssue(rootOwner, staticIssuer, { + subjectDID: rootOwnerDID, + claimType, + registrationTypes: [ + RegistrationTypes.OffChain, + RegistrationTypes.OnChain, + ], + publishOnChain: true, + }); + expect( + await claimsService.hasOnChainRole(rootOwnerDID, claimType, version) + ).toBe(true); + + await enrolAndIssue(rootOwner, staticIssuer, { + subjectDID: rootOwnerDID, + claimType, + registrationTypes: [ + RegistrationTypes.OffChain, + RegistrationTypes.OnChain, + ], + publishOnChain: true, + }); + }); + + test('should be able to issue without publishing onchain', async () => { + await enrolAndIssue(rootOwner, staticIssuer, { + subjectDID: rootOwnerDID, + claimType, + registrationTypes: [ + RegistrationTypes.OffChain, + RegistrationTypes.OnChain, + ], + publishOnChain: false, + }); + expect( + await claimsService.hasOnChainRole(rootOwnerDID, claimType, version) + ).toBe(false); + }); }); test('should issue claim request with additional issuer fields', async () => { diff --git a/package-lock.json b/package-lock.json index e3a41a15..bfa22aab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "iam-client-lib", - "version": "6.0.0-alpha.29", + "version": "6.0.0-alpha.37", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "iam-client-lib", - "version": "6.0.0-alpha.29", + "version": "6.0.0-alpha.37", "license": "GPL-3.0-or-later", "dependencies": { "@energyweb/credential-governance": "^1.0.1-alpha.193.0", diff --git a/src/modules/claims/claims.service.ts b/src/modules/claims/claims.service.ts index d5f6c3bc..55fbb7f6 100644 --- a/src/modules/claims/claims.service.ts +++ b/src/modules/claims/claims.service.ts @@ -7,9 +7,7 @@ import { PreconditionType, RoleCredentialSubject, } from '@energyweb/credential-governance'; -import { - VerifiableCredential, -} from '@ew-did-registry/credentials-interface'; +import { VerifiableCredential } from '@ew-did-registry/credentials-interface'; import { ClaimRevocation } from '@energyweb/onchain-claims'; import { Methods } from '@ew-did-registry/did'; import { Algorithms } from '@ew-did-registry/jwt'; @@ -80,6 +78,7 @@ import { compareDID, isValidDID } from '../../utils/did'; import { readyToBeRegisteredOnchain } from './claims.types'; import { VerifiableCredentialsServiceBase } from '../verifiable-credentials'; import { StatusListEntryVerification } from '@ew-did-registry/revocation'; +import { getLogger } from '../../config'; const { id, @@ -453,13 +452,13 @@ export class ClaimsService { expiry, sub ); - if (!subjectAgreement) { - throw new Error( - ERROR_MESSAGES.ONCHAIN_ROLE_SUBJECT_AGREEMENT_NOT_SPECIFIED - ); - } message.onChainProof = onChainProof; if (publishOnChain) { + if (!subjectAgreement) { + throw new Error( + ERROR_MESSAGES.ONCHAIN_ROLE_SUBJECT_AGREEMENT_NOT_SPECIFIED + ); + } await this.registerOnchain({ token, subjectAgreement, @@ -524,20 +523,6 @@ export class ClaimsService { if (claim.token) { claim = { ...claim, ...this.extractClaimRequest(claim.token) }; } - - if ( - !claim.subjectAgreement && - claim.subject === this._signerService.did && - claim.claimType && - claim.claimTypeVersion - ) { - claim.subjectAgreement = await this.approveRolePublishing({ - subject: this._signerService.did, - role: claim.claimType as string, - version: +claim.claimTypeVersion, - }); - } - if (!readyToBeRegisteredOnchain(claim)) { throw new Error(ERROR_MESSAGES.CLAIM_WAS_NOT_ISSUED); } @@ -546,10 +531,26 @@ export class ClaimsService { claimTypeVersion, claimType, acceptedBy, - subjectAgreement, onChainProof, expirationTimestamp, } = claim; + let { subjectAgreement } = claim; + + if (await this.hasOnChainRole(subject, claimType, +claimTypeVersion)) { + getLogger().warn( + `[ClaimsService]: ${claimType} already registered for ${subject}` + ); + return; + } + + if (!subjectAgreement && subject === this._signerService.did) { + subjectAgreement = await this.approveRolePublishing({ + subject: this._signerService.did, + role: claimType, + version: +claimTypeVersion, + }); + } + const expiry = expirationTimestamp || eternityTimestamp; const data = this._claimManagerInterface.encodeFunctionData('register', [ addressOf(subject), diff --git a/src/modules/claims/claims.types.ts b/src/modules/claims/claims.types.ts index 16d9ae77..0f43a84e 100644 --- a/src/modules/claims/claims.types.ts +++ b/src/modules/claims/claims.types.ts @@ -76,13 +76,8 @@ export const readyToBeRegisteredOnchain = ( ): claim is Required< Pick< Claim, - | 'claimType' - | 'claimTypeVersion' - | 'subject' - | 'onChainProof' - | 'acceptedBy' - | 'subjectAgreement' - > & { expirationTimestamp?: number } + 'claimType' | 'claimTypeVersion' | 'subject' | 'onChainProof' | 'acceptedBy' + > & { expirationTimestamp?: number; subjectAgreement?: string } > => { if (!claim) return false; if (typeof claim !== 'object') return false; @@ -92,7 +87,6 @@ export const readyToBeRegisteredOnchain = ( 'subject', 'onChainProof', 'acceptedBy', - 'subjectAgreement', ]; const claimProps = Object.keys(claim);