Files: 87a65d74fc19501dc9c07b90c48108364bce60f3 / index.js
3253 bytesRaw
1 | |
2 | var path = require('path') |
3 | var ssbKeys = require('ssb-keys') |
4 | var explain = require('explain-error') |
5 | var path = require('path') |
6 | var fs = require('fs') |
7 | |
8 | var MultiServer = require('multiserver') |
9 | var WS = require('multiserver/plugins/ws') |
10 | var Net = require('multiserver/plugins/net') |
11 | var Onion = require('multiserver/plugins/onion') |
12 | var Shs = require('multiserver/plugins/shs') |
13 | |
14 | var muxrpc = require('muxrpc') |
15 | var pull = require('pull-stream') |
16 | var ssbHash = require('pull-hash/ext/ssb') |
17 | var multicb = require('multicb') |
18 | |
19 | function toSodiumKeys(keys) { |
20 | if(!keys || !keys.public) return null |
21 | return { |
22 | publicKey: |
23 | new Buffer(keys.public.replace('.ed25519',''), 'base64'), |
24 | secretKey: |
25 | new Buffer(keys.private.replace('.ed25519',''), 'base64'), |
26 | } |
27 | } |
28 | |
29 | function fixAddBlob(add) { |
30 | return function (hash, cb) { |
31 | if (typeof hash === 'function') cb = hash, hash = null |
32 | var done = multicb({ pluck: 1, spread: true }) |
33 | var sink = pull( |
34 | ssbHash(done()), |
35 | add(hash, done()) |
36 | ) |
37 | done(cb) |
38 | return sink |
39 | } |
40 | } |
41 | |
42 | //load cap from config instead! |
43 | var cap = '1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s=' |
44 | |
45 | var createConfig = require('ssb-config/inject') |
46 | |
47 | module.exports = function (keys, opts, cb) { |
48 | var config |
49 | if (typeof keys == 'function') { |
50 | cb = keys |
51 | keys = null |
52 | opts = null |
53 | } |
54 | else if (typeof opts == 'function') { |
55 | cb = opts |
56 | opts = keys |
57 | keys = null |
58 | } |
59 | if(typeof opts === 'string' || opts == null || !keys) |
60 | config = createConfig((typeof opts === 'string' ? opts : null) || process.env.ssb_appname) |
61 | else if(opts && 'object' === typeof opts) |
62 | config = opts |
63 | |
64 | keys = keys || ssbKeys.loadOrCreateSync(path.join(config.path, 'secret')) |
65 | opts = opts || {} |
66 | |
67 | var appKey = new Buffer((opts.caps && opts.caps.shs) || cap, 'base64') |
68 | |
69 | var remote |
70 | if(opts.remote) |
71 | remote = opts.remote |
72 | else { |
73 | var host = opts.host || 'localhost' |
74 | var port = opts.port || config.port || 8008 |
75 | var key = opts.key || keys.id |
76 | |
77 | var protocol = 'net:' |
78 | if (host.endsWith(".onion")) |
79 | protocol = 'onion:' |
80 | remote = protocol+host+':'+port+'~shs:'+key.substring(1).replace('.ed25519', '') |
81 | } |
82 | |
83 | var manifest = opts.manifest || (function () { |
84 | try { |
85 | return JSON.parse(fs.readFileSync( |
86 | path.join(config.path, 'manifest.json') |
87 | )) |
88 | } catch (err) { |
89 | throw explain(err, 'could not load manifest file') |
90 | } |
91 | })() |
92 | |
93 | var shs = Shs({ |
94 | keys: toSodiumKeys(keys), |
95 | appKey: opts.appKey || appKey, |
96 | |
97 | //no client auth. we can't receive connections anyway. |
98 | auth: function (cb) { cb(null, false) }, |
99 | timeout: config.timers && config.timers.handshake || 3000 |
100 | }) |
101 | |
102 | var ms = MultiServer([ |
103 | [Net({}), shs], |
104 | [Onion({}), shs], |
105 | [WS({}), shs] |
106 | ]) |
107 | |
108 | ms.client(remote, function (err, stream) { |
109 | if(err) return cb(explain(err, 'could not connect to sbot')) |
110 | var sbot = muxrpc(manifest, false)() |
111 | sbot.id = '@'+stream.remote.toString('base64')+'.ed25519' |
112 | if (sbot.blobs && sbot.blobs.add) sbot.blobs.add = fixAddBlob(sbot.blobs.add) |
113 | pull(stream, sbot.createStream(), stream) |
114 | config.keys = keys |
115 | cb(null, sbot, config) |
116 | }) |
117 | } |
118 | |
119 |
Built with git-ssb-web