Skip to content

Commit

Permalink
feat(claims): made accetpedBy and onChainProof requred for registerOn…
Browse files Browse the repository at this point in the history
…chain

both props must always be provided.
  • Loading branch information
Passerino committed Jan 26, 2022
1 parent 5087651 commit 3db931b
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 76 deletions.
12 changes: 5 additions & 7 deletions docs/api/classes/ClaimsService.md
Expand Up @@ -112,7 +112,7 @@ ___

### createSelfSignedClaim

**createSelfSignedClaim**(`__namedParameters`): `Promise`<`undefined` \| `string`\>
**createSelfSignedClaim**(`__namedParameters`): `Promise`<`string`\>

**`description`** Creates claim with `data` and adds it to `subject` document. Signer must own or control subject

Expand All @@ -126,7 +126,7 @@ ___

#### Returns

`Promise`<`undefined` \| `string`\>
`Promise`<`string`\>

claim url

Expand Down Expand Up @@ -368,9 +368,7 @@ ___

**publishPublicClaim**(`token`): `Promise`<`undefined` \| `string`\>

publishPublicClaim

**`description`** publishes claim off-chain (by storing claim data in ipfs and save url to DID document services
**`description`** publishes claim off-chain (by storing claim data in ipfs and save url to DID document services) or registering on-chain depending on registrationTypes values.

#### Parameters

Expand Down Expand Up @@ -402,10 +400,10 @@ ___
| Name | Type | Description |
| :------ | :------ | :------ |
| `claim` | `Object` | id of signed onchain claim. |
| `claim.acceptedBy?` | `string` | - |
| `claim.acceptedBy` | `string` | - |
| `claim.claimType?` | `string` | - |
| `claim.claimTypeVersion?` | `string` | - |
| `claim.onChainProof?` | `string` | - |
| `claim.onChainProof` | `string` | - |
| `claim.subject?` | `string` | - |
| `claim.subjectAgreement?` | `string` | - |
| `claim.token?` | `string` | - |
Expand Down
14 changes: 7 additions & 7 deletions docs/api/enums/ERROR_MESSAGES.md
Expand Up @@ -6,7 +6,6 @@

- [APP\_WITH\_ROLES](ERROR_MESSAGES.md#app_with_roles)
- [CAN\_NOT\_UPDATE\_NOT\_CONTROLLED\_DOCUMENT](ERROR_MESSAGES.md#can_not_update_not_controlled_document)
- [CLAIM\_NOT\_FOUND](ERROR_MESSAGES.md#claim_not_found)
- [CLAIM\_TYPE\_REQUIRED\_FOR\_ON\_CHAIN\_REGISTRATION](ERROR_MESSAGES.md#claim_type_required_for_on_chain_registration)
- [CLAIM\_WAS\_NOT\_ISSUED](ERROR_MESSAGES.md#claim_was_not_issued)
- [ENS\_OWNER\_NOT\_VALID\_ADDRESS](ERROR_MESSAGES.md#ens_owner_not_valid_address)
Expand All @@ -22,6 +21,7 @@
- [ONCHAIN\_ROLE\_VERSION\_NOT\_SPECIFIED](ERROR_MESSAGES.md#onchain_role_version_not_specified)
- [ORG\_WITH\_APPS](ERROR_MESSAGES.md#org_with_apps)
- [ORG\_WITH\_ROLES](ERROR_MESSAGES.md#org_with_roles)
- [PUBLISH\_NOT\_ISSUED\_CLAIM](ERROR_MESSAGES.md#publish_not_issued_claim)
- [ROLE\_NOT\_EXISTS](ERROR_MESSAGES.md#role_not_exists)
- [ROLE\_PREREQUISITES\_NOT\_MET](ERROR_MESSAGES.md#role_prerequisites_not_met)
- [STAKE\_WAS\_NOT\_PUT](ERROR_MESSAGES.md#stake_was_not_put)
Expand All @@ -44,12 +44,6 @@ ___

___

### CLAIM\_NOT\_FOUND

**CLAIM\_NOT\_FOUND** = `"Claim not found"`

___

### CLAIM\_TYPE\_REQUIRED\_FOR\_ON\_CHAIN\_REGISTRATION

**CLAIM\_TYPE\_REQUIRED\_FOR\_ON\_CHAIN\_REGISTRATION** = `"claimType required for on-chain registration"`
Expand Down Expand Up @@ -140,6 +134,12 @@ ___

___

### PUBLISH\_NOT\_ISSUED\_CLAIM

**PUBLISH\_NOT\_ISSUED\_CLAIM** = `"Claim to publish has not been issued"`

___

### ROLE\_NOT\_EXISTS

**ROLE\_NOT\_EXISTS** = `"Role you want to enroll to does not exists"`
Expand Down
7 changes: 0 additions & 7 deletions docs/api/interfaces/Claim.md
Expand Up @@ -8,7 +8,6 @@
- [claimIssuer](Claim.md#claimissuer)
- [claimType](Claim.md#claimtype)
- [claimTypeVersion](Claim.md#claimtypeversion)
- [g](Claim.md#g)
- [id](Claim.md#id)
- [isAccepted](Claim.md#isaccepted)
- [isRejected](Claim.md#isrejected)
Expand Down Expand Up @@ -47,12 +46,6 @@ ___

___

### g

**g**: `any`

___

### id

**id**: `string`
Expand Down
4 changes: 2 additions & 2 deletions docs/api/modules.md
Expand Up @@ -653,7 +653,7 @@ ___

### readyToBeRegisteredOnchain

`Const` **readyToBeRegisteredOnchain**(`claim`): `Required`<`Pick`<[`Claim`](interfaces/Claim.md), ``"subject"`` \| ``"claimTypeVersion"`` \| ``"claimType"`` \| ``"onChainProof"`` \| ``"acceptedBy"`` \| ``"subjectAgreement"``\>\>
`Const` **readyToBeRegisteredOnchain**(`claim`): claim is Required<Pick<Claim, "claimTypeVersion" \| "claimType" \| "subject" \| "onChainProof" \| "acceptedBy" \| "subjectAgreement"\>\>

#### Parameters

Expand All @@ -663,7 +663,7 @@ ___

#### Returns

`Required`<`Pick`<[`Claim`](interfaces/Claim.md), ``"subject"`` \| ``"claimTypeVersion"`` \| ``"claimType"`` \| ``"onChainProof"`` \| ``"acceptedBy"`` \| ``"subjectAgreement"``\>\>
claim is Required<Pick<Claim, "claimTypeVersion" \| "claimType" \| "subject" \| "onChainProof" \| "acceptedBy" \| "subjectAgreement"\>\>

___

Expand Down
41 changes: 20 additions & 21 deletions e2e/claims.service.e2e.ts
Expand Up @@ -118,7 +118,7 @@ describe('Enrollment claim tests', () => {

beforeEach(async () => {
jest.clearAllMocks();

//mockGetClaimsBySubject.mockReset();
await replenish(await staticIssuer.getAddress());
await replenish(await rootOwner.getAddress());
await replenish(await dynamicIssuer.getAddress());
Expand Down Expand Up @@ -220,7 +220,7 @@ describe('Enrollment claim tests', () => {
return issuedClaim;
}

async function enrolAndIssueWithoutRequest(
async function issueWithoutRequest(
issueSigner: Required<ethers.Signer>,
{
subjectDID,
Expand Down Expand Up @@ -256,7 +256,7 @@ describe('Enrollment claim tests', () => {

expect(did).toBe(issuerDID);

const { issuedToken, requester, claimIssuer, onChainProof, acceptedBy } = issuedClaim;
const { issuedToken, requester, claimIssuer, acceptedBy } = issuedClaim;

if (registrationTypes.includes(RegistrationTypes.OffChain)) {
expect(issuedToken).toBeDefined();
Expand All @@ -275,19 +275,7 @@ describe('Enrollment claim tests', () => {
expect(signer).toBe(issuerDID);
expect(did).toBe(requesterDID);
}
if (registrationTypes.includes(RegistrationTypes.OnChain)) {
expect(onChainProof).toHaveLength(132);

const mockedClaim = {
claimType,
isApproved: true,
onChainProof,
claimTypeVersion: version,
acceptedBy: issuerDID,
subject: requesterDID,
};
mockGetClaimsBySubject.mockReset().mockImplementationOnce(() => [mockedClaim]);
}
expect(requester).toEqual(subjectDID);
expect(claimIssuer).toEqual([issuerDID]);
expect(acceptedBy).toBe(issuerDID);
Expand Down Expand Up @@ -429,14 +417,25 @@ describe('Enrollment claim tests', () => {
});

test('should be able to issue and publish onchain without request', async () => {
mockGetClaimsBySubject.mockImplementationOnce(() => [role1Claim]); // to verify requesting

await enrolAndIssueWithoutRequest(staticIssuer, {
const claim = await issueWithoutRequest(staticIssuer, {
subjectDID: rootOwnerDID,
claimType,
registrationTypes,
});
expect(claim.onChainProof).toHaveLength(132);

await signerService.connect(rootOwner, ProviderType.PrivateKey);
const mockedClaim = {
claimType,
isApproved: true,
onChainProof: claim.onChainProof,
claimTypeVersion: version,
acceptedBy: claim.acceptedBy,
subject: rootOwnerDID,
};
mockGetClaimsBySubject.mockReset().mockImplementationOnce(() => [mockedClaim]);

await claimsService.publishPublicClaim({ claim: { claimType }, registrationTypes });
expect(await claimsService.hasOnChainRole(rootOwnerDID, claimType, version)).toBe(true);
});
Expand Down Expand Up @@ -502,10 +501,10 @@ describe('Enrollment claim tests', () => {

describe('Selfsigned claim tests', () => {
test('Selfsigned claim should be verified', async () => {
const claimUrl = (await claimsService.createSelfSignedClaim({
const claimUrl = await claimsService.createSelfSignedClaim({
data: { claimType: roleName1 },
subject: rootOwnerDID,
})) as string;
});
const claim = await didRegistry.ipfsStore.get(claimUrl);

const document = await didRegistry.getDidDocument();
Expand All @@ -523,10 +522,10 @@ describe('Enrollment claim tests', () => {
{ document: { id: assetDID }, id: assetDID },
]);
const claimType = 'test claim';
const claimUrl = (await claimsService.createSelfSignedClaim({
const claimUrl = await claimsService.createSelfSignedClaim({
data: { claimType },
subject: assetDID,
})) as string;
});
const claim = await didRegistry.ipfsStore.get(claimUrl);

const ownerDoc = await didRegistry.getDidDocument({ did: rootOwnerDID, includeClaims: true });
Expand Down
2 changes: 1 addition & 1 deletion src/errors/ErrorMessages.ts
Expand Up @@ -19,7 +19,7 @@ export enum ERROR_MESSAGES {
ERROR_IN_AZURE_PROVIDER = 'Error in Azure Provider',
JWT_ALGORITHM_NOT_SUPPORTED = 'Jwt algorithm not supported',
CLAIM_WAS_NOT_ISSUED = 'Claim was not issued',
CLAIM_NOT_FOUND = 'Claim not found',
PUBLISH_NOT_ISSUED_CLAIM = 'Claim to publish has not been issued',
CLAIM_TYPE_REQUIRED_FOR_ON_CHAIN_REGISTRATION = 'claimType required for on-chain registration',
TOKEN_REQUIRED_FOR_OFF_CHAIN_REGISTRATION = 'token required for off-chain registration',
ENS_OWNER_NOT_VALID_ADDRESS = 'Provided owner is not a valid address. Owner of ENS domain must be an address',
Expand Down
45 changes: 23 additions & 22 deletions src/modules/claims/claims.service.ts
Expand Up @@ -230,8 +230,6 @@ export class ClaimsService {
requester,
claimIssuer: [this._signerService.did],
acceptedBy: this._signerService.did,
claimType: claimData.claimType,
claimTypeVersion: claimData.claimTypeVersion.toString(),
};
const strippedClaimData = this.stripClaimData(claimData);
if (registrationTypes.includes(RegistrationTypes.OffChain)) {
Expand Down Expand Up @@ -267,15 +265,12 @@ export class ClaimsService {
* @param token optional token containing claimType, version and subject
* @returns claim params obtained from token
*/
private getClaimTypeFromToken(token?: string) {
if (token) {
const { claimData, sub } = this._didRegistry.jwt.decode(token) as {
claimData: { claimType: string; claimTypeVersion: string };
sub: string;
};
return { ...claimData, subject: sub };
}
return {};
private extractClaimRequest(token: string) {
const { claimData, sub } = this._didRegistry.jwt.decode(token) as {
claimData: { claimType: string; claimTypeVersion: string };
sub: string;
};
return { ...claimData, subject: sub };
}

/**
Expand All @@ -289,12 +284,12 @@ export class ClaimsService {
claimTypeVersion?: string;
token?: string;
subjectAgreement?: string;
onChainProof?: string;
acceptedBy?: string;
onChainProof: string;
acceptedBy: string;
subject?: string;
}) {
// backward compatibility with token
claim = { ...claim, ...this.getClaimTypeFromToken(claim.token) };
if (claim.token) claim = { ...claim, ...this.extractClaimRequest(claim.token) };

if (
!claim.subjectAgreement &&
Expand All @@ -309,9 +304,11 @@ export class ClaimsService {
});
}

const expiry = defaultClaimExpiry;
const { subject, claimTypeVersion, claimType, acceptedBy, subjectAgreement, onChainProof } =
readyToBeRegisteredOnchain(claim);
if (!readyToBeRegisteredOnchain(claim)) {
throw new Error(ERROR_MESSAGES.CLAIM_WAS_NOT_ISSUED);
}
const { subject, claimTypeVersion, claimType, acceptedBy, subjectAgreement, onChainProof } = claim;
const expiry = defaultClaimExpiry;

const data = this._claimManagerInterface.encodeFunctionData('register', [
addressOf(subject),
Expand Down Expand Up @@ -435,9 +432,8 @@ export class ClaimsService {
}

/**
* publishPublicClaim
*
* @description publishes claim off-chain (by storing claim data in ipfs and save url to DID document services
* @description publishes claim off-chain (by storing claim data in ipfs and save url to DID document services) or registering on-chain depending on registrationTypes values.
* @returns ulr to ipfs
* @param token - @deprecated - use claim with claimType instead
*
Expand All @@ -461,10 +457,15 @@ export class ClaimsService {
isAccepted: true,
});
if (claims.length < 1) {
throw new Error(ERROR_MESSAGES.CLAIM_NOT_FOUND);
throw new Error(ERROR_MESSAGES.PUBLISH_NOT_ISSUED_CLAIM);
}

const claimData = claims[0];
await this.registerOnchain(claimData);
await this.registerOnchain({
...claimData,
onChainProof: claimData.onChainProof as string,
acceptedBy: claimData.acceptedBy as string,
});
}

// add scenario for offchain without request based on claimType instead of token
Expand Down Expand Up @@ -516,7 +517,7 @@ export class ClaimsService {
*/
async createSelfSignedClaim({ data, subject }: { data: ClaimData; subject?: string }) {
const token = await this._didRegistry.createPublicClaim({ data, subject });
return this.publishPublicClaim({ claim: { token } });
return (await this.publishPublicClaim({ claim: { token } })) as string;
}

/**
Expand Down
13 changes: 4 additions & 9 deletions src/modules/claims/claims.types.ts
Expand Up @@ -11,7 +11,7 @@ export interface IClaimRequest extends IMessage {

export interface IClaimIssuance extends IMessage {
// issuedToken is is only provided in the case of off-chain role
issuedToken?: string;
issuedToken?: string;
// onChainProof is only provided in case of on-chain role
onChainProof?: string;
claimType?: string;
Expand Down Expand Up @@ -51,12 +51,12 @@ export interface Claim {
isAccepted: boolean;
acceptedBy?: string;
isRejected?: boolean;
namespace: string;g,
namespace: string;
}

export const readyToBeRegisteredOnchain = (
claim: any
): Required<
): claim is Required<
Pick<
Claim,
| 'claimType'
Expand All @@ -77,12 +77,7 @@ export const readyToBeRegisteredOnchain = (
];
const claimProps = Object.keys(claim);

const missingProps = requiredProps.filter((p) => !claimProps.includes(p));
if (missingProps.length > 0)
throw new Error(
'CANNOT REGISTER ON CHAIN. THE FOLLOWING PROPS ARE MISSING: ' + JSON.stringify(missingProps)
);
return claim;
return requiredProps.every((p) => claimProps.includes(p));
};

export const typedMsgPrefix = '1901';
Expand Down

0 comments on commit 3db931b

Please sign in to comment.