UNPKG

1.79 kBJavaScriptView Raw
1const SecretHandshake = require('secret-handshake')
2const pull = require('pull-stream')
3
4module.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 // shs is designed so that we do not _know_ who is connecting if it
26 // fails, so we probably can't add the connecting address. (unless
27 // it was client unauthorized)
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 // Seed of private key to connect with, optional.
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}