git ssb

4+

Dominic / scuttlebot



Commit e5d0b7d8bace9ec48ab12ec7a1a40872a050acad

merge multiserver

Dominic Tarr committed on 10/2/2016, 12:01:36 PM
Parent: f01447184bc4318a21262c0bed6a7a726e6e3bfe
Parent: 682c3a5400995ac0d881d88c82a8647730578ba2

Files changed

bin.jschanged
lib/util.jschanged
package.jsonchanged
plugins/gossip/index.jschanged
plugins/gossip/init.jschanged
plugins/gossip/schedule.jschanged
plugins/invite.jschanged
plugins/replicate.jschanged
plugins/plugins.jsdeleted
test/invite.jschanged
test/master.jschanged
test/server.jschanged
test/util.jschanged
test/plugins.jsdeleted
bin.jsView
@@ -34,9 +34,8 @@
3434 // special server command:
3535 // import sbot and start the server
3636
3737 var createSbot = require('./')
38- .use(require('./plugins/plugins'))
3938 .use(require('./plugins/master'))
4039 .use(require('./plugins/gossip'))
4140 .use(require('./plugins/friends'))
4241 .use(require('./plugins/replicate'))
@@ -46,11 +45,8 @@
4645 .use(require('./plugins/local'))
4746 .use(require('./plugins/logging'))
4847 .use(require('./plugins/private'))
4948
50- // add third-party plugins
51- require('./plugins/plugins').loadUserPlugins(createSbot, config)
52-
5349 // start server
5450
5551 config.keys = keys
5652 var server = createSbot(config)
@@ -146,4 +142,6 @@
146142
147143
148144
149145
146 +
147 +
lib/util.jsView
@@ -65,37 +65,5 @@
6565 a[k] = b
6666 }
6767 }
6868
69-exports.stringifyAddress = function (e) {
70- if(isString(e)) return e
71- return [e.host, e.port || DEFAULT_PORT, e.key].join(':')
72-}
7369
74-exports.parseAddress = function (e) {
75- if(isString(e)) {
76- var parts = e.split(':')
77- var id = parts.pop(), port = parts.pop(), host = parts.join(':')
78- var e = {
79- host: host,
80- port: +(port || DEFAULT_PORT),
81- key: id
82- }
83- return e
84- }
85- return e
86-}
87-
88-exports.isAddress = function (addr) {
89- return (
90- ref.isFeedId(addr.key || addr.link)
91- && isInteger(addr.port)
92- && typeof addr.host === 'string' && !!addr.host
93- )
94-}
95-
96-exports.toAddress = function (e) {
97- e = exports.parseAddress(e)
98- e.port = e.port || DEFAULT_PORT
99- e.host = e.host || 'localhost'
100- return e
101-}
package.jsonView
@@ -14,26 +14,20 @@
1414 "explain-error": "~1.0.1",
1515 "graphmitter": "^1.6.3",
1616 "ip": "^0.3.3",
1717 "level-memview": "~0.0.0",
18- "map-merge": "~1.1.0",
1918 "mdmanifest": "^1.0.4",
2019 "minimist": "^1.1.3",
2120 "mkdirp": "~0.5.0",
2221 "multiblob": "^1.10.1",
2322 "multicb": "^1.0.0",
2423 "muxrpc": "^6.1.1",
2524 "muxrpc-validation": "^2.0.0",
2625 "muxrpcli": "^1.0.0",
27- "mv": "^2.1.1",
28- "mynosql-query": "~1.0.0",
29- "nomnom": "1.8.0",
3026 "non-private-ip": "~1.1.0",
31- "observ": "~0.2.0",
3227 "observ-debounce": "^1.1.1",
3328 "on-change-network": "0.0.2",
3429 "on-wakeup": "^1.0.0",
35- "osenv": "~0.1.0",
3630 "pull-abortable": "~4.0.0",
3731 "pull-cat": "~1.1.5",
3832 "pull-file": "^0.5.0",
3933 "pull-inactivity": "~2.1.1",
@@ -46,17 +40,17 @@
4640 "pull-stream": "^3.0.0",
4741 "pull-stream-to-stream": "~1.3.0",
4842 "pull-stringify": "~1.2.2",
4943 "rimraf": "^2.4.2",
50- "secret-stack": "^2.5.0",
44 + "secret-stack": "^2.5.2",
5145 "secure-scuttlebutt": "^15.4.1",
5246 "ssb-blobs": "^0.1.6",
5347 "ssb-client": "^4.0.2",
5448 "ssb-config": "^2.0.0",
5549 "ssb-feed": "^2.2.0",
5650 "ssb-keys": "^5.1.2",
5751 "ssb-msgs": "~5.0.0",
58- "ssb-ref": "^2.3.2",
52 + "ssb-ref": "^2.6.0",
5953 "statistics": "^2.0.1",
6054 "stream-to-pull-stream": "^1.6.10",
6155 "zerr": "^1.0.0"
6256 },
plugins/gossip/index.jsView
@@ -5,8 +5,9 @@
55 var mdm = require('mdmanifest')
66 var valid = require('../../lib/validators')
77 var apidoc = require('../../lib/apidocs').gossip
88 var u = require('../../lib/util')
9 +var ref = require('ssb-ref')
910 var ping = require('pull-ping')
1011 var Stats = require('statistics')
1112 var isArray = Array.isArray
1213 var Schedule = require('./schedule')
@@ -15,8 +16,12 @@
1516 function isFunction (f) {
1617 return 'function' === typeof f
1718 }
1819
20 +function stringify(peer) {
21 + return [peer.host, peer.port, peer.key].join(':')
22 +}
23 +
1924 /*
2025 Peers : [{
2126 key: id,
2227 host: ip,
@@ -37,9 +42,9 @@
3742 },
3843 init: function (server, config) {
3944 var notify = Notify()
4045 var conf = config.gossip || {}
41- var home = u.toAddress(server.getAddress())
46 + var home = ref.parseAddress(server.getAddress())
4247
4348 //Known Peers
4449 var peers = []
4550
@@ -56,9 +61,9 @@
5661 peers: function () {
5762 return peers
5863 },
5964 get: function (addr) {
60- addr = u.toAddress(addr)
65 + addr = ref.parseAddress(addr)
6166 return u.find(peers, function (a) {
6267 return (
6368 addr.port === a.port
6469 && addr.host === a.host
@@ -66,9 +71,9 @@
6671 )
6772 })
6873 },
6974 connect: valid.async(function (addr, cb) {
70- addr = u.toAddress(addr)
75 + addr = ref.parseAddress(addr)
7176 if (!addr || typeof addr != 'object')
7277 return cb(new Error('first param must be an address'))
7378
7479 if(!addr.key) return cb(new Error('address must have ed25519 key'))
@@ -114,10 +119,10 @@
114119 return notify.listen()
115120 },
116121 //add an address to the peer table.
117122 add: valid.sync(function (addr, source) {
118- addr = u.toAddress(addr)
119- if(!u.isAddress(addr))
123 + addr = ref.parseAddress(addr)
124 + if(!ref.isAddress(addr))
120125 throw new Error('not a valid address:' + JSON.stringify(addr))
121126 // check that this is a valid address, and not pointing at self.
122127
123128 if(addr.key === home.key) return
@@ -164,9 +169,9 @@
164169 var peer = getPeer(rpc.id)
165170 //don't track clients that connect, but arn't considered peers.
166171 //maybe we should though?
167172 if(!peer) return
168- console.log('+connected', u.stringifyAddress(peer))
173 + console.log('Connected', stringify(peer))
169174 //means that we have created this connection, not received it.
170175 peer.client = !!isClient
171176 peer.state = 'connected'
172177 peer.stateChange = Date.now()
@@ -188,9 +193,9 @@
188193 )
189194 }
190195
191196 rpc.on('closed', function () {
192- console.log('-disconnected', u.stringifyAddress(peer))
197 + console.log('Disconnected', stringify(peer))
193198 //track whether we have successfully connected.
194199 //or how many failures there have been.
195200 var since = peer.stateChange
196201 peer.stateChange = Date.now()
@@ -208,20 +213,4 @@
208213 }
209214 }
210215
211216
212-
213-
214-
215-
216-
217-
218-
219-
220-
221-
222-
223-
224-
225-
226-
227-
plugins/gossip/init.jsView
@@ -1,6 +1,7 @@
11 var isArray = Array.isArray
22 var pull = require('pull-stream')
3 +var ref = require('ssb-ref')
34
45 module.exports = function (gossip, config, server) {
56
67 // populate peertable with configured seeds (mainly used in testing)
@@ -15,9 +16,10 @@
1516 type: 'pub', live: true, keys: false
1617 }),
1718 pull.drain(function (msg) {
1819 if(!msg.content.address) return
19- gossip.add(msg.content.address, 'pub')
20 + if(ref.isAddress(msg.content.address))
21 + gossip.add(msg.content.address, 'pub')
2022 })
2123 )
2224
2325 // populate peertable with announcements on the LAN multicast
plugins/gossip/schedule.jsView
@@ -124,16 +124,14 @@
124124
125125 if(connected.length > opts.quota) {
126126 return earliest(connected, connected.length - opts.quota)
127127 .forEach(function (peer) {
128- console.log('Disconnect', name, u.stringifyAddress(peer))
129128 gossip.disconnect(peer)
130129 })
131130 }
132131
133132 select(peers, ts, and(filter, isOnline), opts)
134133 .forEach(function (peer) {
135- console.log('Connect', name, u.stringifyAddress(peer))
136134 gossip.connect(peer)
137135 })
138136 }
139137
@@ -203,7 +201,4 @@
203201 exports.select = select
204202
205203
206204
207-
208-
209-
plugins/invite.jsView
@@ -26,26 +26,8 @@
2626 function isObject(o) {
2727 return o && 'object' === typeof o
2828 }
2929
30-function parseMultiServerInvite (invite) {
31- var parts = invite.split('~')
32- .map(function (e) { return e.split(':') })
33-
34- if(parts.length !== 2) return null
35- if(!/^(net|wss?)$/.test(parts[0][0])) return null
36- if(parts[1][0] !== 'shs') return null
37- if(parts[1].length !== 3) return null
38- var p2 = invite.split(':')
39- p2.pop()
40-
41- return {
42- invite: invite,
43- remote: p2.join(':'),
44- key: '@'+p2.pop()+'.ed25519'
45- }
46-}
47-
4830 module.exports = {
4931 name: 'invite',
5032 version: '1.0.0',
5133 manifest: mdm.manifest(apidoc),
@@ -84,9 +66,9 @@
8466 n = 1
8567 modern = true
8668 }
8769 var addr = server.getAddress()
88- var host = toAddress(addr).host
70 + var host = ref.parseAddress(addr).host
8971 if(!config.allowPrivate && (ip.isPrivate(host) || 'localhost' === host))
9072 return cb(new Error('Server has no public ip address, '
9173 + 'cannot create useable invitation'))
9274
@@ -112,10 +94,12 @@
11294 if(err) cb(err)
11395 else if(modern && server.ws && server.ws.getAddress) {
11496 cb(null, server.ws.getAddress()+':'+seed.toString('base64'))
11597 }
116- else
117- cb(null, addr + '~' + seed.toString('base64'))
98 + else {
99 + addr = ref.parseAddress(addr)
100 + cb(null, [addr.host, addr.port, addr.key].join(':') + '~' + seed.toString('base64'))
101 + }
118102 })
119103 }, 'number|object'),
120104 use: valid.async(function (req, cb) {
121105 var rpc = this
@@ -172,19 +156,21 @@
172156 var opts
173157 // connect to the address in the invite code
174158 // using a keypair generated from the key-seed in the invite code
175159 var modern = false
176- if(ref.isInvite(invite)) { //legacy invite
177-
178- var parts = invite.split('~')
179- opts = toAddress(parts[0])//.split(':')
180- //convert legacy code to multiserver invite code.
181- invite = 'net:'+opts.host+':'+opts.port+'~shs:'+opts.key.slice(1, -8)+':'+parts[1]
182- } else {
183- modern = true
184- opts = parseMultiServerInvite(invite)
160 + if(ref.isInvite(invite)) { //legacy ivite
161 + if(ref.isLegacyInvite(invite)) {
162 + var parts = invite.split('~')
163 + opts = ref.parseAddress(parts[0])//.split(':')
164 + //convert legacy code to multiserver invite code.
165 + invite = 'net:'+opts.host+':'+opts.port+'~shs:'+opts.key.slice(1, -8)+':'+parts[1]
166 + }
167 + else
168 + modern = true
185169 }
186170
171 + opts = ref.parseAddress(ref.parseInvite(invite).remote)
172 +
187173 ssbClient(null, {
188174 remote: invite,
189175 manifest: {invite: {use: 'async'}, getAddress: 'async'}
190176 }, function (err, rpc) {
@@ -228,6 +214,4 @@
228214 }
229215 }
230216
231217
232-
233-
plugins/replicate.jsView
@@ -5,9 +5,8 @@
55 var many = require('pull-many')
66 var Cat = require('pull-cat')
77 var Abort = require('pull-abortable')
88 var Debounce = require('observ-debounce')
9-var Observ = require('observ')
109 var mdm = require('mdmanifest')
1110 var apidoc = require('../lib/apidocs').replicate
1211
1312 var Pushable = require('pull-pushable')
@@ -217,6 +216,4 @@
217216 }
218217 }
219218
220219
221-
222-
plugins/plugins.jsView
@@ -1,224 +1,0 @@
1-var assert = require('assert')
2-var path = require('path')
3-var fs = require('fs')
4-var pull = require('pull-stream')
5-var cat = require('pull-cat')
6-var many = require('pull-many')
7-var pushable = require('pull-pushable')
8-var toPull = require('stream-to-pull-stream')
9-var spawn = require('child_process').spawn
10-var mkdirp = require('mkdirp')
11-var osenv = require('osenv')
12-var rimraf = require('rimraf')
13-var mv = require('mv')
14-var mdm = require('mdmanifest')
15-var explain = require('explain-error')
16-var valid = require('../lib/validators')
17-var apidoc = require('../lib/apidocs').plugins
18-
19-module.exports = {
20- name: 'plugins',
21- version: '1.0.0',
22- manifest: mdm.manifest(apidoc),
23- permissions: {
24- master: {allow: ['install', 'uninstall', 'enable', 'disable']}
25- },
26- init: function (server, config) {
27- var installPath = config.path
28- config.plugins = config.plugins || {}
29- mkdirp.sync(path.join(installPath, 'node_modules'))
30-
31- // helper to enable/disable plugins
32- function configPluginEnabled (b) {
33- return function (pluginName, cb) {
34- checkInstalled(pluginName, function (err) {
35- if (err) return cb(err)
36-
37- config.plugins[pluginName] = b
38- writePluginConfig(pluginName, b)
39- if (b)
40- cb(null, '\''+pluginName+'\' has been enabled. Restart Scuttlebot server to use the plugin.')
41- else
42- cb(null, '\''+pluginName+'\' has been disabled. Restart Scuttlebot server to stop using the plugin.')
43- })
44- }
45- }
46-
47- // helper to check if a plugin is installed
48- function checkInstalled (pluginName, cb) {
49- if (!pluginName || typeof pluginName !== 'string')
50- return cb(new Error('plugin name is required'))
51- var modulePath = path.join(installPath, 'node_modules', pluginName)
52- fs.stat(modulePath, function (err) {
53- if (err)
54- cb(new Error('Plugin "'+pluginName+'" is not installed.'))
55- else
56- cb()
57- })
58- }
59-
60- // write the plugin config to ~/.ssb/config
61- function writePluginConfig (pluginName, value) {
62- var cfgPath = path.join(config.path, 'config')
63- var existingConfig = {}
64-
65- // load ~/.ssb/config
66- try { existingConfig = JSON.parse(fs.readFileSync(cfgPath, 'utf-8')) }
67- catch (e) {}
68-
69- // update the plugins config
70- existingConfig.plugins = existingConfig.plugins || {}
71- existingConfig.plugins[pluginName] = value
72-
73- // write to disc
74- fs.writeFileSync(cfgPath, JSON.stringify(existingConfig, null, 2), 'utf-8')
75- }
76-
77- return {
78- install: valid.source(function (pluginName, opts) {
79- var p = pushable()
80- var dryRun = opts && opts['dry-run']
81- var from = opts && opts.from
82-
83- if (!pluginName || typeof pluginName !== 'string')
84- return pull.error(new Error('plugin name is required'))
85-
86- // pull out the version, if given
87- if (pluginName.indexOf('@') !== -1) {
88- var pluginNameSplitted = pluginName.split('@')
89- pluginName = pluginNameSplitted[0]
90- var version = pluginNameSplitted[1]
91-
92- if (version && !from)
93- from = pluginName + '@' + version
94- }
95-
96- if (!validatePluginName(pluginName))
97- return pull.error(new Error('invalid plugin name: "'+pluginName+'"'))
98-
99- // create a tmp directory to install into
100- var tmpInstallPath = path.join(osenv.tmpdir(), pluginName)
101- rimraf.sync(tmpInstallPath); mkdirp.sync(tmpInstallPath)
102-
103- // build args
104- // --global-style: dont dedup at the top level, gives proper isolation between each plugin
105- // --loglevel error: dont output warnings, because npm just whines about the lack of a package.json in ~/.ssb
106- var args = ['install', from||pluginName, '--global-style', '--loglevel', 'error']
107- if (dryRun)
108- args.push('--dry-run')
109-
110- // exec npm
111- var child = spawn('npm', args, { cwd: tmpInstallPath })
112- .on('close', function (code) {
113- if (code == 0 && !dryRun) {
114- var tmpInstallNMPath = path.join(tmpInstallPath, 'node_modules')
115- var finalInstallNMPath = path.join(installPath, 'node_modules')
116-
117- // delete plugin, if it's already there
118- rimraf.sync(path.join(finalInstallNMPath, pluginName))
119-
120- // move the plugin from the tmpdir into our install path
121- // ...using our given plugin name
122- var dirs = fs.readdirSync(tmpInstallNMPath)
123- .filter(function (name) { return name.charAt(0) !== '.' }) // filter out dot dirs, like '.bin'
124- mv(
125- path.join(tmpInstallNMPath, dirs[0]),
126- path.join(finalInstallNMPath, pluginName),
127- function (err) {
128- if (err)
129- return p.end(explain(err, '"'+pluginName+'" failed to install. See log output above.'))
130-
131- // enable the plugin
132- // - use basename(), because plugins can be installed from the FS, in which case pluginName is a path
133- var name = path.basename(pluginName)
134- config.plugins[name] = true
135- writePluginConfig(name, true)
136- p.push(new Buffer('"'+pluginName+'" has been installed. Restart Scuttlebot server to enable the plugin.\n', 'utf-8'))
137- p.end()
138- }
139- )
140- } else
141- p.end(new Error('"'+pluginName+'" failed to install. See log output above.'))
142- })
143- return cat([
144- pull.values([new Buffer('Installing "'+pluginName+'"...\n', 'utf-8')]),
145- many([toPull(child.stdout), toPull(child.stderr)]),
146- p
147- ])
148- }, 'string', 'object?'),
149- uninstall: valid.source(function (pluginName, opts) {
150- var p = pushable()
151- if (!pluginName || typeof pluginName !== 'string')
152- return pull.error(new Error('plugin name is required'))
153-
154- var modulePath = path.join(installPath, 'node_modules', pluginName)
155-
156- rimraf(modulePath, function (err) {
157- if (!err) {
158- writePluginConfig(pluginName, false)
159- p.push(new Buffer('"'+pluginName+'" has been uninstalled. Restart Scuttlebot server to disable the plugin.\n', 'utf-8'))
160- p.end()
161- } else
162- p.end(err)
163- })
164- return p
165- }, 'string', 'object?'),
166- enable: valid.async(configPluginEnabled(true), 'string'),
167- disable: valid.async(configPluginEnabled(false), 'string')
168- }
169- }
170-}
171-
172-module.exports.loadUserPlugins = function (createSbot, config) {
173- // iterate all modules
174- var nodeModulesPath = path.join(config.path, 'node_modules')
175- try {
176- console.log('Loading plugins from', nodeModulesPath)
177- fs.readdirSync(nodeModulesPath).forEach(function (filename) {
178- if (filename.charAt(0) == '.')
179- return // ignore
180- if (!config.plugins[filename])
181- return console.log('Skipping disabled plugin "'+filename+'"')
182- console.log('Loading plugin "'+filename+'"')
183-
184- try {
185- // load module
186- var plugin = require(path.join(nodeModulesPath, filename))
187-
188- // check the signature
189- assertSbotPlugin(plugin)
190-
191- // load
192- createSbot.use(plugin)
193- } catch (e) {
194- console.error('Error loading plugin "'+filename+'":', e.message)
195- }
196- })
197- } catch (e) {
198- // node_modules dne, ignore
199- }
200-}
201-
202-// predictate to check if an object appears to be a sbot plugin
203-function assertSbotPlugin (obj) {
204- // function signature:
205- if (typeof obj == 'function')
206- return
207-
208- // object signature:
209- assert(obj && typeof obj == 'object', 'module.exports must be an object')
210- assert(typeof obj.name == 'string', 'module.exports.name must be a string')
211- assert(typeof obj.version == 'string', 'module.exports.version must be a string')
212- assert(obj.manifest &&
213- typeof obj.manifest == 'object', 'module.exports.manifest must be an object')
214- assert(typeof obj.init == 'function', 'module.exports.init must be a function')
215-}
216-
217-function validatePluginName (name) {
218- if (/^[._]/.test(name))
219- return false
220- // from npm-validate-package-name:
221- if (encodeURIComponent(name) !== name)
222- return false
223- return true
224-}
test/invite.jsView
@@ -4,8 +4,9 @@
44 var explain = require('explain-error')
55 var pull = require('pull-stream')
66 var u = require('../lib/util')
77 var ssbClient = require('ssb-client')
8 +var ref = require('ssb-ref')
89
910 var createSbot = require('../')
1011 .use(require('../plugins/master'))
1112 .use(require('../plugins/invite'))
@@ -15,66 +16,8 @@
1516 function all(stream, cb) {
1617 return pull(stream, pull.collect(cb))
1718 }
1819
19-tape('test invite api', function (t) {
20-
21- var aliceKeys = ssbKeys.generate()
22-
23- var alice = createSbot({
24- temp: 'test-invite-alice', timeout: 1000,
25- allowPrivate: true,
26- keys: aliceKeys
27- })
28-
29- var bobKeys = ssbKeys.generate()
30- var bob = alice.createFeed(bobKeys) //bob
31-
32- //request a secret that with particular permissions.
33-
34- createSbot.createClient({keys: aliceKeys})
35- (alice.getAddress(), function (err, rpc) {
36- if(err) throw err
37-
38- rpc.invite.create(1, function (err, invite) {
39- if(err) throw explain(err, 'cannot create invite code')
40-
41- var parts = invite.split('~')
42- console.log(parts)
43- createSbot.createClient({seed: parts[1]})
44- (parts[0], function (err, rpc2) {
45- if(err) throw err
46-
47- rpc2.invite.use({
48- feed: bob.id
49- }, function (err, msg) {
50- if(err) throw explain(err, 'bob cannot use invite code')
51-
52- pull(
53- rpc.links({dest: bob.id, rel: 'contact', source: '@', keys: false}),
54- pull.collect(function (err, ary) {
55- if(err) throw err
56-
57- var followed = ary[0]
58- delete followed.message
59-
60- t.deepEqual(
61- ary[0],
62- {source: alice.id, dest: bob.id, rel: 'contact'}
63- )
64-
65- alice.close(true)
66- console.log('done')
67- t.end()
68-
69- })
70- )
71- })
72- })
73- })
74- })
75-})
76-
7720 tape('test invite.accept api', function (t) {
7821
7922 var alice = createSbot({
8023 temp: 'test-invite-alice2', timeout: 100,
@@ -148,11 +91,12 @@
14891 all(bob.messagesByType('pub'), function (err, ary) {
14992 if(err) throw err
15093 t.equal(ary.length, 1)
15194
95 + console.log(ary)
15296 t.deepEqual({
15397 type: 'pub',
154- address: u.toAddress(alice.address()),
98 + address: ref.parseAddress(alice.address()),
15599 }, ary[0].value.content)
156100
157101 all(bob.messagesByType('contact'), function (err, ary) {
158102 if(err) throw err
@@ -201,9 +145,13 @@
201145 alice.invite.create(1, function (err, invite) {
202146 if(err) throw err
203147
204148 // use a local ipv6 address in the invite
205- var inviteV6 = invite.replace(/^[0-9.]*/, '::1')
149 +// if(/localhost/.test(invite))
150 +
151 + var inviteV6
152 +
153 + = invite.replace(/localhost|([0-9.]*)/, '::1')
206154 console.log(inviteV6, invite)
207155
208156 bob.invite.accept(inviteV6, function (err, msg) {
209157 if(err) throw err
@@ -304,4 +252,8 @@
304252
305253
306254 })
307255
256 +
257 +
258 +
259 +
test/master.jsView
@@ -17,22 +17,8 @@
1717 keys: aliceKeys
1818 })
1919
2020 tape('connect remote master', function (t) {
21-
22- t.equal(alice.getAddress(), 'localhost:45451:'+alice.id)
23-
24- t.deepEqual(
25- util.parseAddress(alice.getAddress()), {
26- host: 'localhost',
27- port: 45451,
28- key: alice.id
29- })
30-
31- t.end()
32-})
33-
34-tape('connect remote master', function (t) {
3521 createSbot.createClient({keys: bobKeys})
3622 (alice.getAddress(), function (err, rpc) {
3723 if(err) throw err
3824 rpc.publish({
@@ -57,4 +43,5 @@
5743 })
5844 })
5945 })
6046
47 +
test/server.jsView
@@ -6,10 +6,8 @@
66 var ssbKeys = require('ssb-keys')
77
88 var u = require('./util')
99
10-var toAddr = require('../lib/util').toAddress
11-
1210 // create 3 servers
1311 // give them all pub servers (on localhost)
1412 // and get them to follow each other...
1513
@@ -93,4 +91,5 @@
9391 })
9492
9593
9694
95 +
test/util.jsView
@@ -1,5 +1,5 @@
1-var toAddress = require('../lib/util').parseAddress
1 +var ref = require('ssb-ref')
22
33 exports.follow = function (id) {
44 return {
55 type: 'contact', contact: id, following: true
@@ -18,9 +18,9 @@
1818
1919 exports.pub = function (address) {
2020 return {
2121 type: 'pub',
22- address: toAddress(address)
22 + address: ref.parseAddress(address)
2323 }
2424 }
2525
2626 exports.file = function (hash) {
@@ -28,4 +28,5 @@
2828 type: 'file',
2929 file: hash
3030 }
3131 }
32 +
test/plugins.jsView
@@ -1,195 +1,0 @@
1-var ssbKeys = require('ssb-keys')
2-var tape = require('tape')
3-var u = require('./util')
4-var pull = require('pull-stream')
5-var osenv = require('osenv')
6-var path = require('path')
7-var fs = require('fs')
8-var createSbot = require('../')
9-
10-var initialPlugins = createSbot.plugins.slice()
11-function resetSbot () {
12- createSbot.plugins = initialPlugins.slice()
13- createSbot.use(require('../plugins/plugins'))
14-}
15-
16-tape('install and load plugins', function (t) {
17-
18- var aliceKeys = ssbKeys.generate()
19- var datadirPath = path.join(osenv.tmpdir(), 'test-plugins1')
20-
21- t.test('install plugin', function (t) {
22-
23- resetSbot()
24- var sbot = createSbot({
25- path: datadirPath,
26- port: 45451, host: 'localhost',
27- keys: aliceKeys
28- })
29-
30- console.log('installing plugin...')
31- pull(
32- sbot.plugins.install('test-plugin', { from: __dirname + '/test-plugin' }),
33- pull.collect(function (err, out) {
34- if (err) throw err
35- console.log(out.map(function (b) { return b.toString('utf-8') }).join(''))
36-
37- t.ok(fs.statSync(path.join(datadirPath, 'node_modules/test-plugin')))
38-
39- sbot.close(function () {
40- t.end()
41- })
42- })
43- )
44- })
45-
46- t.test('installed and enabled plugin is loaded', function (t) {
47-
48- var config = {
49- path: datadirPath,
50- port: 45451, host: 'localhost',
51- keys: aliceKeys,
52- plugins: {
53- 'test-plugin': true
54- }
55- }
56- resetSbot()
57- require('../plugins/plugins').loadUserPlugins(createSbot, config)
58- var sbot = createSbot(config)
59-
60- t.ok(sbot.test)
61- t.ok(sbot.test.ping)
62-
63- sbot.test.ping('ping', function (err, res) {
64- if (err) throw err
65- t.equal(res, 'ping pong')
66-
67- sbot.close(function () {
68- t.end()
69- })
70- })
71- })
72-
73- t.test('installed and disabled plugin is not loaded', function (t) {
74-
75- var config = {
76- path: datadirPath,
77- port: 45451, host: 'localhost',
78- keys: aliceKeys,
79- plugins: {
80- 'test-plugin': false
81- }
82- }
83- resetSbot()
84- require('../plugins/plugins').loadUserPlugins(createSbot, config)
85- var sbot = createSbot(config)
86-
87- t.equal(sbot.test, undefined)
88-
89- sbot.close(function () {
90- t.end()
91- })
92- })
93-
94- t.test('uninstall plugin', function (t) {
95-
96- resetSbot()
97- var sbot = createSbot({
98- path: datadirPath,
99- port: 45451, host: 'localhost',
100- keys: aliceKeys
101- })
102-
103- console.log('uninstalling plugin...')
104- pull(
105- sbot.plugins.uninstall('test-plugin'),
106- pull.collect(function (err, out) {
107- if (err) throw err
108- console.log(out.map(function (b) { return b.toString('utf-8') }).join(''))
109-
110- t.throws(function () { fs.statSync(path.join(datadirPath, 'node_modules/test-plugin')) })
111-
112- sbot.close(function () {
113- t.end()
114- })
115- })
116- )
117- })
118-
119- t.test('install plugin under custom name', function (t) {
120-
121- resetSbot()
122- var sbot = createSbot({
123- path: datadirPath,
124- port: 45451, host: 'localhost',
125- keys: aliceKeys
126- })
127-
128- console.log('installing plugin...')
129- pull(
130- sbot.plugins.install('my-test-plugin', { from: __dirname + '/test-plugin' }),
131- pull.collect(function (err, out) {
132- if (err) throw err
133- console.log(out.map(function (b) { return b.toString('utf-8') }).join(''))
134-
135- t.ok(fs.statSync(path.join(datadirPath, 'node_modules/my-test-plugin')))
136-
137- sbot.close(function () {
138- t.end()
139- })
140- })
141- )
142- })
143-
144- t.test('installed and enabled plugin is loaded, under custom name', function (t) {
145-
146- var config = {
147- path: datadirPath,
148- port: 45451, host: 'localhost',
149- keys: aliceKeys,
150- plugins: {
151- 'my-test-plugin': true
152- }
153- }
154- resetSbot()
155- require('../plugins/plugins').loadUserPlugins(createSbot, config)
156- var sbot = createSbot(config)
157-
158- t.ok(sbot.test)
159- t.ok(sbot.test.ping)
160-
161- sbot.test.ping('ping', function (err, res) {
162- if (err) throw err
163- t.equal(res, 'ping pong')
164-
165- sbot.close(function () {
166- t.end()
167- })
168- })
169- })
170-
171- t.test('uninstall plugin under custom name', function (t) {
172-
173- resetSbot()
174- var sbot = createSbot({
175- path: datadirPath,
176- port: 45451, host: 'localhost',
177- keys: aliceKeys
178- })
179-
180- console.log('uninstalling plugin...')
181- pull(
182- sbot.plugins.uninstall('my-test-plugin'),
183- pull.collect(function (err, out) {
184- if (err) throw err
185- console.log(out.map(function (b) { return b.toString('utf-8') }).join(''))
186-
187- t.throws(function () { fs.statSync(path.join(datadirPath, 'node_modules/my-test-plugin')) })
188-
189- sbot.close(function () {
190- t.end()
191- })
192- })
193- )
194- })
195-})

Built with git-ssb-web