Skip to content

Commit 10efe1a

Browse files
authored
Merge pull request #32 from ssbc/exclude-keep-readkeys
Keep readKeys when excluding
2 parents ec8d533 + 4b73f1e commit 10efe1a

File tree

5 files changed

+51
-6
lines changed

5 files changed

+51
-6
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ on the `sbot.box2` namespace:
7272
- `key` must be a buffer. The key can then be used for decrypting messages from the group, and if picked with `pickGroupWriteKey`, as a "recp" to encrypt messages to the group. Note that the keys are not persisted in this module.
7373
- `scheme` _String_ - scheme of that encryption key (optional, there is only one option at the moment which we default to)
7474
- `root` _MessageId_ the id of the `group/init` message
75-
- `excludeGroupInfo(groupId, cb)`: Removes group info from a groupId, for instance if you or someone else has excluded you from one. Getting info about it will only return `{ excluded: true }`. Returns a promise if cb isn't provided.
75+
- `excludeGroupInfo(groupId, cb)`: Removes the writeKey from a groupId and marks the group as excluded. Useful for instance if you or someone else has excluded you from the group. Getting info about the group will return the old group info minus the `writeKey` and plus an `excluded` field set to `true`. Returns a promise if cb isn't provided.
7676
- `listGroupIds({ live, excluded }) => PullStream<groupIds>`: Returns a pull stream of all groupIds whose messages you're able to decrypt. If `live` is true then it returns a pull stream with all previous but also all future group ids. If `excluded` is true then it returns only excluded groups (groups you've been excluded from) instead of only non-excluded groups.
7777
- `pickGroupWriteKey(groupId, pickedKey, cb)`: Picks one of the group's current read keys to be the group's write key. The picked key needs to exactly match one of the read keys. Returns a promise if cb isn't provided.
7878
- `groupId`: cloaked message id or uri encoded group id.

format.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,9 @@ function makeEncryptionFormat() {
291291
const authorBFE = BFE.encode(authorId)
292292
const previousBFE = BFE.encode(opts.previous)
293293

294-
const groupKeys = keyring.group
295-
.listSync()
294+
const groups = keyring.group.listSync()
295+
const excludedGroups = keyring.group.listSync({ excluded: true })
296+
const groupKeys = [...groups, ...excludedGroups]
296297
.map(keyring.group.get)
297298
.map((groupInfo) => groupInfo.readKeys)
298299
.flat()

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"pull-defer": "^0.2.3",
2020
"pull-stream": "^3.6.14",
2121
"ssb-bfe": "^3.7.0",
22-
"ssb-keyring": "^5.3.0",
22+
"ssb-keyring": "^5.3.2",
2323
"ssb-private-group-keys": "^1.1.1",
2424
"ssb-ref": "^2.16.0",
2525
"ssb-uri2": "^2.4.1"

test/index.js

+39
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,45 @@ test('decrypt as group recipient', (t) => {
138138
})
139139
})
140140

141+
test('decrypt as group recipient, still works after exclusion', (t) => {
142+
const box2 = Box2()
143+
const keys = ssbKeys.generate(null, 'alice', 'buttwoo-v1')
144+
145+
box2.setup({ keys }, () => {
146+
const groupId = '%Lihvp+fMdt5CihjbOY6eZc0qCe0eKsrN2wfgXV2E3PM=.cloaked'
147+
box2.addGroupInfo(groupId, {
148+
key: Buffer.from(
149+
'30720d8f9cbf37f6d7062826f6decac93e308060a8aaaa77e6a4747f40ee1a76',
150+
'hex'
151+
),
152+
})
153+
154+
const opts = {
155+
keys,
156+
content: { type: 'post', text: 'super secret' },
157+
previous: null,
158+
timestamp: 12345678900,
159+
tag: buttwoo.tags.SSB_FEED,
160+
hmacKey: null,
161+
recps: [groupId, ssbKeys.generate(null, '2').id],
162+
}
163+
164+
const plaintext = buttwoo.toPlaintextBuffer(opts)
165+
t.true(Buffer.isBuffer(plaintext), 'plaintext is a buffer')
166+
167+
const ciphertext = box2.encrypt(plaintext, opts)
168+
169+
box2.excludeGroupInfo(groupId, (err) => {
170+
if (err) t.fail(err)
171+
172+
const decrypted = box2.decrypt(ciphertext, { ...opts, author: keys.id })
173+
t.deepEqual(decrypted, plaintext, 'decrypted plaintext is the same')
174+
175+
t.end()
176+
})
177+
})
178+
})
179+
141180
test('cannot decrypt own DM after we changed our own DM keys', (t) => {
142181
const box2 = Box2()
143182
const keys = ssbKeys.generate(null, 'alice', 'buttwoo-v1')

test/tribes.js

+7-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const SecretStack = require('secret-stack')
1212
const caps = require('ssb-caps')
1313
const ref = require('ssb-ref')
1414
const pull = require('pull-stream')
15+
const { keySchemes } = require('private-group-spec')
1516

1617
function readyDir(dir) {
1718
rimraf.sync(dir)
@@ -369,8 +370,12 @@ test('You can exclude info from a group', async (t) => {
369370

370371
t.deepEquals(
371372
groupInfo,
372-
{ excluded: true },
373-
'excluding group info just leaves excluded: true'
373+
{
374+
readKeys: [{ key: testkey, scheme: keySchemes.private_group }],
375+
root: testRoot,
376+
excluded: true,
377+
},
378+
'excluding group info removes writeKey and adds excluded: true'
374379
)
375380

376381
const listNotExcluded = await pull(

0 commit comments

Comments
 (0)