From 3181b27173ca9aa47940726f19d7eacb3c176739 Mon Sep 17 00:00:00 2001 From: Andre Staltz Date: Tue, 26 Jul 2022 12:05:48 +0300 Subject: [PATCH 1/3] add test coverage script --- .gitignore | 4 +++- package.json | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 426c295..91e11cd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ # SPDX-License-Identifier: Unlicense node_modules -pnpm-lock.yaml \ No newline at end of file +pnpm-lock.yaml +coverage +.nyc_output \ No newline at end of file diff --git a/package.json b/package.json index d2b7395..0efea92 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "ssb-uri2": "^2.0.0" }, "devDependencies": { + "c8": "^7.11.0", "husky": "^4.3.0", "prettier": "^2.1.2", "pretty-quick": "^3.1.0", @@ -45,7 +46,8 @@ "scripts": { "test": "tape test/*.js | tap-arc --bail", "format-code": "prettier --write \"*.js\" \"test/*.js\"", - "format-code-staged": "pretty-quick --staged --pattern \"*.js\" --pattern \"test/*.js\"" + "format-code-staged": "pretty-quick --staged --pattern \"*.js\" --pattern \"test/*.js\"", + "coverage": "c8 --reporter=lcov npm run test" }, "husky": { "hooks": { From 6fe2b67d5dfa79eef92306f1ed9066feb3e0998d Mon Sep 17 00:00:00 2001 From: Andre Staltz Date: Tue, 26 Jul 2022 12:16:25 +0300 Subject: [PATCH 2/3] update to ssb-db2 version 5.0.0 --- README.md | 3 +- api.js | 92 ++++++-------------- messages.js | 220 +++++++++++++++++------------------------------ package.json | 11 ++- query.js | 66 ++++++++------ test/api.js | 7 +- test/messages.js | 199 ++++++++++++++++++++---------------------- test/query.js | 51 +++++------ test/validate.js | 4 +- 9 files changed, 266 insertions(+), 387 deletions(-) diff --git a/README.md b/README.md index 494ed75..b078872 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,8 @@ classic `main` feed, this library will auto-link that main feed in as a "subfeed **Prerequisites:** - Requires **Node.js 10** or higher -- Requires `ssb-db2` +- Requires `ssb-db2` version 5.0 or higher +- Requires `ssb-bendy-butt` version 1.0 or higher ``` npm install --save ssb-meta-feeds diff --git a/api.js b/api.js index 0a12a83..a4b8505 100644 --- a/api.js +++ b/api.js @@ -4,7 +4,6 @@ const run = require('promisify-tuple') const debug = require('debug')('ssb:meta-feeds') -const validate = require('./validate') const alwaysTrue = () => true @@ -76,43 +75,19 @@ exports.init = function (sbot, config) { const cb = maybeCB if (!details.feedpurpose) return cb(new Error('Missing feedpurpose')) if (!details.feedformat) return cb(new Error('Missing feedformat')) - sbot.metafeeds.query.getLatest(metafeed.keys.id, (err, latest) => { - if (err) return cb(err) - const msgVal = sbot.metafeeds.messages.getMsgValAddDerived( - metafeed.keys, - latest, - details.feedpurpose, - metafeed.seed, - details.feedformat, - details.metadata - ) - - const encrypted = typeof msgVal.content === 'string' - - if (!encrypted) { - const contentSection = [msgVal.content, msgVal.contentSignature] - const validationResult = validate.validateSingle(contentSection) - if (validationResult instanceof Error) return cb(validationResult) - } - sbot.db.add(msgVal, (err, addedMsg) => { - if (err) return cb(err) - - if (encrypted) - sbot.db.get(addedMsg.key, (err, msgVal) => { - const msg = { - key: addedMsg.key, - value: msgVal, - } - cb(null, sbot.metafeeds.query.hydrateFromMsg(msg, metafeed.seed)) - }) - else { - cb( - null, - sbot.metafeeds.query.hydrateFromMsg(addedMsg, metafeed.seed) - ) - } - }) + const { keys, seed } = metafeed + const { feedpurpose, feedformat, metadata } = details + const opts = sbot.metafeeds.messages.optsForAddDerived( + keys, + feedpurpose, + seed, + feedformat, + metadata + ) + sbot.db.create(opts, (err) => { + if (err) return cb(err) + cb(null, sbot.metafeeds.query.hydrateFromCreateOpts(opts, seed)) }) } } @@ -136,31 +111,18 @@ exports.init = function (sbot, config) { } function findAndTombstone(metafeed, visit, reason, cb) { - const { getLatest } = sbot.metafeeds.query - const { getMsgValTombstone } = sbot.metafeeds.messages + const { optsForTombstone } = sbot.metafeeds.messages find(metafeed, visit, (err, found) => { if (err) return cb(err) if (!found) return cb(new Error('Cannot find subfeed to tombstone')) - getLatest(metafeed.keys.id, (err, latest) => { + optsForTombstone(metafeed.keys, found.keys, reason, (err, opts) => { if (err) return cb(err) - - getMsgValTombstone( - metafeed.keys, - latest, - found.keys, - reason, - (err, msgVal) => { - if (err) return cb(err) - - sbot.db.add(msgVal, (err, msg) => { - if (err) return cb(err) - - cb(null, true) - }) - } - ) + sbot.db.create(opts, (err, msg) => { + if (err) return cb(err) + cb(null, true) + }) }) }) } @@ -202,8 +164,8 @@ exports.init = function (sbot, config) { // Pluck relevant internal APIs const { deriveRootMetaFeedKeyFromSeed } = sbot.metafeeds.keys - const { getSeed, getAnnounces, getLatest } = sbot.metafeeds.query - const { getContentSeed, getContentAnnounce, getMsgValAddExisting } = + const { getSeed, getAnnounces } = sbot.metafeeds.query + const { optsForSeed, optsForAnnounce, optsForAddExisting } = sbot.metafeeds.messages // Ensure seed exists @@ -214,8 +176,8 @@ exports.init = function (sbot, config) { else debug('generating a seed') const seed = sbot.metafeeds.keys.generateSeed() const mfKeys = deriveRootMetaFeedKeyFromSeed(seed) - const content = getContentSeed(mfKeys.id, sbot.id, seed) - const [err2] = await run(sbot.db.publish)(content) + const opts = optsForSeed(mfKeys, sbot.id, seed) + const [err2] = await run(sbot.db.create)(opts) if (err2) return cb(err2) mf = { seed, keys: mfKeys } } else { @@ -229,9 +191,9 @@ exports.init = function (sbot, config) { if (err2 || !announcements || announcements.length === 0) { if (err2) debug('announcing meta feed on main feed because %o', err2) else debug('announcing meta feed on main feed') - const [err3, content] = await run(getContentAnnounce)(mf.keys) + const [err3, opts] = await run(optsForAnnounce)(mf.keys, config.keys) if (err3) return cb(err3) - const [err4] = await run(sbot.db.publish)(content) + const [err4] = await run(sbot.db.create)(opts) if (err4) return cb(err4) } else { debug('announce post exists on main feed') @@ -241,11 +203,9 @@ exports.init = function (sbot, config) { const [err3, added] = await run(find)(mf, (f) => f.feedpurpose === 'main') if (err3) return cb(err3) if (!added) { - const [err4, latest] = await run(getLatest)(mf.keys.id) - if (err4) return cb(err4) debug('adding main feed to root meta feed') - const msgVal = getMsgValAddExisting(mf.keys, latest, 'main', config.keys) - const [err5] = await run(sbot.db.add)(msgVal) + const opts = optsForAddExisting(mf.keys, 'main', config.keys) + const [err5] = await run(sbot.db.create)(opts) if (err5) return cb(err5) } else { debug('main feed already added to root meta feed') diff --git a/messages.js b/messages.js index 8c4994f..653a8e6 100644 --- a/messages.js +++ b/messages.js @@ -4,7 +4,6 @@ const crypto = require('crypto') const ssbKeys = require('ssb-keys') -const bb = require('ssb-bendy-butt') const { where, author, @@ -13,7 +12,7 @@ const { type, toCallback, } = require('ssb-db2/operators') -const keys = require('./keys') +const { deriveFeedKeyFromSeed } = require('./keys') // FIXME: define and use json schema @@ -21,49 +20,29 @@ const keys = require('./keys') * Low level API for generating messages */ exports.init = function init(sbot) { - function add(feedpurpose, nonce, previousMsg, subKeys, mfKeys, metadata) { - const content = nonce - ? { - type: 'metafeed/add/derived', - feedpurpose, - subfeed: subKeys.id, - metafeed: mfKeys.id, - nonce, - tangles: { - metafeed: { root: null, previous: null }, - }, - } - : { - type: 'metafeed/add/existing', - feedpurpose, - subfeed: subKeys.id, - metafeed: mfKeys.id, - tangles: { - metafeed: { root: null, previous: null }, - }, - } - - if (metadata) Object.assign(content, metadata) + function optsForAdd(mfKeys, feedKeys, nonce, feedpurpose, metadata) { + const type = nonce ? 'metafeed/add/derived' : 'metafeed/add/existing' + const content = { + type, + feedpurpose, + subfeed: feedKeys.id, + metafeed: mfKeys.id, + tangles: { + metafeed: { root: null, previous: null }, + }, + } - const sequence = previousMsg ? previousMsg.value.sequence + 1 : 1 - const previous = previousMsg ? previousMsg.key : null - const timestamp = Date.now() + if (nonce) content.nonce = nonce - if (content.recps && !sbot.box2) - throw new Error('Not able to encrypt without ssb-db2-box2 module loaded') + if (metadata) Object.assign(content, metadata) - const bbmsg = bb.encodeNew( + return { + feedFormat: 'bendybutt-v1', + keys: mfKeys, + contentKeys: feedKeys, content, - subKeys, - mfKeys, - sequence, - previous, - timestamp, - null, - content.recps ? sbot.box2.encryptBendyButt : null - ) - const msgVal = bb.decode(bbmsg) - return msgVal + encryptionFormat: 'box2', // in case metadata.recps is set + } } function getNonce() { @@ -72,70 +51,40 @@ exports.init = function init(sbot) { return { /** - * Generate a message linking an existing feed to a meta feed. `previous` - * is the previous message on the meta feed in KVT form. `metadata` is an - * optional object to be included (object spread) in `msg.value.content`. - * - * ```js - * const msg = sbot.metafeeds.messages.getMsgValAddExisting(metafeedKeys, null, 'main', mainKeys) - * ``` + * Generate opts for "ssb.db.create" to create a message to be posted on + * a metafeed linking to a new feed. + * Similar to in `deriveFeedKeyFromSeed`, `feedformat` can be either + * `bendybutt-v1` for a metafeed or `classic`. `metadata` is an optional + * object to be included (object spread) in the message `content`. */ - getMsgValAddExisting(mfKeys, previous, feedpurpose, feedKeys, metadata) { - return add(feedpurpose, undefined, previous, feedKeys, mfKeys, metadata) - }, - - /** - * Generate a message to be posted on meta feed linking feed to a meta feed. - * Similar to `deriveFeedKeyFromSeed`, `feedformat` can be either - * `bendybutt-v1` for a meta feed or `classic`. `metadata` is an optional - * object to be included (object spread) in `msg.value.content`. - * - * ```js - * const msg = sbot.metafeeds.messages.getMsgValAddDerived(metafeedKeys, null, 'main', seed, 'classic') - * ``` - */ - getMsgValAddDerived( - mfKeys, - previous, - feedpurpose, - seed, - feedformat, - metadata - ) { - if (feedformat !== 'classic' && feedformat !== 'bendybutt-v1') { - throw new Error('Unknown feed format: ' + feedformat) + optsForAddDerived(mfKeys, feedpurpose, seed, feedFormat, metadata) { + if (feedFormat !== 'classic' && feedFormat !== 'bendybutt-v1') { + throw new Error('Unknown feed format: ' + feedFormat) } const nonce = getNonce() - const feedKeys = keys.deriveFeedKeyFromSeed( + const feedKeys = deriveFeedKeyFromSeed( seed, nonce.toString('base64'), - feedformat + feedFormat ) - return add(feedpurpose, nonce, previous, feedKeys, mfKeys, metadata) + return optsForAdd(mfKeys, feedKeys, nonce, feedpurpose, metadata) + }, + + /** + * Generate opts for "ssb.db.create" to create a message linking an existing + * feed to a metafeed. `metadata` is an optional object to be included + * (object spread) in the message `.content`. + */ + optsForAddExisting(mfKeys, feedpurpose, feedKeys, metadata) { + return optsForAdd(mfKeys, feedKeys, null, feedpurpose, metadata) }, /** - * Generate a message to be posted on meta feed tombstoning a feed on a meta - * feed. `Previous` is the previous message on the meta feed in KVT form. - * - * ```js - * const previous = { - * key: '%vv/XLo8lYgFjX9sM44I5F6la2FAp6iREuZ0AVJFp0pU=.bbmsg-v1', - * value: { - * previous: '%jv9hs2es5Pkw85vSOmLvzQh4HtosbCrVjhT+fR6GPr4=.bbmsg-v1', - * // ... - * } - * } - * - * sbot.metafeeds.messages.getMsgValTombstone(metafeedKeys, previous, mainKeys, 'No longer used', (err, tombstoneMsg) => { - * sbot.db.add(tombstoneMsg, (err) => { - * console.log("main is now tombstoned on meta feed") - * }) - * }) - * ``` + * Generate opts for "ssb.db.create" to create a message to be posted on + * a metafeed tombstoning a subfeed. */ - getMsgValTombstone(mfKeys, previousMsg, feedKeys, reason, cb) { + optsForTombstone(mfKeys, feedKeys, reason, cb) { sbot.db.query( where( and( @@ -150,50 +99,33 @@ exports.init = function init(sbot) { return cb(new Error('no add message found on meta feed')) } - const content = { - type: 'metafeed/tombstone', - subfeed: feedKeys.id, - metafeed: mfKeys.id, - reason, - tangles: { - metafeed: { - root: msgs[0].key, - previous: msgs[msgs.length - 1].key, + const opts = { + feedFormat: 'bendybutt-v1', + keys: mfKeys, + contentKeys: feedKeys, + content: { + type: 'metafeed/tombstone', + subfeed: feedKeys.id, + metafeed: mfKeys.id, + reason, + tangles: { + metafeed: { + root: msgs[0].key, + previous: msgs[msgs.length - 1].key, + }, }, }, } - - const sequence = previousMsg ? previousMsg.value.sequence + 1 : 1 - const previous = previousMsg ? previousMsg.key : null - const timestamp = Date.now() - const bbmsg = bb.encodeNew( - content, - feedKeys, - mfKeys, - sequence, - previous, - timestamp - ) - const msgVal = bb.decode(bbmsg) - - cb(null, msgVal) + cb(null, opts) }) ) }, /** - * Generate the content of a message to be published on a main feed linking - * it to a meta feed. - * - * ```js - * sbot.metafeeds.messages.getContentAnnounce(metafeedKeys, (err, content) => { - * sbot.db.publish(content, (err) => { - * console.log("main feed is now linked to meta feed") - * }) - * }) - * ``` + * Generate opts for "ssb.db.create" to create a message on the main feed + * linking it to a new root metafeed. */ - getContentAnnounce(metafeedKeys, cb) { + optsForAnnounce(metafeedKeys, mainKeys, cb) { sbot.db.query( where(and(author(sbot.id), type('metafeed/announce'))), toCallback((err, msgs) => { @@ -216,28 +148,30 @@ exports.init = function init(sbot) { const signedContent = ssbKeys.signObj(metafeedKeys, content) - cb(null, signedContent) + const opts = { + keys: mainKeys, + feedFormat: 'classic', + content: signedContent, + } + + cb(null, opts) }) ) }, /** - * Generate the content of a message to save your seed value as a private - * message on a main feed. - * - * ```js - * const seedContent = sbot.metafeeds.messages.getContentSeed(metafeedKeys.id, sbot.id, seed) - * sbot.db.publish(seedContent, (err) => { - * console.log("seed has now been saved, all feed keys generated from this can be restored from the seed") - * }) - * ``` + * Generate opts for "ssb.db.create" to create a message to save your seed + * value as a private message (ssb-box) on a main feed. */ - getContentSeed(metafeedId, mainfeedId, seed) { + optsForSeed(mfKeys, mainfeedId, seed) { return { - type: 'metafeed/seed', - metafeed: metafeedId, - seed: seed.toString('hex'), recps: [mainfeedId], + encryptionFormat: 'box', + content: { + type: 'metafeed/seed', + metafeed: mfKeys.id, + seed: seed.toString('hex'), + }, } }, } diff --git a/package.json b/package.json index 0efea92..08911b4 100644 --- a/package.json +++ b/package.json @@ -23,12 +23,12 @@ "pull-cat": "^1.1.11", "pull-notify": "^0.1.1", "pull-stream": "^3.6.14", - "ssb-bendy-butt": "~0.12.5", + "ssb-bendy-butt": "^1.0.1", "ssb-bfe": "^3.3.0", - "ssb-db2": ">=3.0.0 <=4", + "ssb-db2": ">=3.0.0 <=5", "ssb-keys": "^8.4.0", "ssb-ref": "^2.16.0", - "ssb-uri2": "^2.0.0" + "ssb-uri2": "^2.0.2" }, "devDependencies": { "c8": "^7.11.0", @@ -37,11 +37,10 @@ "pretty-quick": "^3.1.0", "rimraf": "^3.0.2", "secret-stack": "^6.4.0", - "ssb-db2": "^4.2.0", - "ssb-db2-box2": "^0.4.0", + "ssb-db2": "^5.1.0", "ssb-caps": "^1.1.0", "tap-arc": "^0.3.5", - "tape": "^5.3.0" + "tape": "^5.5.3" }, "scripts": { "test": "tape test/*.js | tap-arc --bail", diff --git a/query.js b/query.js index ae2b95a..3c3212d 100644 --- a/query.js +++ b/query.js @@ -59,26 +59,7 @@ exports.init = function (sbot, config) { ) }, - /** - * Gets the latest message on the given feed, typically a meta feed, but - * other feed types work too. - */ - getLatest(feedId, cb) { - sbot.db.query( - where(author(feedId)), - paginate(1), - descending(), - toCallback((err, answer) => { - if (err) return cb(err) - const msgs = answer.results - if (msgs.length !== 1) return cb(null, null) - const msg = msgs[0] - cb(null, msg) - }) - ) - }, - - collectMetadata(msg) { + collectMetadata(content) { const metadata = {} const ignored = [ 'feedpurpose', @@ -88,20 +69,21 @@ exports.init = function (sbot, config) { 'tangles', 'type', ] - for (const key of Object.keys(msg.value.content)) { + for (const key of Object.keys(content)) { if (ignored.includes(key)) continue - metadata[key] = msg.value.content[key] + metadata[key] = content[key] } return metadata }, /** - * Gets the current state of a subfeed based on the meta feed message that + * Gets the current state of a subfeed based on the metafeed message that * "added" the subfeed */ hydrateFromMsg(msg, seed) { - const { type, feedpurpose, subfeed, nonce } = msg.value.content - const metadata = self.collectMetadata(msg) + const content = msg.value.content + const { type, feedpurpose, subfeed, nonce } = content + const metadata = self.collectMetadata(content) const feedformat = SSBURI.isBendyButtV1FeedSSBURI(subfeed) ? 'bendybutt-v1' : 'classic' @@ -124,6 +106,35 @@ exports.init = function (sbot, config) { } }, + /** + * Gets the current state of a subfeed based on an "opts" argument for + * "ssb.db.create". + */ + hydrateFromCreateOpts(opts, seed) { + const { feedpurpose, subfeed, metafeed, nonce, type } = opts.content + const feedformat = SSBURI.isBendyButtV1FeedSSBURI(subfeed) + ? 'bendybutt-v1' + : 'classic' + const existing = type === 'metadata/add/existing' + const keys = existing + ? config.keys + : sbot.metafeeds.keys.deriveFeedKeyFromSeed( + seed, + nonce.toString('base64'), + feedformat + ) + const metadata = self.collectMetadata(opts.content) + return { + metafeed, + feedformat, + feedpurpose, + subfeed, + keys, + metadata, + seed: !existing ? seed : undefined, + } + }, + /** * Gets the current state (active feeds) of a meta feed. * @@ -149,8 +160,9 @@ exports.init = function (sbot, config) { const tombstoned = validatedMsgs .filter((msg) => msg.value.content.type === 'metafeed/tombstone') .map((msg) => { - const { feedpurpose, subfeed } = msg.value.content - const metadata = self.collectMetadata(msg) + const content = msg.value.content + const { feedpurpose, subfeed } = content + const metadata = self.collectMetadata(content) return { feedpurpose, subfeed, metadata } }) diff --git a/test/api.js b/test/api.js index b5ab9d6..b44e49a 100644 --- a/test/api.js +++ b/test/api.js @@ -19,6 +19,7 @@ rimraf.sync(dir) let sbot = SecretStack({ appKey: caps.shs }) .use(require('ssb-db2')) + .use(require('ssb-bendy-butt')) .use(require('../')) .call(null, { keys: mainKey, @@ -216,6 +217,7 @@ test('restart sbot', (t) => { sbot.close(true, () => { sbot = SecretStack({ appKey: caps.shs }) .use(require('ssb-db2')) + .use(require('ssb-bendy-butt')) .use(require('../')) .call(null, { keys: mainKey, @@ -365,7 +367,7 @@ tape('findOrCreate() recps', (t) => { let sbotBox2 = SecretStack({ appKey: caps.shs }) .use(require('ssb-db2')) - .use(require('ssb-db2-box2')) + .use(require('ssb-bendy-butt')) .use(require('../')) .call(null, { keys: boxKey, @@ -377,8 +379,7 @@ tape('findOrCreate() recps', (t) => { 'hex' ) - sbotBox2.box2.addOwnDMKey(testkey) - sbotBox2.box2.setReady() + sbotBox2.box2.setOwnDMKey(testkey) sbotBox2.metafeeds.findOrCreate((err, mf) => { sbotBox2.metafeeds.findOrCreate( diff --git a/test/messages.js b/test/messages.js index 397c384..333ef0e 100644 --- a/test/messages.js +++ b/test/messages.js @@ -27,6 +27,7 @@ rimraf.sync(dir) let sbot = SecretStack({ appKey: caps.shs }) .use(require('ssb-db2')) + .use(require('ssb-bendy-butt')) .use(require('../')) .call(null, { keys: mainKey, @@ -38,23 +39,15 @@ let messages = sbot.metafeeds.messages let addMsg test('add a feed to metafeed', (t) => { - const msgVal = messages.getMsgValAddExisting( - metafeedKeys, - null, - 'main', - mainKey - ) + const opts = messages.optsForAddExisting(metafeedKeys, 'main', mainKey) - t.true( - msgVal.contentSignature.endsWith('.sig.ed25519'), - 'correct signature format' - ) - t.equal(msgVal.content.subfeed, mainKey.id, 'correct subfeed id') - t.notOk(msgVal.content.nonce, 'should have no nonce') - t.equal(msgVal.content.metafeed, metafeedKeys.id, 'correct metafeed id') + t.equal(opts.content.subfeed, mainKey.id, 'correct subfeed id') + t.notOk(opts.content.nonce, 'should have no nonce') + t.equal(opts.content.metafeed, metafeedKeys.id, 'correct metafeed id') - db.add(msgVal, (err, kv) => { - addMsg = kv + db.create(opts, (err, kvt) => { + t.error(err, 'no error') + addMsg = kvt t.end() }) }) @@ -64,109 +57,99 @@ let tombstoneMsg test('tombstone a feed in a metafeed', (t) => { const reason = 'Feed no longer used' - messages.getMsgValTombstone( - metafeedKeys, - addMsg, - mainKey, - reason, - (err, msgVal) => { - t.true( - msgVal.contentSignature.endsWith('.sig.ed25519'), - 'correct signature format' - ) - t.equal(msgVal.content.subfeed, mainKey.id, 'correct subfeed id') - t.equal(msgVal.content.tangles.metafeed.root, addMsg.key, 'correct root') - t.equal( - msgVal.content.tangles.metafeed.previous, - addMsg.key, - 'correct previous' - ) - t.equal(msgVal.content.reason, reason, 'correct reason') + messages.optsForTombstone(metafeedKeys, mainKey, reason, (err, opts) => { + t.error(err, 'no error') + t.equal(opts.content.subfeed, mainKey.id, 'correct subfeed id') + t.equal(opts.content.tangles.metafeed.root, addMsg.key, 'correct root') + t.equal( + opts.content.tangles.metafeed.previous, + addMsg.key, + 'correct previous' + ) + t.equal(opts.content.reason, reason, 'correct reason') - db.add(msgVal, (err, kv) => { - tombstoneMsg = kv - t.end() - }) - } - ) + db.create(opts, (err, kv) => { + t.error(err, 'no error') + tombstoneMsg = kv + t.end() + }) + }) }) test('second tombstone', (t) => { - const msgVal = messages.getMsgValAddDerived( - metafeedKeys, - tombstoneMsg, - 'main', - seed, - 'classic' - ) + const opts = messages.optsForAddDerived(metafeedKeys, 'main', seed, 'classic') const newMainKey = keys.deriveFeedKeyFromSeed( seed, - msgVal.content.nonce.toString('base64') + opts.content.nonce.toString('base64') ) - db.add(msgVal, (err, secondAddMsg) => { + db.create(opts, (err, secondAddMsg) => { + t.error(err, 'no error') const reason = 'Also no good' - messages.getMsgValTombstone( - metafeedKeys, - secondAddMsg, - newMainKey, - reason, - (err, msg) => { - t.true( - msg.contentSignature.endsWith('.sig.ed25519'), - 'correct signature format' - ) - t.equal(msg.content.subfeed, newMainKey.id, 'correct subfeed id') - t.equal( - msg.content.tangles.metafeed.root, - secondAddMsg.key, - 'correct root' - ) - t.equal( - msg.content.tangles.metafeed.previous, - secondAddMsg.key, - 'correct previous' - ) - t.equal(msg.content.reason, reason, 'correct reason') + messages.optsForTombstone(metafeedKeys, newMainKey, reason, (err, opts) => { + t.error(err, 'no error') + t.equal(opts.content.subfeed, newMainKey.id, 'correct subfeed id') + t.equal( + opts.content.tangles.metafeed.root, + secondAddMsg.key, + 'correct root' + ) + t.equal( + opts.content.tangles.metafeed.previous, + secondAddMsg.key, + 'correct previous' + ) + t.equal(opts.content.reason, reason, 'correct reason') - t.end() - } - ) + t.end() + }) }) }) test('metafeed announce', (t) => { - messages.getContentAnnounce(metafeedKeys, (err, content) => { - t.equal(content.metafeed, metafeedKeys.id, 'correct metafeed') - t.equal(content.tangles.metafeed.root, null, 'no root') - t.equal(content.tangles.metafeed.previous, null, 'no previous') - t.ok(content.signature, 'has a signature') - t.ok(ssbKeys.verifyObj(metafeedKeys, content), 'signature is correct') - - db.publish(content, (err, announceMsg) => { + messages.optsForAnnounce(metafeedKeys, mainKey, (err, opts) => { + t.error(err, 'no error') + t.equal(opts.content.metafeed, metafeedKeys.id, 'correct metafeed') + t.equal(opts.content.tangles.metafeed.root, null, 'no root') + t.equal(opts.content.tangles.metafeed.previous, null, 'no previous') + t.ok(opts.content.signature, 'has a signature') + t.ok(ssbKeys.verifyObj(metafeedKeys, opts.content), 'signature is correct') + + db.create(opts, (err, announceMsg) => { + t.error(err, 'no error') t.equal(validateMetafeedAnnounce(announceMsg), undefined, 'validated') // test that we fucked up somehow and need to create a new metafeed const newSeed = keys.generateSeed() const mf2Key = keys.deriveFeedKeyFromSeed(newSeed, 'metafeed') - messages.getContentAnnounce(mf2Key, (err, content) => { - t.equal(content.metafeed, mf2Key.id, 'correct metafeed') - t.equal(content.tangles.metafeed.root, announceMsg.key, 'correct root') + messages.optsForAnnounce(mf2Key, mainKey, (err, opts) => { + t.error(err, 'no error') + t.equal(opts.content.metafeed, mf2Key.id, 'correct metafeed') t.equal( - content.tangles.metafeed.previous, + opts.content.tangles.metafeed.root, + announceMsg.key, + 'correct root' + ) + t.equal( + opts.content.tangles.metafeed.previous, announceMsg.key, 'correct previous' ) - db.publish(content, (err, announceMsg2) => { + db.create(opts, (err, announceMsg2) => { // another test to make sure previous is correctly set const newSeed2 = keys.generateSeed() const mf3Key = keys.deriveFeedKeyFromSeed(newSeed2, 'metafeed') - messages.getContentAnnounce(mf3Key, (err, msg) => { - t.equal(msg.metafeed, mf3Key.id, 'correct metafeed') - t.equal(msg.tangles.metafeed.root, announceMsg.key, 'correct root') + messages.optsForAnnounce(mf3Key, mainKey, (err, opts) => { + t.error(err, 'no error') + t.equal(opts.content.metafeed, mf3Key.id, 'correct metafeed') + t.equal( + opts.content.tangles.metafeed.root, + announceMsg.key, + 'correct root' + ) t.equal( - msg.tangles.metafeed.previous, + opts.content.tangles.metafeed.previous, announceMsg2.key, 'correct previous' ) @@ -180,14 +163,15 @@ test('metafeed announce', (t) => { }) test('metafeed seed save', (t) => { - const content = messages.getContentSeed(metafeedKeys.id, sbot.id, seed) + const opts = messages.optsForSeed(metafeedKeys, sbot.id, seed) - t.equal(content.metafeed, metafeedKeys.id, 'correct metafeed') - t.equal(content.seed.length, 64, 'correct seed') - t.equal(content.recps.length, 1, 'recps for private') - t.equal(content.recps[0], sbot.id, 'correct recps') + t.equal(opts.content.metafeed, metafeedKeys.id, 'correct metafeed') + t.equal(opts.content.seed.length, 64, 'correct seed') + t.equal(opts.recps.length, 1, 'recps for private') + t.equal(opts.recps[0], sbot.id, 'correct recps') - db.publish(content, (err, msg) => { + db.create(opts, (err, msg) => { + t.error(err, 'no error') t.equal(typeof msg.value.content, 'string', 'encrypted') db.get(msg.key, (err, msgGotten) => { t.equal(msgGotten.content.seed, seed_hex, 'correct seed extracted') @@ -199,7 +183,7 @@ test('metafeed seed save', (t) => { test('recps', (t) => { let sbotBox2 = SecretStack({ appKey: caps.shs }) .use(require('ssb-db2')) - .use(require('ssb-db2-box2')) + .use(require('ssb-bendy-butt')) .use(require('../')) .call(null, { keys: mainKey, @@ -211,23 +195,22 @@ test('recps', (t) => { 'hex' ) - sbotBox2.box2.addOwnDMKey(testkey) - sbotBox2.box2.setReady() + sbotBox2.box2.setOwnDMKey(testkey) + sbotBox2.box2.addKeypair(metafeedKeys) - const msgVal = sbotBox2.metafeeds.messages.getMsgValAddExisting( + const opts = sbotBox2.metafeeds.messages.optsForAddExisting( metafeedKeys, - null, 'main', mainKey, - { - recps: [mainKey.id], - } + { recps: [mainKey.id] } ) - sbotBox2.db.add(msgVal, (err, kv) => { - t.true(kv.value.content.endsWith('.box2'), 'box2 encoded') - sbotBox2.db.get(kv.key, (err, msg) => { - t.equal(msg.content.feedpurpose, 'main') + sbotBox2.db.create(opts, (err, encryptedKVT) => { + t.error(err, 'no error') + t.true(encryptedKVT.value.content.endsWith('.box2'), 'box2 encoded') + sbotBox2.db.get(encryptedKVT.key, (err, decryptedMsgVal) => { + t.error(err, 'no error') + t.equal(decryptedMsgVal.content.feedpurpose, 'main') sbotBox2.close(t.end) }) }) diff --git a/test/query.js b/test/query.js index 98e7159..c677d19 100644 --- a/test/query.js +++ b/test/query.js @@ -27,6 +27,7 @@ const mainKey = ssbKeys.loadOrCreateSync(path.join(dir, 'secret')) let sbot = SecretStack({ appKey: caps.shs }) .use(require('ssb-db2')) + .use(require('ssb-bendy-butt')) .use(require('../')) .call(null, { keys: mainKey, @@ -38,17 +39,11 @@ let messages = sbot.metafeeds.messages let indexMsg, indexKey test('metafeed with multiple feeds', (t) => { - const classicAddMsgVal = messages.getMsgValAddExisting( - metafeedKeys, - null, - 'main', - mainKey - ) + const classicOpts = messages.optsForAddExisting(metafeedKeys, 'main', mainKey) - db.add(classicAddMsgVal, (err, m) => { - const indexAddMsgVal = messages.getMsgValAddDerived( + db.create(classicOpts, (err, m) => { + const indexAddOpts = messages.optsForAddDerived( metafeedKeys, - m, 'index', seed, 'classic', @@ -65,11 +60,11 @@ test('metafeed with multiple feeds', (t) => { indexKey = keys.deriveFeedKeyFromSeed( seed, - indexAddMsgVal.content.nonce.toString('base64'), + indexAddOpts.content.nonce.toString('base64'), 'classic' ) - db.add(indexAddMsgVal, (err, m) => { + db.create(indexAddOpts, (err, m) => { indexMsg = m sbot.metafeeds.query.hydrate(metafeedKeys.id, seed, (err, hydrated) => { t.equal(hydrated.feeds.length, 2, 'multiple feeds') @@ -97,28 +92,22 @@ test('metafeed with multiple feeds', (t) => { test('metafeed with tombstones', (t) => { const reason = 'Feed no longer used' - messages.getMsgValTombstone( - metafeedKeys, - indexMsg, - indexKey, - reason, - (err, msgVal) => { - db.add(msgVal, (err) => { - sbot.metafeeds.query.hydrate(metafeedKeys.id, seed, (err, hydrated) => { - t.equal(hydrated.feeds.length, 1, 'single feed') - t.equal(hydrated.feeds[0].feedpurpose, 'main') - t.equal(hydrated.tombstoned.length, 1, '1 tombstone') - t.equal(hydrated.tombstoned[0].subfeed, indexKey.id, 'tombstone id') - t.end() - }) + messages.optsForTombstone(metafeedKeys, indexKey, reason, (err, opts) => { + db.create(opts, (err) => { + sbot.metafeeds.query.hydrate(metafeedKeys.id, seed, (err, hydrated) => { + t.equal(hydrated.feeds.length, 1, 'single feed') + t.equal(hydrated.feeds[0].feedpurpose, 'main') + t.equal(hydrated.tombstoned.length, 1, '1 tombstone') + t.equal(hydrated.tombstoned[0].subfeed, indexKey.id, 'tombstone id') + t.end() }) - } - ) + }) + }) }) test('seed', (t) => { - const content = messages.getContentSeed(metafeedKeys.id, sbot.id, seed) - db.publish(content, (err) => { + const opts = messages.optsForSeed(metafeedKeys.id, sbot.id, seed) + db.create(opts, (err) => { sbot.metafeeds.query.getSeed((err, storedSeed) => { t.deepEqual(storedSeed, seed, 'correct seed') t.end() @@ -127,8 +116,8 @@ test('seed', (t) => { }) test('announce', (t) => { - messages.getContentAnnounce(metafeedKeys, (err, content) => { - db.publish(content, (err, publishedAnnounce) => { + messages.optsForAnnounce(metafeedKeys, mainKey, (err, opts) => { + db.create(opts, (err, publishedAnnounce) => { t.error(err, 'no err') sbot.metafeeds.query.getAnnounces((err, announcements) => { t.error(err, 'no err') diff --git a/test/validate.js b/test/validate.js index 521b018..0aa75a4 100644 --- a/test/validate.js +++ b/test/validate.js @@ -6,7 +6,7 @@ const tape = require('tape') const fs = require('fs') const mf = require('../validate') const bfe = require('ssb-bfe') -const bb = require('ssb-bendy-butt') +const bb = require('ssb-bendy-butt/format') const vec = JSON.parse( fs.readFileSync('test/testvector-metafeed-managment.json', 'utf8') @@ -28,7 +28,7 @@ function entryToContentSection(entry) { } function encodedDataToContentSection(data) { - const msg = bb.decode(data) + const msg = bb.fromNativeMsg(data) const contentSection = [msg.content, msg.contentSignature] return contentSection From ae6ed9fee37bcf833fdae26605a6901226ea04c5 Mon Sep 17 00:00:00 2001 From: Andre Staltz Date: Tue, 26 Jul 2022 12:19:09 +0300 Subject: [PATCH 3/3] bendy butt is a devDep --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 08911b4..00d0997 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,6 @@ "pull-cat": "^1.1.11", "pull-notify": "^0.1.1", "pull-stream": "^3.6.14", - "ssb-bendy-butt": "^1.0.1", "ssb-bfe": "^3.3.0", "ssb-db2": ">=3.0.0 <=5", "ssb-keys": "^8.4.0", @@ -37,6 +36,7 @@ "pretty-quick": "^3.1.0", "rimraf": "^3.0.2", "secret-stack": "^6.4.0", + "ssb-bendy-butt": "^1.0.1", "ssb-db2": "^5.1.0", "ssb-caps": "^1.1.0", "tap-arc": "^0.3.5",