Skip to content

Commit

Permalink
feat(did): ts interface checker to validate did update request
Browse files Browse the repository at this point in the history
commit 16494a9
Author: Passerino <bartosz.d.wrobel@gmail.com>
Date:   Wed Mar 2 10:04:01 2022 +0100

    feat(did): update did document params validation

    checking params on updateSignedDidPublicKey, updateSignedDidDelegate functions
    checking params on updateDocument conditionally depending on didAttribute value
    in case of validation issues - throws Error with the list of invalid or missing properties
  • Loading branch information
Passerino committed Mar 9, 2022
1 parent 6242e8b commit a0bfeeb
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 25 deletions.
7 changes: 7 additions & 0 deletions docs/api/enums/ERROR_MESSAGES.md
Expand Up @@ -5,6 +5,7 @@
### Enumeration members

- [APP\_WITH\_ROLES](ERROR_MESSAGES.md#app_with_roles)
- [CAN\_NOT\_UPDATE\_DOCUMENT\_PROPERTIES\_INVALID\_OR\_MISSING](ERROR_MESSAGES.md#can_not_update_document_properties_invalid_or_missing)
- [CAN\_NOT\_UPDATE\_NOT\_CONTROLLED\_DOCUMENT](ERROR_MESSAGES.md#can_not_update_not_controlled_document)
- [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)
Expand Down Expand Up @@ -38,6 +39,12 @@

___

### CAN\_NOT\_UPDATE\_DOCUMENT\_PROPERTIES\_INVALID\_OR\_MISSING

**CAN\_NOT\_UPDATE\_DOCUMENT\_PROPERTIES\_INVALID\_OR\_MISSING** = `"Cannot update document. Properties invalid or missing: "`

___

### CAN\_NOT\_UPDATE\_NOT\_CONTROLLED\_DOCUMENT

**CAN\_NOT\_UPDATE\_NOT\_CONTROLLED\_DOCUMENT** = `"Can not update not controlled document"`
Expand Down
15 changes: 13 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -88,6 +88,7 @@
"lodash.difference": "^4.5.0",
"nats.ws": "^1.7.1",
"qs": "^6.9.4",
"ts-interface-checker": "^1.0.2",
"tslib": "^2.0.3",
"uuid": "^7.0.3"
},
Expand Down
1 change: 1 addition & 0 deletions src/errors/ErrorMessages.ts
Expand Up @@ -11,6 +11,7 @@ export enum ERROR_MESSAGES {
ROLE_PREREQUISITES_NOT_MET = "Enrolment subject doesn't have required roles",
ROLE_NOT_EXISTS = 'Role you want to enroll to does not exists',
CAN_NOT_UPDATE_NOT_CONTROLLED_DOCUMENT = 'Can not update not controlled document',
CAN_NOT_UPDATE_DOCUMENT_PROPERTIES_INVALID_OR_MISSING = 'Cannot update document. Properties invalid or missing: ',
ONCHAIN_ROLE_VERSION_NOT_SPECIFIED = 'On-chain role version not specified',
WITHDRAWAL_WAS_NOT_REQUESTED = 'Stake withdrawal was not requested',
STAKE_WAS_NOT_PUT = 'Stake was not put',
Expand Down
102 changes: 79 additions & 23 deletions src/modules/didRegistry/didRegistry.service.ts
Expand Up @@ -3,6 +3,7 @@ import { AxiosError } from 'axios';
import { KeyType } from '@ew-did-registry/keys';
import { JWT } from '@ew-did-registry/jwt';
import { ProxyOperator } from '@ew-did-registry/proxyidentity';

import {
addressOf,
EwSigner,
Expand Down Expand Up @@ -37,8 +38,13 @@ import { ClaimData } from '../didRegistry/did.types';
import { chainConfigs } from '../../config/chain.config';
import { AssetsService } from '../assets/assets.service';

const { JsonRpcProvider } = providers;
import {
UpdateServicePoint,
UpdateDelegate,
UpdatePublicKey,
} from './didRegistry.validation';

const { JsonRpcProvider } = providers;
export class DidRegistry {
private _identityOwner: EwSigner;
private _operator: Operator;
Expand Down Expand Up @@ -91,28 +97,6 @@ export class DidRegistry {
this._setClaims();
}

private async getDIDDocFull(did) {
if (did === this._signerService.did) {
return this._document;
} else {
const assetDID = (await this._assetsService.getOwnedAssets()).find(
(a) => a.document.id === did
)?.id;
if (!assetDID) {
throw new Error(ERROR_MESSAGES.CAN_NOT_UPDATE_NOT_CONTROLLED_DOCUMENT);
}

const { didRegistryAddress: didContractAddress } =
chainConfigs()[this._signerService.chainId];
const operator = new ProxyOperator(
this._identityOwner,
{ address: didContractAddress },
addressOf(assetDID)
);
return new DIDDocumentFull(did, operator);
}
}

async getDidDocument({
did = this._did,
includeClaims = true,
Expand Down Expand Up @@ -254,6 +238,12 @@ export class DidRegistry {
did?: string;
validity?: number;
}): Promise<boolean> {
this.validDateUpdateDocumentRequest({
didAttribute,
data,
did,
});

const didDocument = await this.getDIDDocFull(did);
const updateData: IUpdateData = {
algo: KeyType.Secp256k1,
Expand Down Expand Up @@ -285,6 +275,11 @@ export class DidRegistry {
tag: string;
validity?: number;
}): Promise<boolean> {
if (!publicKey)
throw new Error(
ERROR_MESSAGES.CAN_NOT_UPDATE_DOCUMENT_PROPERTIES_INVALID_OR_MISSING +
'publicKey'
);
const didDocument = await this.getDIDDocFull(did);
const isDIdDocUpdated = await didDocument.updatePublicKey({
publicKey,
Expand Down Expand Up @@ -314,6 +309,11 @@ export class DidRegistry {
type: PubKeyType;
validity?: number;
}): Promise<boolean> {
if (!delegatePublicKey)
throw new Error(
ERROR_MESSAGES.CAN_NOT_UPDATE_DOCUMENT_PROPERTIES_INVALID_OR_MISSING +
'delegatePublicKey'
);
const didDocument = await this.getDIDDocFull(did);
const isDIdDocUpdated = await didDocument.updateDelegate({
delegatePublicKey,
Expand Down Expand Up @@ -355,6 +355,28 @@ export class DidRegistry {
return this._jwt.decode(token);
}

private async getDIDDocFull(did) {
if (did === this._signerService.did) {
return this._document;
} else {
const assetDID = (await this._assetsService.getOwnedAssets()).find(
(a) => a.document.id === did
)?.id;
if (!assetDID) {
throw new Error(ERROR_MESSAGES.CAN_NOT_UPDATE_NOT_CONTROLLED_DOCUMENT);
}

const { didRegistryAddress: didContractAddress } =
chainConfigs()[this._signerService.chainId];
const operator = new ProxyOperator(
this._identityOwner,
{ address: didContractAddress },
addressOf(assetDID)
);
return new DIDDocumentFull(did, operator);
}
}

private async _setOperator() {
const signer = this._signerService.signer;
const provider = signer.provider;
Expand Down Expand Up @@ -416,4 +438,38 @@ export class DidRegistry {
})
);
}

/**
* validates update document request
*/
private validDateUpdateDocumentRequest({
didAttribute,
data,
did,
}: {
didAttribute: DIDAttribute;
data: IUpdateData;
did: string;
}) {
const rq = { didAttribute, data, did };
try {
switch (didAttribute) {
case DIDAttribute.ServicePoint:
UpdateServicePoint.check(rq);
break;
case DIDAttribute.Authenticate:
UpdateDelegate.check(rq);
break;
case DIDAttribute.PublicKey:
UpdatePublicKey.check(rq);
break;
default:
throw new Error('didAttribute invalida or missing');
}
} catch (e) {
throw new Error(
ERROR_MESSAGES.CAN_NOT_UPDATE_DOCUMENT_PROPERTIES_INVALID_OR_MISSING + (e as Error).message
);
}
}
}
52 changes: 52 additions & 0 deletions src/modules/didRegistry/didRegistry.validation.ts
@@ -0,0 +1,52 @@
import {
DIDAttribute,
Encoding,
PubKeyType,
} from '@ew-did-registry/did-resolver-interface';
import { KeyType } from '@ew-did-registry/keys';
import { createCheckers, iface, enumtype } from 'ts-interface-checker';

const IS_REQ_STRING = 'string';
export const { UpdateServicePoint, UpdateDelegate, UpdatePublicKey } =
createCheckers({
UpdateServicePoint: iface([], {
did: IS_REQ_STRING,
didAttribute: enumtype({ ServicePoint: DIDAttribute.ServicePoint }),
data: iface([], {
type: enumtype({ ServicePoint: DIDAttribute.ServicePoint }),
value: iface([], {
id: IS_REQ_STRING,
hash: IS_REQ_STRING,
hashAlg: IS_REQ_STRING,
}),
}),
}),

UpdateDelegate: iface([], {
did: IS_REQ_STRING,
didAttribute: enumtype({ Authenticate: DIDAttribute.Authenticate }),
data: iface([], {
type: enumtype(PubKeyType),
value: iface([], {
id: IS_REQ_STRING,
hash: IS_REQ_STRING,
hashAlg: IS_REQ_STRING,
}),
delegate: IS_REQ_STRING,
}),
}),

UpdatePublicKey: iface([], {
did: IS_REQ_STRING,
didAttribute: enumtype({ PublicKey: DIDAttribute.PublicKey }),
data: iface([], {
type: enumtype(PubKeyType),
algo: enumtype(KeyType),
encoding: enumtype(Encoding),
value: iface([], {
publicKey: IS_REQ_STRING,
tag: IS_REQ_STRING,
}),
}),
}),
});

0 comments on commit a0bfeeb

Please sign in to comment.