diff --git a/src/libDDO/DDO.ts b/src/libDDO/DDO.ts index f0478b0..35a3cc0 100644 --- a/src/libDDO/DDO.ts +++ b/src/libDDO/DDO.ts @@ -1,4 +1,8 @@ - +/* + * + * DDO Library to parse, create and validate DDO JSON data + * + */ import Authentication from "./Authentication" import Proof from "./Proof" import PublicKey from "./PublicKey" @@ -26,6 +30,18 @@ export default class DDO { BASE64: "base64", } + /* + * Function to validate a signed text using the public key + * + * :param text: text string to hash to create the signature on + * :param keyValue: public key of the signer + * :param encoding: encoding of the public key, can be 'utf8', 'hex' + * :param signature: binary value of the signature that was created by the + * users private key + * :param authenticationType: Type of authentication, at the moment it's "RsaVerificationKey2018" + * + * :return true if the signature was valid with the text + */ public static validateSignature( text: string, keyValue: string, @@ -41,6 +57,16 @@ export default class DDO { return false } + /* + * Function to sign a some text using the private key + * + * :param text: text to sign + * :param keyValue: private key in PEM format + * :param signType: at the moment only "RsaSignatureAuthentication2018" is supported + * + * :return signature in binary format + * + */ public static signText(text: string, keyValue: string, signType: string): string { let signature = "" if ( signType === PublicKey.TYPE_RSA ) { @@ -73,6 +99,10 @@ export default class DDO { } + /* + * Read from a data structur, this can be a JSON + * :param data: data to import + */ public readFromData(data: IDDO) { if (data.hasOwnProperty("id") ) { this.did = data.id @@ -111,6 +141,10 @@ export default class DDO { } } + /* + * Convert the current DDO into a data sturcture + * :return data values of the DDO + */ public toData(): IDDO { const data: IDDO = { "@context": this.context, @@ -144,10 +178,22 @@ export default class DDO { return data } + /* + * return a JSON string of the DDO data + */ public toJSON(): string { return JSON.stringify(this.toData(), null, 2) } + /* + * Add a signature to the DDO + * + * :param encoding: optional type of encoding of the public key 'hex', 'pem'. Defaults to 'pem' + * :param isEmbedded: optional if set to true then embedd the public key in + * the authorization record + * :return the private key used to sign in 'pem' format + * + */ public addSignature(encoding?: string, isEmbedded?: boolean): string { if ( encoding == null ) { encoding = DDO.ENCODING_TYPES.PEM @@ -188,10 +234,15 @@ export default class DDO { this.authentications.push(authentication) } return keys.toPrivatePem("utf8") - - return null } + /* + * Add a service to the DDO + * + * :param data: data of the service record + * + * :return The Service object + */ public addService(data): Service { const service = new Service(data) if (service.id == null ) { @@ -201,6 +252,16 @@ export default class DDO { return service } + /* + * Add proof to the DDO + * + * :param authIndex: index of the authorization record + * :param privateKey: PEM of the private key + * :param signatureText: optional signature text, if none provided + * then the 'this.hashTextList()' will be called to get the standard + * hash text + * + */ public addProof(authIndex, privateKey, signatureText?) { if ( authIndex == null ) { authIndex = 0 @@ -230,10 +291,19 @@ export default class DDO { }) } + /* + * return: true if a static has been defined in DDO + */ public isProofDefined(): boolean { return this.proof != null } + /* + * Validate the DDO for the correct data and fields, if a static + * proof is defined, then also validate the static proof + * + * :return true if this DDO is valid + */ public validate(): boolean { if (this.context.length === 0 || this.did.length === 0 || this.created.length === 0) { @@ -285,7 +355,11 @@ export default class DDO { } return true } - // return a service based on the service type value + /* + * :param serviceType: service.type to find in the DDO + * + * :return a valid service object if found, else null + */ public getService(serviceType: string): Service { const result = { service: null } this.services.forEach(function(service) { @@ -296,6 +370,21 @@ export default class DDO { return result.service } + /* + * Find a service based on it's key value + * + * e.g. + * service.ServiceAgreement = "test" + * so calling + * this function with: + * + * findServiceKeyValue("ServiceAgreement", "test") + * + * :param key: The key to search for + * :param value: the key value to match + * + * :return a service object if found else return null + */ public findServiceKeyValue(key: string, value: string): Service { const result = { service: null } this.services.forEach(function(service) { @@ -306,7 +395,12 @@ export default class DDO { return result.service } - // return a string list of fields used for hashing + /* + * Generate a list of strings for hashing + * This is used as the default hash data for signing static proofs + * + * :return a string list + */ public hashTextList(): string[] { const values = [] @@ -331,11 +425,21 @@ export default class DDO { return values } + /* + * Calculate the hash of this DDO + * :return a string hash + */ public calculateHash(): string { const values = this.hashTextList() return Web3.utils.sha3(values.join()) } + /* + * Get a public key in this DDO + * + * :param keyId: public key id to find + * :return the PublicKey object or null for not found + */ public getPublicKey(keyId: string): PublicKey { const result = {publicKey: null } this.publicKeys.forEach(function(publicKey) { @@ -346,6 +450,14 @@ export default class DDO { return result.publicKey } + /* Get an authentication object based on it's public key id + * + * This method will search the list of public keys in the DDO and + * also the embedded public keys in the authentication records + * + * :param publicKeyId: the public key id to use to search + * :return if found return the Authentication object or null + */ public getAuthentication(publicKeyId: string): Authentication { const result = {authentication: null } this.authentications.forEach(function(authentication) { @@ -360,6 +472,19 @@ export default class DDO { return result.authentication } + /* + * Validate a signature using a specified public key id. The public + * key id can be from the list of public keys, or embedded in an authorization record + * + * :param keyId: The public key to validate the signature with + * :param signatureText: optional text to use to validate the signature text, if + * none provided then use the stand hashTextList + * :param signatureValue: the singnature in binary format to validate against + * + * :return true if the signature, signatureText and keyId are all valid and have been + * signed + * + */ public validateFromKey(keyId: string, signatureText: string, signatureValue: string): boolean { let publicKey = this.getPublicKey(keyId) let authentication = null @@ -396,6 +521,15 @@ export default class DDO { ) } + /* + * Validate a static proof + * + * :param signatureText: text to validate the proof against, if not + * provided then the 'hashTextList' will be used. + * + * :return true if the proof is valid + * + */ public validateProof(signatureText?: string): boolean { if ( signatureText == null ) { signatureText = this.hashTextList().join() @@ -410,6 +544,9 @@ export default class DDO { return this.validateFromKey(this.proof.creator, signatureText, signature.toString("binary")) } + /* + * :return true if this DDO object is empty + */ public isEmpty(): boolean { return this.did && this.did.length === 0 && this.publicKeys.length === 0 @@ -417,6 +554,9 @@ export default class DDO { && this.services.length === 0 } + /* + * :return true if a DID has been assigned to this DDO + */ public isDIDAssigned(): boolean { return this.did && this.did.length > 0 }