diff --git a/.eslintrc.js b/.eslintrc.js index 22dfa17..bf7549e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -13,7 +13,7 @@ module.exports = { SharedArrayBuffer: 'readonly', }, parserOptions: { - ecmaVersion: 2020, + ecmaVersion: 2021, sourceType: 'module', }, rules: { diff --git a/index.js b/index.js index 6458b0d..b3de9c6 100644 --- a/index.js +++ b/index.js @@ -503,7 +503,10 @@ module.exports = { pull.drain( (msg) => { const groupId = msg.value.content.recps[0] - ssb.box2.excludeGroupInfo(groupId, null) + ssb.box2.excludeGroupInfo(groupId, (err) => { + // prettier-ignore + if (err) return cb(clarify(err, 'Error on excluding group info after finding exclusion of ourselves')) + }) }, (err) => { // prettier-ignore diff --git a/package.json b/package.json index 3f8b89d..fd04aae 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "pull-stream": "^3.7.0", "set.prototype.difference": "^1.0.2", "ssb-bfe": "^3.7.0", - "ssb-box2": "^6.1.0", + "ssb-box2": "^7.0.0", "ssb-crut": "^4.6.2", "ssb-db2": "^6.3.3", "ssb-meta-feeds": "^0.39.0", diff --git a/test/exclude-members.test.js b/test/exclude-members.test.js index e195415..8aae0e3 100644 --- a/test/exclude-members.test.js +++ b/test/exclude-members.test.js @@ -198,7 +198,7 @@ test('Verify that you actually get excluded from a group', async (t) => { await Promise.all([alice.tribes2.start(), bob.tribes2.start()]) t.pass('tribes2 started for both alice and bob') - const [aliceId, bobId] = await getRootIds([alice, bob], t) + const [, bobId] = await getRootIds([alice, bob], t) await replicate(alice, bob) t.pass('alice and bob replicate their trees') @@ -323,7 +323,7 @@ test("If you're not the excluder nor the excludee then you should still be in th ]) t.pass('tribes2 started for everyone') - const [aliceId, bobId, carolId] = await getRootIds([alice, bob, carol], t) + const [, bobId, carolId] = await getRootIds([alice, bob, carol], t) await replicate(alice, bob) await replicate(alice, carol) @@ -450,7 +450,7 @@ test('Get added to an old epoch but still find newer epochs', async (t) => { ]) t.pass('tribes2 started for everyone') - const [aliceId, bobId, carolId] = await getRootIds([alice, bob, carol], t) + const [, bobId, carolId] = await getRootIds([alice, bob, carol], t) await replicate(alice, bob) await replicate(alice, carol) @@ -606,3 +606,88 @@ test('Can exclude a person in a group with a lot of members', async (t) => { await Promise.all(all.map((peer) => p(peer.close)(true))) }) + +test("restarting the client doesn't make us rejoin old stuff", async (t) => { + const alice = Testbot({ + keys: ssbKeys.generate(null, 'alice'), + mfSeed: Buffer.from( + '000000000000000000000000000000000000000000000000000000000000a1ce', + 'hex' + ), + }) + let bob = Testbot({ + name: 'bobrestart', + keys: ssbKeys.generate(null, 'bob'), + mfSeed: Buffer.from( + '0000000000000000000000000000000000000000000000000000000000000b0b', + 'hex' + ), + }) + + await Promise.all([alice.tribes2.start(), bob.tribes2.start()]) + + const bobRoot = await p(bob.metafeeds.findOrCreate)() + + await replicate(alice, bob).catch(t.error) + + const { id: groupId } = await alice.tribes2 + .create() + .catch((err) => t.error(err, 'alice failed to create group')) + + await alice.tribes2 + .addMembers(groupId, [bobRoot.id]) + .then(() => t.pass('added bob')) + .catch((err) => t.error(err, 'add bob fail')) + + await replicate(alice, bob).catch(t.error) + + await bob.tribes2.acceptInvite(groupId) + + await replicate(alice, bob).catch(t.error) + + await alice.tribes2 + .excludeMembers(groupId, [bobRoot.id]) + .then(() => t.pass('alice excluded bob')) + .catch((err) => t.error(err, 'remove member fail')) + + await replicate(alice, bob).catch(t.error) + + const beforeGroup = await bob.tribes2.get(groupId) + t.equals(beforeGroup.id, groupId, 'correct group id') + t.true( + beforeGroup.excluded, + "bob knows he's excluded from the group before restart" + ) + + await p(bob.close)(true).then(() => t.pass("bob's client was closed")) + bob = Testbot({ + rimraf: false, + name: 'bobrestart', + keys: ssbKeys.generate(null, 'bob'), + mfSeed: Buffer.from( + '0000000000000000000000000000000000000000000000000000000000000b0b', + 'hex' + ), + }) + t.pass('bob got a new client') + await bob.tribes2.start().then(() => t.pass('bob restarted')) + + t.true( + (await bob.tribes2.get(groupId)).excluded, + "bob knows he's excluded from the group after restart" + ) + + const list = await pull(bob.tribes2.list(), pull.collectAsPromise()) + t.equal(list.length, 0, "there aren't any groups in bob's group list anymore") + + const invites = await pull(bob.tribes2.listInvites(), pull.collectAsPromise()) + t.equal(invites.length, 0, "bob doesn't have any invites") + + await bob.tribes2 + .acceptInvite(groupId) + .then(() => t.fail("bob didn't error when trying to accept invalid invite")) + .catch(() => t.pass("bob couldn't accept old invite we were excluded from")) + + await p(alice.close)(true) + await p(bob.close)(true) +})