From f9e5a74921d6b57e32db8582541c78e9d9c1acdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chuck=20LeDuc=20D=C3=ADaz?= Date: Tue, 12 May 2020 12:46:41 +0200 Subject: [PATCH] fix ipfs endpoint for verify; change validateCertificate to verifyCredential --- .vscode/launch.json | 1 + .vscode/settings.json | 59 ++++++++++++++++++++++++++++++++ package.json | 12 +++---- src/index.js | 79 +++++++++++++++++++++++++++++++++++-------- test/lorena-test.js | 10 +++--- 5 files changed, 137 insertions(+), 24 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index d4e1608..a62c02f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -16,6 +16,7 @@ "bdd", "--timeout", "999999", + "--bail", "--colors", "${workspaceFolder}/test" ], diff --git a/.vscode/settings.json b/.vscode/settings.json index dbe4606..a72598c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,14 +3,17 @@ "Dspace", "GMVZE", "Puig", + "Sessionless", "Tqnl", "admintest", "caelumlabs", "connectionstring", "diddoc", "idspaces", + "ipfs", "keypair", "labdev", + "labtest", "lcov", "maxonrow", "nikola", @@ -19,5 +22,61 @@ "pubkey", "superadmin", "zenroom" + ], + "cSpell.ignoreWords": [ + "a", + "aa", + "bj", + "bo", + "bww", + "c", + "cd", + "cg", + "d", + "e", + "ez", + "gc", + "gta", + "h", + "he", + "hl", + "ia", + "ik", + "iymfx", + "j", + "jlr", + "k", + "kn", + "le", + "lm", + "m", + "ms", + "myll", + "n", + "nl", + "o", + "pfcy", + "pus", + "qgkv", + "qz", + "s", + "sx", + "tkz", + "uf", + "ufr", + "umpo", + "uu", + "uv", + "v", + "vf", + "vk", + "vlrdz", + "w", + "xw", + "y", + "z", + "zb", + "zpbm", + "zw" ] } \ No newline at end of file diff --git a/package.json b/package.json index 6c046b4..70971c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@lorena-ssi/lorena-sdk", - "version": "1.3.3", + "version": "1.4.0", "description": "Lorena SDK", "author": "Alex Puig ", "license": "MIT", @@ -24,25 +24,25 @@ "homepage": "https://github.com/lorena-ssi/lorena-sdk#readme", "dependencies": { "@lorena-ssi/credential-lib": "^1.1.2", - "@lorena-ssi/did-resolver": "^0.3.0", + "@lorena-ssi/did-resolver": "^0.4.2", "@lorena-ssi/matrix-lib": "^1.0.13", - "@lorena-ssi/wallet-lib": "1.1.3", + "@lorena-ssi/wallet-lib": "1.1.5", "@lorena-ssi/zenroom-lib": "1.5.3", "debug": "^4.1.1", "did-resolver": "^1.1.0", "esm": "^3.2.25", - "ipfs-http-client": "^44.0.1" + "ipfs-http-client": "^44.0.3" }, "devDependencies": { "chai": "^4.2.0", "chai-as-promised": "^7.1.1", "chai-spies": "^1.0.0", "coveralls": "^3.1.0", - "eslint": "^6.8.0", + "eslint": "^7.0.0", "eslint-config-standard": "^14.1.1", "eslint-plugin-chai-friendly": "^0.6.0", "eslint-plugin-import": "^2.20.2", - "eslint-plugin-jsdoc": "^24.0.2", + "eslint-plugin-jsdoc": "^25.2.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.1", diff --git a/src/index.js b/src/index.js index eebefbc..8c24f15 100644 --- a/src/index.js +++ b/src/index.js @@ -169,6 +169,7 @@ export default class Lorena extends EventEmitter { disconnect () { this.emit('disconnecting') this.disconnecting = true + LorenaDidResolver.disconnectAll() } /** @@ -320,21 +321,59 @@ export default class Lorena extends EventEmitter { return this.oneMsg(`message:${recipe}`) } - async getDiddoc (did) { + /** + * Get the DID resolver for the lor namespace, caching as necessary + * + * @returns {object} resolver + */ + getLorResolver () { + if (!this.lorResolver) { + this.lorResolver = LorenaDidResolver.getResolver() + } + return this.lorResolver + } + + /** + * Get the general DID resolver for all namespaces, caching as necessary + * + * @returns {object} resolver + */ + getResolver () { if (!this.resolver) { - const lorResolver = LorenaDidResolver.getResolver() - this.resolver = new Resolver(lorResolver, true) + this.resolver = new Resolver(this.getLorResolver(), true) } - const diddoc = await this.resolver.resolve(did) + return this.resolver + } + + /** + * Get the specified DID document using the DID resolver + * + * @param {string} did to fetch + * @returns {object} diddoc + */ + async getDiddoc (did) { + const diddoc = await this.getResolver().resolve(did) return diddoc } + /** + * Get the matrix User ID for the specified DID + * + * @param {string} did to fetch + * @returns {string} matrixUserID + */ async getMatrixUserIDForDID (did) { const diddoc = await this.getDiddoc(did) const matrixUserID = diddoc.service[0].serviceEndpoint return matrixUserID } + /** + * Get the public key for the specified DID + * + * @param {string} did to fetch + * @returns {string} public key + */ async getPublicKeyForDID (did) { const diddoc = await this.getDiddoc(did) const publicKey = diddoc.authentication[0].publicKey @@ -541,7 +580,25 @@ export default class Lorena extends EventEmitter { }) } + /** + * Verify a credential (deprecated: use `verifyCredential()`) + * + * @param {*} json of credential to verify + * @returns {Promise} of success (JSON) or failure (false) + */ + /* istanbul ignore next */ validateCertificate (json) { + debug('validateCertificate() deprecated: use verifyCredential()') + return this.verifyCredential(json) + } + + /** + * Verify a credential + * + * @param {*} json of credential to verify + * @returns {Promise} of success (JSON) or failure (false) + */ + verifyCredential (json) { return new Promise((resolve) => { try { const credential = JSON.parse(json) @@ -550,14 +607,8 @@ export default class Lorena extends EventEmitter { issuer: credential.issuer } - // Load resolver. - if (!this.resolver) { - const lorResolver = LorenaDidResolver.getResolver() - this.resolver = new Resolver(lorResolver, true) - } - - // get Publick Key -> Resolve from Blockchain & Check credential signature - this.resolver.resolve(verified.issuer) + // get Public Key -> Resolve from Blockchain & Check credential signature + this.getResolver().resolve(verified.issuer) .then((diddoc) => { verified.network = verified.issuer.split(':')[2] verified.pubKey = diddoc.authentication[0].publicKey @@ -567,14 +618,14 @@ export default class Lorena extends EventEmitter { .then((result) => { verified.checkCertificateSignature = result // IPFS DAG : Load Credential from IPFS - const ipfs = new IpfsClient({ host: 'labdev.ipfs.lorena.tech', port: '5001' }) + const ipfs = new IpfsClient(LorenaDidResolver.getInfoForNetwork(verified.network).ipfsEndpoint) const did = credential.credentialSubject.course.id const cid = did.split(':')[3] return ipfs.dag.get(cid) }) .then((result) => { verified.credential = result.value - // Verify Credencial -> The credential is signed by the Issuer + // Verify Credential -> The credential is signed by the Issuer return Credential.verifyCredential(this.zenroom, verified.credential, verified.pubKey, verified.issuer) }) .then((result) => { diff --git a/test/lorena-test.js b/test/lorena-test.js index a20dea0..d343e41 100644 --- a/test/lorena-test.js +++ b/test/lorena-test.js @@ -1,4 +1,4 @@ -import Lorena from '../src/index.js' +import Lorena from '../index.js' import Wallet from '@lorena-ssi/wallet-lib' import chai, { expect } from 'chai' import { describe, it } from 'mocha' @@ -64,10 +64,10 @@ describe('Lorena SDK', function () { lorena.disconnect() }) - it('should validate a Credential', (done) => { - const lorenaDisconnected = new Lorena() + it('should verify a Credential', (done) => { + const lorenaSessionless = new Lorena() const json = '{"@context":["https://www.w3.org/2018/credentials/v1"],"type":["VerifiableCredential","Achievement"],"issuer":"did:lor:labtest:ZGtaUFRIaHlOQzEzUmpoSVlrdzJZbTkz","issuanceDate":"2020-04-30T04:17:18.037Z","credentialSubject":{"@type":"Achievement","id":"did:lor:labtest:bafyreiegi4p5fg65chx67gkppk2zcded7smfe6lgestf44wcqyiuxicriu;id:22","course":{"id":"did:lor:labtest:bafyreiegi4p5fg65chx67gkppk2zcded7smfe6lgestf44wcqyiuxicriu"},"agent":{"@type":"Person","id":"","name":"Alex Puig","email":"alex@caelumlabs.com"},"expirationDate":""},"proof":{"type":"Curve448-Goldilocks","proofPurpose":"assertionMethod","verificationMethod":"","signature":{"did:lor:labtest:ZGtaUFRIaHlOQzEzUmpoSVlrdzJZbTkz":{"draft":"dW5kZWZpbmVk","signature":{"r":"K1zKNIkSx87nZ7bj_JlrN8z2qgkvPUsHe25E3yZ1UU16ufH4H31MS52_leNlBoCdLmM4vUvCAaA","s":"Pcb-VF08gc7IymfxXWCgBwwPfcyMYLL-7pLrjwKuQF4p5gpfvQSCrOKk0QjolRSY3v6Wwtqwc4E"}}}}}' - lorenaDisconnected.validateCertificate(json) + lorenaSessionless.verifyCredential(json) .then((res) => { expect(typeof res).to.equal('object') expect(typeof res.verified).to.equal('object') @@ -75,6 +75,8 @@ describe('Lorena SDK', function () { expect(res.verified.network).to.equal('labtest') expect(typeof res.verified).to.equal('object') expect(typeof res.verified.certificate.credentialSubject.agent.name).to.equal('string') + + lorenaSessionless.disconnect() done() }) })