Skip to content

Commit a172537

Browse files
feat: passing through onfeedauthentication hook
1 parent 8d460d1 commit a172537

File tree

3 files changed

+99
-1
lines changed

3 files changed

+99
-1
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ Creates a new SwarmNetworker that will open replication streams on the `corestor
4949
id: crypto.randomBytes(32), // A randomly-generated peer ID,
5050
keyPair: HypercoreProtocol.keyPair(), // A NOISE keypair that's used across all connections.
5151
onauthenticate: (remotePublicKey, cb) => { cb() }, // A NOISE keypair authentication hook
52+
onfeedauthenticate: (feed, remotePublicKey, cb) => { cb() }, // A NOISE protocol authentication hook per feed
5253
}
5354
```
5455

index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class CorestoreNetworker extends Nanoresource {
1818
encrypt: true,
1919
live: true,
2020
keyPair: this.keyPair,
21-
onauthenticate: opts.onauthenticate
21+
onauthenticate: opts.onauthenticate,
22+
onfeedauthenticate: opts.onfeedauthenticate
2223
}
2324

2425
this.streams = new Set()

test/all.js

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,102 @@ test('onauthentication hook', async t => {
508508
t.end()
509509
})
510510

511+
test.only('onfeedauthentication hook blocks replication in either direction', async t => {
512+
const keyPair1 = HypercoreProtocol.keyPair()
513+
const keyPair2 = HypercoreProtocol.keyPair()
514+
const { increment, done: allAuthenticationDone } = countTo(6)
515+
const passedAuthentications = {}
516+
const { networker: networker1, store: store1 } = await create({
517+
keyPair: keyPair1,
518+
onfeedauthenticate
519+
})
520+
const { networker: networker2, store: store2 } = await create({
521+
keyPair: keyPair2,
522+
onfeedauthenticate
523+
})
524+
const core1a = store1.get()
525+
await append(core1a, 'a')
526+
const core1b = store1.get()
527+
await append(core1b, 'b')
528+
const core1c = store1.get()
529+
await append(core1c, 'c')
530+
const core2a = store2.get({ key: core1a.key })
531+
const core2b = store2.get({ key: core1b.key })
532+
const core2c = store2.get({ key: core1c.key })
533+
534+
await networker1.configure(core1a.discoveryKey)
535+
await networker1.configure(core1b.discoveryKey)
536+
await networker1.configure(core1c.discoveryKey)
537+
await networker2.configure(core2a.discoveryKey)
538+
await networker2.configure(core2b.discoveryKey)
539+
await networker2.configure(core2c.discoveryKey)
540+
541+
await allAuthenticationDone
542+
await new Promise(resolve => setTimeout(resolve, 100))
543+
544+
t.equals(core2a.length, 1, 'replicated core2a')
545+
t.equals(core2b.length, 0, 'blocked replication of core2b')
546+
t.equals(core2c.length, 0, 'blocked replication of core2c')
547+
await cleanup([networker1, networker2])
548+
t.end()
549+
550+
function onfeedauthenticate (feed, peerPublicKey, cb) {
551+
const remotePeer =
552+
Buffer.compare(peerPublicKey, keyPair1.publicKey) === 0 ? 1 :
553+
Buffer.compare(peerPublicKey, keyPair2.publicKey) === 0 ? 2 :
554+
0
555+
556+
if (remotePeer === 0) {
557+
t.fail('unexpeced key:' + peerPublicKey)
558+
return
559+
}
560+
561+
const core =
562+
remotePeer === 2 ? (
563+
feed === core1a ? 'a' :
564+
feed === core1b ? 'b' :
565+
feed === core1c ? 'c' :
566+
null
567+
) :
568+
remotePeer === 1 ? (
569+
feed === core2a ? 'a' :
570+
feed === core2b ? 'b' :
571+
feed === core2c ? 'c' :
572+
null
573+
) :
574+
null
575+
576+
if (core === null) {
577+
t.fail('unexpected feed:' + feed + ' for key ' + peerPublicKey)
578+
return
579+
}
580+
const id = `core${remotePeer}${core}`
581+
const error = (id === 'core1b' || id === 'core2c') ? new Error('prevent replication') : null
582+
if (!passedAuthentications[id]) {
583+
passedAuthentications[id] = true
584+
t.pass(`${id}: ${error ? 'error': 'ok'}`)
585+
increment()
586+
}
587+
cb(error)
588+
}
589+
590+
function countTo (amount) {
591+
let counted = 0
592+
let _resolve
593+
return {
594+
done: new Promise(resolve => { _resolve = resolve }),
595+
increment: () => {
596+
counted += 1
597+
if (counted === amount) {
598+
_resolve()
599+
} else if (counted > amount) {
600+
t.fail('unexpected amount of calls')
601+
}
602+
}
603+
}
604+
}
605+
})
606+
511607
async function create (opts = {}) {
512608
if (!bootstrap) {
513609
bootstrap = dht({

0 commit comments

Comments
 (0)