1 | const SecretHandshake = require('secret-handshake')
|
2 | const pull = require('pull-stream')
|
3 |
|
4 | module.exports = function Shs(opts) {
|
5 | const keys = SecretHandshake.toKeys(opts.keys || opts.seed)
|
6 | const appKey =
|
7 | typeof opts.appKey === 'string'
|
8 | ? Buffer.from(opts.appKey, 'base64')
|
9 | : opts.appKey
|
10 |
|
11 | const server = SecretHandshake.createServer(
|
12 | keys,
|
13 | opts.auth || opts.authenticate,
|
14 | appKey,
|
15 | opts.timeout
|
16 | )
|
17 | const client = SecretHandshake.createClient(keys, appKey, opts.timeout)
|
18 |
|
19 | return {
|
20 | name: 'shs',
|
21 | create(_opts) {
|
22 | return function shsTransform(stream, cb) {
|
23 | function _cb(err, stream) {
|
24 | if (err) {
|
25 |
|
26 |
|
27 |
|
28 | err.address = 'shs:'
|
29 | return cb(err)
|
30 | }
|
31 | stream.address = 'shs:' + stream.remote.toString('base64')
|
32 | cb(null, stream)
|
33 | }
|
34 | pull(
|
35 | stream.source,
|
36 | _opts && _opts.key ? client(_opts.key, _opts.seed, _cb) : server(_cb),
|
37 | stream.sink
|
38 | )
|
39 | }
|
40 | },
|
41 |
|
42 | parse(str) {
|
43 | const ary = str.split(':')
|
44 | if (ary[0] !== 'shs') return null
|
45 | let seed = undefined
|
46 |
|
47 | if (ary.length > 2) {
|
48 | seed = Buffer.from(ary[2], 'base64')
|
49 | if (seed.length !== 32) return null
|
50 | }
|
51 | const key = Buffer.from(ary[1], 'base64')
|
52 | if (key.length !== 32) return null
|
53 | return { key: key, seed: seed }
|
54 | },
|
55 |
|
56 | stringify() {
|
57 | if (!keys) return
|
58 | return 'shs:' + keys.publicKey.toString('base64')
|
59 | },
|
60 | publicKey: keys && keys.publicKey,
|
61 | }
|
62 | }
|