UNPKG

2.66 kBJavaScriptView Raw
1var MultiServer = require('multiserver')
2var WS = require('multiserver/plugins/ws')
3var SHS = require('multiserver/plugins/shs')
4var http = require('http')
5var muxrpc = require('muxrpc')
6var pull = require('pull-stream')
7var JSONApi = require('./json-api')
8
9var cap =
10 new Buffer('1KHLiKZvAvjbY1ziZEHMXawbCEIM6qwjCDm3VYRan/s=', 'base64')
11
12function toSodiumKeys(keys) {
13 return {
14 publicKey:
15 new Buffer(keys.public.replace('.ed25519',''), 'base64'),
16 secretKey:
17 new Buffer(keys.private.replace('.ed25519',''), 'base64'),
18 }
19}
20
21var READ_AND_ADD = [ //except for add, of course
22 'get',
23 'getLatest',
24 'createLogStream',
25 'createUserStream',
26
27 'createHistoryStream',
28 'getAddress',
29
30 'links',
31
32 'blobs.add',
33 'blobs.size',
34 'blobs.has',
35 'blobs.get',
36 'blobs.changes',
37 'blobs.createWants',
38
39 'add',
40
41 'query.read',
42 'links2.read'
43]
44
45
46exports.name = 'ws'
47exports.version = require('./package.json').version
48exports.manifest = {
49 getAddress: 'sync'
50}
51
52function toId(id) {
53 if (typeof id !== 'string') {
54 return '@' + id.toString('base64') + '.ed25519' // isn't this available somewhere else?
55 } else throw new Error('toId() called on string. todo: clean this your mess.')
56}
57
58exports.init = function (sbot, config) {
59
60 var port
61 if(config.ws)
62 port = config.ws.port
63 if(!port)
64 port = 1024+(~~(Math.random()*(65536-1024)))
65
66 var layers = []
67 var server = http.createServer(JSONApi(sbot, layers)).listen(port)
68
69 function _auth (id, cb) {
70 sbot.friends.get({source: sbot.id, dest: toId(id)}, function (err, follows) {
71 if(err) return cb(err)
72 else if(follows) cb(null, {allow: READ_AND_ADD, deny: null})
73 else cb()
74 })
75 }
76
77 var ms = MultiServer([
78 [
79 WS({server: server, port: port, host: config.host || 'localhost'}),
80 SHS({
81 keys: toSodiumKeys(config.keys),
82 appKey: (config.caps && new Buffer(config.caps.shs, "base64")) || cap,
83 auth: function (id, cb) {
84 sbot.auth(toId(id), function (err, allowed) {
85 if(err || allowed) cb(err, allowed)
86 else _auth(id, cb)
87 })
88 },
89 timeout: config.timeout
90 })
91 ]
92 ])
93
94 var close = ms.server(function (stream) {
95 var manifest = sbot.getManifest()
96 var rpc = muxrpc({}, manifest)(sbot, stream.auth)
97 rpc.id = toId(stream.remote)
98 pull(stream, rpc.createStream(), stream)
99 })
100
101 //close when the server closes.
102 sbot.close.hook(function (fn, args) {
103 close()
104 fn.apply(this, args)
105 })
106
107 return {
108 getAddress: function () {
109 return ms.stringify()
110 },
111 use: function (handler) {
112 layers.push(handler)
113 }
114
115 }
116}
117
118