diff --git a/README.md b/README.md index a1d0e729..6a0e6ecc 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Discord](https://img.shields.io/discord/484729862368526356.svg?style=for-the-badge)](https://discordapp.com/invite/Z3f3Cxy) [![npm](https://img.shields.io/npm/dt/3box.svg?style=for-the-badge)](https://www.npmjs.com/package/3box) [![npm](https://img.shields.io/npm/v/3box.svg?style=for-the-badge)](https://www.npmjs.com/package/3box) -[![Codecov](https://img.shields.io/codecov/c/github/uport-project/3box-js.svg?style=for-the-badge)](https://codecov.io/gh/uport-project/3box-js) +[![Codecov](https://img.shields.io/codecov/c/github/3box/3box-js.svg?style=for-the-badge)](https://codecov.io/gh/3box/3box-js) [![Twitter Follow](https://img.shields.io/twitter/follow/3boxdb.svg?style=for-the-badge&label=Twitter)](https://twitter.com/3boxdb) [![Greenkeeper badge](https://badges.greenkeeper.io/3box/3box-js.svg)](https://greenkeeper.io/) diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 83f4fb13..213055c4 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,10 @@ # Release Notes +## v1.7.2 - 2019-04-30 +* Fix: Don't allow setting values wihtout a 'key' +* Fix: Ensure that linkProfile only happens once +* Fix: Import keys in correct format + ## v1.7.1 - 2019-04-25 * Fix: Throw error on openSpace if user denies consent * Fix: Return correct timestamp format in metadata diff --git a/package-lock.json b/package-lock.json index 2678378a..b8b79aca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "3box", - "version": "1.6.1-beta.1", + "version": "1.7.1", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -4298,7 +4298,6 @@ "datastore-core": "~0.6.0", "encoding-down": "^5.0.4", "interface-datastore": "~0.6.0", - "level-js": "github:timkuijsten/level.js#18e03adab34c49523be7d3d58fafb0c632f61303", "leveldown": "^3.0.2", "levelup": "^2.0.2", "pull-stream": "^3.6.9" @@ -4314,12 +4313,22 @@ }, "level-js": { "version": "github:timkuijsten/level.js#18e03adab34c49523be7d3d58fafb0c632f61303", - "from": "github:timkuijsten/level.js#idbunwrapper", + "from": "github:timkuijsten/level.js#18e03adab34c49523be7d3d58fafb0c632f61303", "requires": { "abstract-leveldown": "~2.4.1", "idb-readable-stream": "0.0.4", "ltgt": "^2.1.2", "xtend": "^4.0.1" + }, + "dependencies": { + "idb-readable-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/idb-readable-stream/-/idb-readable-stream-0.0.4.tgz", + "integrity": "sha1-MoPaZkW/ayINxhumHfYr7l2uSs8=", + "requires": { + "xtend": "^4.0.1" + } + } } }, "pull-stream": { @@ -7749,14 +7758,6 @@ "safer-buffer": ">= 2.1.2 < 3" } }, - "idb-readable-stream": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/idb-readable-stream/-/idb-readable-stream-0.0.4.tgz", - "integrity": "sha1-MoPaZkW/ayINxhumHfYr7l2uSs8=", - "requires": { - "xtend": "^4.0.1" - } - }, "ieee754": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", @@ -8340,13 +8341,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -8510,13 +8510,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -8834,13 +8833,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -8891,13 +8889,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -9283,14 +9280,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master", - "dev": true + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -9361,14 +9356,12 @@ "pem-jwk": "^1.5.1", "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", - "tweetnacl": "^1.0.0", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "tweetnacl": "^1.0.0" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master", - "dev": true + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -9983,14 +9976,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master", - "dev": true + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -12249,13 +12240,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -12497,13 +12487,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -12553,13 +12542,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -12711,13 +12699,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -12766,13 +12753,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -12924,13 +12910,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -13018,13 +13003,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -13067,13 +13051,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -13214,8 +13197,7 @@ "simple-peer": "^9.1.2", "socket.io": "^2.1.1", "socket.io-client": "^2.1.1", - "stream-to-pull-stream": "^1.7.2", - "webrtcsupport": "github:ipfs/webrtcsupport#0669f576582c53a3a42aa5ac014fcc5966809615" + "stream-to-pull-stream": "^1.7.2" }, "dependencies": { "debug": { @@ -13243,13 +13225,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -13336,6 +13317,10 @@ "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", "from": "github:dignifiedquire/webcrypto-shim#master" + }, + "webrtcsupport": { + "version": "github:ipfs/webrtcsupport#0669f576582c53a3a42aa5ac014fcc5966809615", + "from": "github:ipfs/webrtcsupport#0669f576582c53a3a42aa5ac014fcc5966809615" } } }, @@ -13387,13 +13372,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -13473,13 +13457,12 @@ "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", "tweetnacl": "^1.0.0", - "ursa-optional": "~0.9.9", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "ursa-optional": "~0.9.9" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -15347,13 +15330,12 @@ "pem-jwk": "^1.5.1", "protons": "^1.0.1", "rsa-pem-to-jwk": "^1.1.3", - "tweetnacl": "^1.0.0", - "webcrypto-shim": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" + "tweetnacl": "^1.0.0" }, "dependencies": { "webcrypto-shim": { "version": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8", - "from": "github:dignifiedquire/webcrypto-shim#master" + "from": "github:dignifiedquire/webcrypto-shim#190bc9ec341375df6025b17ae12ddb2428ea49c8" } } }, @@ -20375,10 +20357,6 @@ } } }, - "webrtcsupport": { - "version": "github:ipfs/webrtcsupport#0669f576582c53a3a42aa5ac014fcc5966809615", - "from": "github:ipfs/webrtcsupport" - }, "whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", diff --git a/package.json b/package.json index 1bca3673..ae72ab87 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "3box", - "version": "1.7.1", + "version": "1.7.2", "description": "Interact with user data", "main": "lib/3box.js", "directories": { @@ -8,7 +8,7 @@ }, "scripts": { "lint": "./node_modules/.bin/standard --verbose src/**", - "test": "rm -rf ./tmp ; jest --forceExit --coverage --runInBand --testURL=\"http://localhost\"", + "test": "rm -rf ./tmp ; jest --detectOpenHandles --coverage --runInBand --testURL=\"http://localhost\"", "build:es5": "rm -rf ./lib; ./node_modules/.bin/babel src --out-dir lib --ignore=src/__tests__/,src/__mocks__/", "build:dist": "./node_modules/.bin/webpack --config webpack.config.js --mode=development", "build:dist:dev": "./node_modules/.bin/webpack --config webpack.dev.config.js --mode=development", @@ -45,7 +45,6 @@ "dependencies": { "@babel/runtime": "^7.1.2", "did-jwt": "^0.1.1", - "elliptic": "^6.4.1", "ethers": "^4.0.20", "graphql-request": "^1.8.2", "https-did-resolver": "^0.1.0", diff --git a/readme-template.md b/readme-template.md index fab20af7..12477186 100644 --- a/readme-template.md +++ b/readme-template.md @@ -2,7 +2,7 @@ [![Discord](https://img.shields.io/discord/484729862368526356.svg?style=for-the-badge)](https://discordapp.com/invite/Z3f3Cxy) [![npm](https://img.shields.io/npm/dt/3box.svg?style=for-the-badge)](https://www.npmjs.com/package/3box) [![npm](https://img.shields.io/npm/v/3box.svg?style=for-the-badge)](https://www.npmjs.com/package/3box) -[![Codecov](https://img.shields.io/codecov/c/github/uport-project/3box-js.svg?style=for-the-badge)](https://codecov.io/gh/uport-project/3box-js) +[![Codecov](https://img.shields.io/codecov/c/github/3box/3box-js.svg?style=for-the-badge)](https://codecov.io/gh/3box/3box-js) [![Twitter Follow](https://img.shields.io/twitter/follow/3boxdb.svg?style=for-the-badge&label=Twitter)](https://twitter.com/3boxdb) [![Greenkeeper badge](https://badges.greenkeeper.io/3box/3box-js.svg)](https://greenkeeper.io/) diff --git a/src/3box.js b/src/3box.js index f0c233b4..c33e4e68 100644 --- a/src/3box.js +++ b/src/3box.js @@ -82,7 +82,8 @@ class Box { this._orbitdb = new OrbitDB(this._ipfs, opts.orbitPath) // , { cache }) globalOrbitDB = this._orbitdb - const key = this._3id.getKeyringBySpaceName(rootStoreName).getDBKey() + const dbKey = this._3id.getKeyringBySpaceName(rootStoreName).getDBKey() + const key = await this._orbitdb.keystore.importPrivateKey(dbKey) this._rootStore = await this._orbitdb.feed(rootStoreName, { key, write: [key.getPublic('hex')] @@ -423,7 +424,13 @@ class Box { consent_signature: consent.sig, linked_did: did } - await this.public.set('ethereum_proof', linkData) + await this.public.set('ethereum_proof', linkData, { noLink: true }) + } + + // Ensure we self-published our did + if (!(await this.public.get('proof_did'))) { + // we can just sign an empty JWT as a proof that we own this DID + await this.public.set('proof_did', await this._3id.signJWT(), { noLink: true }) } // Send consentSignature to 3box-address-server to link profile with ethereum address @@ -432,12 +439,6 @@ class Box { } catch (err) { console.error(err) } - - // Ensure we self-published our did - if (!(await this.public.get('proof_did'))) { - // we can just sign an empty JWT as a proof that we own this DID - await this.public.set('proof_did', await this._3id.signJWT()) - } } async _ensurePinningNodeConnected (odbAddress, isThread) { diff --git a/src/3id/__tests__/keyring.test.js b/src/3id/__tests__/keyring.test.js index 59f498eb..c85cb6c2 100644 --- a/src/3id/__tests__/keyring.test.js +++ b/src/3id/__tests__/keyring.test.js @@ -42,7 +42,7 @@ describe('Keyring', () => { it('getDBKey works correctly', async () => { const key = keyring1.getDBKey() - expect(key.getPublic('hex')).toEqual('048aaa695fa16f2a2279e1de718d80e00f4f4ddf30fe8674bbdb9e1f11778c2f77f8ffb5ad2bd3f1f9840b3462c26f756ec0f47626894c20ed247145f5c0e26fe8') + expect(key).toEqual('68957df606e586990a6286239987aaf4c902971ae642d50609d35ff36fb0728a') }) it('signs data correctly', async () => { diff --git a/src/3id/keyring.js b/src/3id/keyring.js index 42f587ed..066c331c 100644 --- a/src/3id/keyring.js +++ b/src/3id/keyring.js @@ -1,8 +1,6 @@ const { HDNode } = require('ethers').utils const nacl = require('tweetnacl') nacl.util = require('tweetnacl-util') -const EC = require('elliptic').ec -const ec = new EC('secp256k1') const SimpleSigner = require('did-jwt').SimpleSigner const { sha256 } = require('../utils/index') @@ -60,7 +58,7 @@ class Keyring { } getDBKey () { - return ec.keyFromPrivate(this.signingKey.privateKey.slice(2)) + return this.signingKey.privateKey.slice(2) } getDBSalt () { diff --git a/src/__tests__/3box.test.js b/src/__tests__/3box.test.js index 1fa282e5..cbdd47c9 100644 --- a/src/__tests__/3box.test.js +++ b/src/__tests__/3box.test.js @@ -2,7 +2,6 @@ const testUtils = require('./testUtils') const OrbitDB = require('orbit-db') const Pubsub = require('orbit-db-pubsub') const jsdom = require('jsdom') -const IPFS = require('ipfs') const Box = require('../3box') global.window = new jsdom.JSDOM().window @@ -31,7 +30,7 @@ jest.mock('../3id', () => { muportFingerprint: managementKey === '0x12345' ? 'b932fe7ab' : 'ab8c73d8f', getDidDocument: () => { return { managementKey } }, getKeyringBySpaceName: () => { - return { getDBKey: () => ec.keyFromPrivate('f917ac6883f88798a8ce39821fa523f2acd17c0ba80c724f219367e76d8f2c46') } + return { getDBKey: () => 'f917ac6883f88798a8ce39821fa523f2acd17c0ba80c724f219367e76d8f2c46' } } } } @@ -146,7 +145,7 @@ describe('3Box', () => { let ipfs, pubsub, boxOpts, ipfsBox, box jest.setTimeout(30000) - beforeEach(async () => { + beforeAll(async () => { if (!ipfs) ipfs = await testUtils.initIPFS(0) const ipfsMultiAddr = (await ipfs.id()).addresses[0] if (!pubsub) pubsub = new Pubsub(ipfs, (await ipfs.id()).id) @@ -159,9 +158,7 @@ describe('3Box', () => { } if (!ipfsBox) { - //ipfsBox = new IPFS(IPFS_OPTIONS) ipfsBox = await testUtils.initIPFS(1) - //await new Promise((resolve, reject) => { ipfsBox.on('ready', () => resolve() )}) } boxOpts = { @@ -173,7 +170,9 @@ describe('3Box', () => { iframeStore: false, pinningNode: ipfsMultiAddr } + }) + beforeEach(async () => { mockedUtils.openBoxConsent.mockClear() mockedUtils.fetchJson.mockClear() mockedUtils.getLinkConsent.mockClear() @@ -182,10 +181,11 @@ describe('3Box', () => { }) afterAll(async () => { - await pubsub.disconnect() - //await ipfs.stop() -}) - + await pubsub.disconnect() + await box.close() + await testUtils.stopIPFS(ipfs, 0) + await testUtils.stopIPFS(ipfsBox, 1) + }) it('should openBox correctly', async () => { const publishPromise = new Promise((resolve, reject) => { @@ -255,6 +255,7 @@ describe('3Box', () => { expect(mockedUtils.fetchJson).toHaveBeenCalledTimes(1) await publishPromise pubsub.unsubscribe('3box-pinning') + await orbitdb.stop() }) it('should open spaces correctly', async () => { @@ -304,7 +305,7 @@ describe('3Box', () => { // It will check the self-signed did expect(box.public.get).toHaveBeenNthCalledWith(2, 'proof_did') - expect(box.public.set).toHaveBeenNthCalledWith(2, 'proof_did', 'veryJWT,did:muport:Qmsdfp98yw4t7') + expect(box.public.set).toHaveBeenNthCalledWith(2, 'proof_did', 'veryJWT,did:muport:Qmsdfp98yw4t7', { noLink: true }) expect(global.console.error).toHaveBeenCalledTimes(1) expect(mockedUtils.fetchJson).toHaveBeenCalledTimes(1) @@ -425,6 +426,7 @@ describe('3Box', () => { }) it('should get profile (when API is used)', async () => { + delete boxOpts.useCacheService const profile = await Box.getProfile('0x12345', boxOpts) expect(profile).toEqual({ name: 'zfer', diff --git a/src/__tests__/keyValueStore.test.js b/src/__tests__/keyValueStore.test.js index cad1311d..2dfac8f8 100644 --- a/src/__tests__/keyValueStore.test.js +++ b/src/__tests__/keyValueStore.test.js @@ -8,7 +8,7 @@ const STORE_NAME = '09ab7cd93f9e.public' const THREEID_MOCK = { getKeyringBySpaceName: () => { - return { getDBKey: () => ec.keyFromPrivate('f917ac6883f88798a8ce39821fa523f2acd17c0ba80c724f219367e76d8f2c46') } + return { getDBKey: () => 'f917ac6883f88798a8ce39821fa523f2acd17c0ba80c724f219367e76d8f2c46' } } } @@ -67,6 +67,11 @@ describe('KeyValueStore', () => { expect(ensureConnected).toHaveBeenCalledTimes(2) }) + it('should throw if key not given', async () => { + expect(keyValueStore.set()).rejects.toEqual(new Error('key is a required argument')) + expect(keyValueStore.remove()).rejects.toEqual(new Error('key is a required argument')) + }) + it('should sync an old profile correctly', async () => { let ipfs2 = await utils.initIPFS(3) let orbitdb2 = new OrbitDB(ipfs2, './tmp/orbitdb2') @@ -81,7 +86,7 @@ describe('KeyValueStore', () => { expect(await keyValueStore2.get('key2')).toBeUndefined() expect(await keyValueStore2.get('key3')).toBeUndefined() await orbitdb2.stop() - // await ipfs2.stop() + await utils.stopIPFS(ipfs2, 3) }) describe('metdata', () => { @@ -150,8 +155,11 @@ describe('KeyValueStore', () => { }) }) - // afterAll(async () => { - // await orbitdb.stop() - // await ipfs.stop() - // }) + it('should including ALL entries, including DEL ops', async () => { + }) + + afterAll(async () => { + await orbitdb.stop() + await utils.stopIPFS(ipfs, 2) + }) }) diff --git a/src/__tests__/privateStore.test.js b/src/__tests__/privateStore.test.js index 85af2305..70498a31 100644 --- a/src/__tests__/privateStore.test.js +++ b/src/__tests__/privateStore.test.js @@ -106,6 +106,11 @@ describe('PrivateStore', () => { expect(await privateStore.get('key2')).toBeNull() }) + it('should throw if key not given', async () => { + expect(privateStore.set()).rejects.toEqual(new Error('Entry to encrypt cannot be undefined')) + expect(privateStore.remove()).rejects.toEqual(new Error('key is a required argument')) + }) + describe('log', () => { beforeEach(async () => { diff --git a/src/__tests__/publicStore.test.js b/src/__tests__/publicStore.test.js index 8b0bb0f4..566a7456 100644 --- a/src/__tests__/publicStore.test.js +++ b/src/__tests__/publicStore.test.js @@ -25,6 +25,18 @@ describe('PublicStore', () => { expect(linkProfile).toHaveBeenCalledWith() }) + it('should not call linkProfile when noLink is true', async () => { + linkProfile.mockClear() + await publicStore._load() + let ret = await publicStore.set('key1', 'value1', { noLink: true }) + expect(ret).toEqual(true) + expect(linkProfile).toHaveBeenCalledTimes(0) + }) + + it('should throw if key not given', async () => { + expect(publicStore.set()).rejects.toEqual(new Error('key is a required argument')) + }) + it('should return profile correctly', async () => { expect(await publicStore.all()).toEqual({ key1: 'value1' }) }) diff --git a/src/__tests__/space.test.js b/src/__tests__/space.test.js index 301e0e1c..fb3fd949 100644 --- a/src/__tests__/space.test.js +++ b/src/__tests__/space.test.js @@ -113,6 +113,11 @@ describe('Space', () => { k3: 'v3' }) }) + + it('should throw if key not given', async () => { + expect(space.public.set()).rejects.toEqual(new Error('key is a required argument')) + expect(space.public.remove()).rejects.toEqual(new Error('key is a required argument')) + }) }) describe('private store reducer', () => { @@ -142,6 +147,11 @@ describe('Space', () => { k3: 'sv3' }) }) + + it('should throw if key not given', async () => { + expect(space.private.set()).rejects.toEqual(new Error('key is a required argument')) + expect(space.private.remove()).rejects.toEqual(new Error('key is a required argument')) + }) }) describe('Threads', () => { diff --git a/src/__tests__/testUtils.js b/src/__tests__/testUtils.js index a152fe1d..8d6d9e5a 100644 --- a/src/__tests__/testUtils.js +++ b/src/__tests__/testUtils.js @@ -1,4 +1,5 @@ const IPFS = require('ipfs') +const fs = require('fs') const CONF_1 = { EXPERIMENTAL: { @@ -116,5 +117,11 @@ module.exports = { ipfs.on('error', reject) ipfs.on('ready', () => resolve(ipfs)) }) + }, + stopIPFS: async (ipfs, useAltConf) => { + // seems to be an issue with the api file not being present when trying to close ipfs + const apiFilePath = CONFS[useAltConf].repo + 'api' + fs.closeSync(fs.openSync(apiFilePath, 'w')) + await ipfs.stop() } } diff --git a/src/__tests__/thread.test.js b/src/__tests__/thread.test.js index e9388077..f0170447 100644 --- a/src/__tests__/thread.test.js +++ b/src/__tests__/thread.test.js @@ -14,13 +14,13 @@ const MSG4 = 'message4' const THREEID1_MOCK = { _mainKeyring: { - getDBKey: () => ec.keyFromPrivate('f917ac6883f88798a8ce39821fa523f2acd17c0ba80c724f219367e76d8f2c46') + getDBKey: () => 'f917ac6883f88798a8ce39821fa523f2acd17c0ba80c724f219367e76d8f2c46' }, getDid: () => 'did:3:mydid1' } const THREEID2_MOCK = { _mainKeyring: { - getDBKey: () => ec.keyFromPrivate('f977777aaaaaaabbbbbbb9821fa523f2acd17c0ba80c724f219367e76d8f2c46') + getDBKey: () => 'f977777aaaaaaabbbbbbb9821fa523f2acd17c0ba80c724f219367e76d8f2c46' }, getDid: () => 'did:3:mydid2' } @@ -147,5 +147,15 @@ describe('Thread', () => { expect(posts1[1].message).toEqual(MSG2) expect(posts1[1].postId).toEqual(posts2[1].postId) }) + + afterAll(async () => { + await orbitdb2.stop() + await utils.stopIPFS(ipfs2, 5) + }) + }) + + afterAll(async () => { + await orbitdb.stop() + await utils.stopIPFS(ipfs, 4) }) }) diff --git a/src/keyValueStore.js b/src/keyValueStore.js index 0441d2e1..b9adc19c 100644 --- a/src/keyValueStore.js +++ b/src/keyValueStore.js @@ -1,3 +1,5 @@ +const { throwIfUndefined } = require('./utils/index') + class KeyValueStore { /** * Please use **box.public** or **box.private** to get the instance of this class @@ -47,6 +49,7 @@ class KeyValueStore { * @return {Boolean} true if successful */ async set (key, value) { + throwIfUndefined(key, 'key') this._requireLoad() this._ensureConnected() const timeStamp = new Date().getTime() @@ -61,6 +64,7 @@ class KeyValueStore { * @return {Boolean} true if successful */ async remove (key) { + throwIfUndefined(key, 'key') this._requireLoad() this._ensureConnected() await this._db.del(key) @@ -113,7 +117,8 @@ class KeyValueStore { } async _load (odbAddress) { - const key = this._3id.getKeyringBySpaceName(this._name).getDBKey() + const dbKey = this._3id.getKeyringBySpaceName(this._name).getDBKey() + const key = await this._orbitdb.keystore.importPrivateKey(dbKey) this._db = await this._orbitdb.keyvalue(odbAddress || this._name, { key, write: [key.getPublic('hex')] diff --git a/src/privateStore.js b/src/privateStore.js index f4d72fb9..61718a47 100644 --- a/src/privateStore.js +++ b/src/privateStore.js @@ -51,6 +51,7 @@ class PrivateStore extends KeyValueStore { } _genDbKey (key) { + utils.throwIfUndefined(key, 'key') return utils.sha256Multihash(this._salt + key) } diff --git a/src/publicStore.js b/src/publicStore.js index 383cf084..0e10d881 100644 --- a/src/publicStore.js +++ b/src/publicStore.js @@ -1,4 +1,5 @@ const KeyValueStore = require('./keyValueStore') +const { throwIfUndefined } = require('./utils/index') class ProfileStore extends KeyValueStore { constructor (orbitdb, name, linkProfile, ensureConnected, _3id) { @@ -6,8 +7,10 @@ class ProfileStore extends KeyValueStore { this._linkProfile = linkProfile } - async set (key, value) { - this._linkProfile() + async set (key, value, opts = {}) { + throwIfUndefined(key, 'key') + // if this is the noLink call we shouldn't call _linkProfile. + if (!opts.noLink) this._linkProfile() return super.set(key, value) } } diff --git a/src/space.js b/src/space.js index 43bde22d..0f84bfad 100644 --- a/src/space.js +++ b/src/space.js @@ -1,6 +1,6 @@ const KeyValueStore = require('./keyValueStore') const Thread = require('./thread') -const { sha256Multihash } = require('./utils') +const { sha256Multihash, throwIfUndefined } = require('./utils') const ENC_BLOCK_SIZE = 24 const nameToSpaceName = name => `3box.space.${name}.keyvalue` @@ -118,8 +118,14 @@ const publicStoreReducer = (store) => { return { get: async key => store.get(PREFIX + key), getMetadata: async key => store.getMetadata(PREFIX + key), - set: async (key, value) => store.set(PREFIX + key, value), - remove: async key => store.remove(PREFIX + key), + set: async (key, value) => { + throwIfUndefined(key, 'key') + store.set(PREFIX + key, value) + }, + remove: async key => { + throwIfUndefined(key, 'key') + store.remove(PREFIX + key) + }, get log () { return store.log.reduce((newLog, entry) => { if (entry.key.startsWith(PREFIX)) { @@ -144,7 +150,10 @@ const publicStoreReducer = (store) => { const privateStoreReducer = (store, keyring) => { const PREFIX = 'priv_' const SALT = keyring.getDBSalt() - const dbKey = key => PREFIX + sha256Multihash(SALT + key) + const dbKey = key => { + throwIfUndefined(key, 'key') + return PREFIX + sha256Multihash(SALT + key) + } const pad = (val, blockSize = ENC_BLOCK_SIZE) => { const blockDiff = (blockSize - (val.length % blockSize)) % blockSize return `${val}${'\0'.repeat(blockDiff)}` diff --git a/src/thread.js b/src/thread.js index 12e4d686..682b3585 100644 --- a/src/thread.js +++ b/src/thread.js @@ -83,7 +83,8 @@ class Thread { async _load (odbAddress) { // TODO - threads should use the space keyring once pairwise DIDs are implemented - const key = this._3id._mainKeyring.getDBKey() + const dbKey = this._3id._mainKeyring.getDBKey() + const key = await this._orbitdb.keystore.importPrivateKey(dbKey) this._db = await this._orbitdb.log(odbAddress || this._name, { key, write: ['*'] diff --git a/src/utils/index.js b/src/utils/index.js index 21b977b8..1c0f9849 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -113,6 +113,12 @@ module.exports = { } }, + throwIfUndefined: (arg, name) => { + if (arg === undefined || arg === null) { + throw new Error(`${name} is a required argument`) + } + }, + sha256Multihash: str => { const digest = Buffer.from(sha256.digest(str)) return Multihash.encode(digest, 'sha2-256').toString('hex')