module.exports = function (keys, authorized) { var peer = secure(keys); authorized.push({ key: keys.public, write: true, read: true }); var auth = function (flags, name, cb) { var sec = peer(function (stream) { var key = stream.key = normalizeKey(stream.id.key.public); auth.keys[key].connections ++; sec.once('close', function () { auth.keys[key].connections --; }); cb(stream); }); sec.on('identify', function (id) { if (flags === '*') return id.accept(); var key = normalizeKey(id.key.public); var r = auth.keys[key]; if (!r) return id.reject(); var read = typeof r.read === 'boolean' ? r.read : [].concat(r.read).indexOf(name) >= 0 ; var write = typeof r.write === 'boolean' ? r.write : [].concat(r.write).indexOf(name) >= 0 ; if (!r) return id.reject(); if (/r/.test(flags) && !read) return id.reject(); if (/w/.test(flags) && !write) return id.reject(); return id.accept(); }); return sec; }; auth.keys = authorized.reduce(function (acc, r, ix) { r.index = ix; r.key = normalizeKey(r.key); r.connections = 0; acc[r.key] = r; return acc; }, {}); return auth; };
function Seaport (opts) { var self = this; if (!(this instanceof Seaport)) return new Seaport(opts); if (!opts) opts = {}; this.endpoints = []; this.services = {}; this.heartbeat = defined(opts.heartbeat, 15 * 1000); this.timeout = defined(opts.timeout, this.heartbeat * 3); this.known = {}; this.doc = this; // for legacy .doc.set() syntax, deprecated if (opts.private) { var keys = { private: opts.private, public: opts.public }; this.secure = secure(keys); if (opts.authorized) { this.authorized = opts.authorized.map(normalizeKey); } } }
var secure = require('secure-peer'); var peer = secure(require('./b.json')); var net = require('net'); var rawStream = net.connect(5000); var sec = peer(function (stream) { stream.pipe(process.stdout); stream.end('beep boop\n'); }); sec.pipe(rawStream).pipe(sec); var pubkeys = { a : require('./a.json').public }; sec.on('identify', function (id) { var key = id.key.public; console.log(key); // ... });
module.exports = function(localdb, changes, ee, config) { var connections = config.connections || {} connections.interval = connections.interval || 500 connections.tmax = connections.tmax || 500 var remotedb = multilevel.client({ "methods": { "createReadStream": { "type": "readable" }, "fetch": { "type": "async" } } }) if (config.pems) { var pems = require(config.pems) config.public = pems.public securepeer = secure(pems) } function connect(host, port) { var rawStream = net.connect(port, host, function() { ee.emit('connect') }) rawStream.on('error', function(err) { ee.emit('error', err) rawStream.end() }) if (securepeer && config.pems) { var sec = securepeer(function (stream) { replicate(stream) }) sec.pipe(rawStream).pipe(sec) sec.on('identify', function(id) { id.accept() }) } else { replicate(rawStream) } function replicate(stream) { stream.pipe(remotedb.createRpcStream()).pipe(stream) if (connections.tmax) { setTimeout(function() { ee.emit('timeout') stream.end() }, connections.tmax) } function pull(lastRecord) { var opts = { reverse: true, keys: false } if (lastRecord) { opts.end = lastRecord + '~' } var uniques = {} var ops = [] var waiting = 0 var wait remotedb .createReadStream(opts) .on('data', function(r) { if (!uniques[r.key]) { if (r.type == 'put') { waiting++ remotedb.fetch(r.key, function(err, val) { if (err) return ee.emit('error', err) ops.push({ type: 'put', key: r.key, value: val }) waiting-- }) } else if (r.type == 'del') { ops.push({ type: 'del', key: r.key }) } } }) .on('end', function() { if (waiting > 0) { wait = setInterval(function() { if (waiting == 0) { clearInterval(wait) localdb.batch(ops, function(err) { if (err) return ee.emit('error', err) ops.length = 0 }) } }, 64) } }) } var lastRecord changes.createReadStream({ reverse: true, values: false, limit: 1 }) .on('error', function(err) { ee.emit('error', err) }) .on('data', function (r) { lastRecord = r }) .on('end', function() { pull(lastRecord) }) } } function randomServer() { var servers = Object.keys(config.servers) var r = Math.random()*servers.length return servers[Math.floor(r)] } var interval = setInterval(function() { var server if (config.getServer) { server = getServer() } else { server = randomServer() } if (server) { server = server.split(':') var host = server[0] var port = parseInt(server[1], 10) connect(host, port) } }, connections.interval) return interval }