From c0bb78490e7a504fc7233ac75136fb144dc58183 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 23 Oct 2018 10:19:59 +0100 Subject: [PATCH 1/9] fix: better input validation for add License: MIT Signed-off-by: Alan Shaw --- src/core/components/files-regular.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/core/components/files-regular.js b/src/core/components/files-regular.js index d843ba6735..01ba7b30a7 100644 --- a/src/core/components/files-regular.js +++ b/src/core/components/files-regular.js @@ -14,7 +14,7 @@ const waterfall = require('async/waterfall') const isStream = require('is-stream') const isSource = require('is-pull-stream').isSource const Duplex = require('readable-stream').Duplex -const OtherBuffer = require('buffer').Buffer +const isString = require('lodash/isString') const CID = require('cids') const toB58String = require('multihashes').toB58String const errCode = require('err-code') @@ -292,15 +292,23 @@ module.exports = function (self) { options = options || {} - const ok = Buffer.isBuffer(data) || - isStream.readable(data) || - Array.isArray(data) || - OtherBuffer.isBuffer(data) || - typeof data === 'object' || - isSource(data) + // Buffer, pull stream or Node.js stream + const isBufferOrStream = obj => Buffer.isBuffer(obj) || isStream.readable(obj) || isSource(obj) + // An object like { content?, path? }, where content isBufferOrStream and path isString + const isContentObject = obj => { + if (typeof obj !== 'object') return false + // path is optional if content is present + if (obj.content) return isBufferOrStream(obj.content) + // path must be a non-empty string if no content + return Boolean(obj.path) && isString(obj.path) + } + // An input atom: a buffer, stream or content object + const isInput = obj => isBufferOrStream(obj) || isContentObject(obj) + // All is ok if data isInput or data is an array of isInput + const ok = isInput(data) || (Array.isArray(data) && data.every(isInput)) if (!ok) { - return callback(new Error('first arg must be a buffer, readable stream, pull stream, an object or array of objects')) + return callback(new Error('invalid input: expected buffer, readable stream, pull stream, object or array of objects')) } // CID v0 is for multihashes encoded with sha2-256 From f23eda9cfaf619c2345e0791fd4db092b3c93396 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Mon, 26 Nov 2018 11:35:49 +0000 Subject: [PATCH 2/9] chore: update interface-ipfs-core dependency License: MIT Signed-off-by: Alan Shaw --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3ad9ba9c28..424a46cfdd 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "execa": "^1.0.0", "form-data": "^2.3.3", "hat": "0.0.3", - "interface-ipfs-core": "~0.86.0", + "interface-ipfs-core": "~0.87.0", "ipfsd-ctl": "ipfs/js-ipfsd-ctl#update-dag-pb-to-not-have-cid-property", "ncp": "^2.0.0", "qs": "^6.5.2", From bdc6f4d0c9478324c7a343f1455feea1265654a8 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 27 Nov 2018 14:13:45 +0000 Subject: [PATCH 3/9] refactor: object APIs write methods now return CIDs For the back story on this change, please see: https://github.com/ipfs/interface-ipfs-core/pull/388#pullrequestreview-173866270 BREAKING CHANGE: Object API refactor. Object API methods that write DAG nodes now return a [CID](https://www.npmjs.com/package/cids) instead of a DAG node. Affected methods: * `ipfs.object.new` * `ipfs.object.patch.addLink` * `ipfs.object.patch.appendData` * `ipfs.object.patch.rmLink` * `ipfs.object.patch.setData` * `ipfs.object.put` Example: ```js // Before const dagNode = await ipfs.object.new() ``` ```js // After const cid = await ipfs.object.new() // now returns a CID const dagNode = await ipfs.object.get(cid) // fetch the DAG node that was created ``` IMPORTANT: `DAGNode` instances, which are part of the IPLD dag-pb format have been refactored. These instances no longer have `multihash`, `cid` or `serialized` properties. This effects the following API methods that return these types of objects: * `ipfs.object.get` * `ipfs.dag.get` See https://github.com/ipld/js-ipld-dag-pb/pull/99 for more information. License: MIT Signed-off-by: Alan Shaw --- src/core/components/object.js | 12 +++++++----- src/http/api/resources/object.js | 13 ++++++------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/core/components/object.js b/src/core/components/object.js index 2bc91d3026..57e8e0b9b4 100644 --- a/src/core/components/object.js +++ b/src/core/components/object.js @@ -98,7 +98,7 @@ module.exports = function object (self) { self._preload(cid) } - cb(null, node) + cb(null, cid) }) }) } @@ -150,7 +150,7 @@ module.exports = function object (self) { self._preload(cid) } - callback(null, node) + callback(null, cid) }) }) }), @@ -209,9 +209,11 @@ module.exports = function object (self) { return callback(err) } - self.object.get(cid, { - preload: options.preload - }, callback) + if (options.preload !== false) { + self._preload(cid) + } + + callback(null, cid) }) } }), diff --git a/src/http/api/resources/object.js b/src/http/api/resources/object.js index 5d970dc1ae..a65009a937 100644 --- a/src/http/api/resources/object.js +++ b/src/http/api/resources/object.js @@ -37,7 +37,7 @@ exports.new = (request, reply) => { waterfall([ (cb) => ipfs.object.new(template, cb), - (node, cb) => dagPB.util.cid(node, (err, cid) => cb(err, { node, cid })) + (cid, cb) => ipfs.object.get(cid, (err, node) => cb(err, { node, cid })) ], (err, results) => { if (err) { log.error(err) @@ -200,8 +200,7 @@ exports.put = { waterfall([ (cb) => DAGNode.create(Buffer.from(node.Data), node.Links, cb), - (node, cb) => ipfs.object.put(node, cb), - (node, cb) => dagPB.util.cid(node, (err, cid) => cb(err, { cid, node })) + (node, cb) => ipfs.object.put(node, (err, cid) => cb(err, { cid, node })) ], (err, results) => { if (err) { log.error(err) @@ -366,7 +365,7 @@ exports.patchAppendData = { waterfall([ (cb) => ipfs.object.patch.appendData(key, data, cb), - (node, cb) => dagPB.util.cid(node, (err, cid) => cb(err, { node, cid })) + (cid, cb) => ipfs.object.get(cid, (err, node) => cb(err, { node, cid })) ], (err, results) => { if (err) { log.error(err) @@ -409,7 +408,7 @@ exports.patchSetData = { waterfall([ (cb) => ipfs.object.patch.setData(key, data, cb), - (node, cb) => dagPB.util.cid(node, (err, cid) => cb(err, { node, cid })) + (cid, cb) => ipfs.object.get(cid, (err, node) => cb(err, { node, cid })) ], (err, results) => { if (err) { log.error(err) @@ -477,7 +476,7 @@ exports.patchAddLink = { waterfall([ (cb) => ipfs.object.get(ref, cb), (node, cb) => ipfs.object.patch.addLink(root, new DAGLink(name, node.size, ref), cb), - (node, cb) => dagPB.util.cid(node, (err, cid) => cb(err, { node, cid })) + (cid, cb) => ipfs.object.get(cid, (err, node) => cb(err, { node, cid })) ], (err, results) => { if (err) { log.error(err) @@ -544,7 +543,7 @@ exports.patchRmLink = { waterfall([ (cb) => ipfs.object.patch.rmLink(root, { name: link }, cb), - (node, cb) => dagPB.util.cid(node, (err, cid) => cb(err, { node, cid })) + (cid, cb) => ipfs.object.get(cid, (err, node) => cb(err, { node, cid })) ], (err, results) => { if (err) { log.error(err) From d6bc70636c5ef1910fd6566fcf370e3b3d79d9b4 Mon Sep 17 00:00:00 2001 From: Alan Shaw Date: Tue, 27 Nov 2018 14:53:58 +0000 Subject: [PATCH 4/9] refactor: object API in CLI License: MIT Signed-off-by: Alan Shaw --- package.json | 4 ++-- src/cli/commands/object/get.js | 8 ++------ src/cli/commands/object/new.js | 15 ++------------- src/cli/commands/object/patch/add-link.js | 17 +++-------------- src/cli/commands/object/patch/append-data.js | 15 ++------------- src/cli/commands/object/patch/rm-link.js | 15 ++------------- src/cli/commands/object/patch/set-data.js | 15 ++------------- src/cli/commands/object/put.js | 15 ++------------- 8 files changed, 17 insertions(+), 87 deletions(-) diff --git a/package.json b/package.json index 3ad9ba9c28..e9dc7f30cc 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "execa": "^1.0.0", "form-data": "^2.3.3", "hat": "0.0.3", - "interface-ipfs-core": "~0.86.0", + "interface-ipfs-core": "~0.88.0", "ipfsd-ctl": "ipfs/js-ipfsd-ctl#update-dag-pb-to-not-have-cid-property", "ncp": "^2.0.0", "qs": "^6.5.2", @@ -102,7 +102,7 @@ "hoek": "^5.0.4", "human-to-milliseconds": "^1.0.0", "interface-datastore": "~0.6.0", - "ipfs-api": "ipfs/js-ipfs-api", + "ipfs-api": "ipfs/js-ipfs-api#refactor/object-api", "ipfs-bitswap": "~0.21.0", "ipfs-block": "~0.8.0", "ipfs-block-service": "~0.15.1", diff --git a/src/cli/commands/object/get.js b/src/cli/commands/object/get.js index ccc4b466ab..548ae4f508 100644 --- a/src/cli/commands/object/get.js +++ b/src/cli/commands/object/get.js @@ -1,11 +1,7 @@ 'use strict' const print = require('../../utils').print -const { - util: { - cid - } -} = require('ipld-dag-pb') +const dagPB = require('ipld-dag-pb') module.exports = { command: 'get ', @@ -29,7 +25,7 @@ module.exports = { throw err } - cid(node, (err, result) => { + dagPB.util.cid(node, (err, result) => { if (err) { throw err } diff --git a/src/cli/commands/object/new.js b/src/cli/commands/object/new.js index 36ab5a3659..fc8543fd25 100644 --- a/src/cli/commands/object/new.js +++ b/src/cli/commands/object/new.js @@ -4,11 +4,6 @@ const debug = require('debug') const log = debug('cli:object') log.error = debug('cli:object:error') const print = require('../../utils').print -const { - util: { - cid - } -} = require('ipld-dag-pb') module.exports = { command: 'new [