fix tests and make it work with encryption & sigs

This commit is contained in:
Manuel Araoz 2014-08-04 15:43:38 -03:00
parent 93a227316e
commit 3977dc8443
5 changed files with 92 additions and 74 deletions

View File

@ -9,15 +9,16 @@ module.exports.init = function(io_ext) {
ios = io_ext; ios = io_ext;
ios.sockets.on('connection', function(socket) { ios.sockets.on('connection', function(socket) {
socket.on('subscribe', function(topic) { socket.on('subscribe', function(topic) {
console.log('subscribe ' + topic);
socket.join(topic); socket.join(topic);
}); });
socket.on('message', function(m) { socket.on('message', function(m) {
mdb.addMessage(m, m.from, m.to, function(err) { mdb.addMessage(m, function(err) {
if (err) throw err; // TODO: handle if (err) throw err; // TODO: handle
}); });
}); });
}); });
mdb.on('message', broadcastMessage);
}; };
module.exports.broadcastTx = function(tx) { module.exports.broadcastTx = function(tx) {
@ -60,14 +61,9 @@ module.exports.broadcastSyncInfo = function(historicSync) {
ios.sockets.in('sync').emit('status', historicSync); ios.sockets.in('sync').emit('status', historicSync);
}; };
module.exports.broadcastMessage = function(from, to, ts, message) { var broadcastMessage = module.exports.broadcastMessage = function(message) {
if (ios) { if (ios) {
console.log('sending message '+to); ios.sockets.in(message.to).emit('message', message);
ios.sockets.in(to).emit('message', {
from: from,
payload: message,
ts: ts
});
} }
} }

View File

@ -67,41 +67,44 @@
var AuthMessage = bitcore.AuthMessage; var AuthMessage = bitcore.AuthMessage;
var Buffer = bitcore.Buffer; var Buffer = bitcore.Buffer;
// show message
var show = function(msg) {
$('#messages').append($('<li>').text(msg.from+':' + JSON.stringify(msg.payload)));
};
// generate new identity // generate new identity
var pk = Key.generateSync(); var pk = Key.generateSync();
var pubkey = pk.public.toString('hex'); var pubkey = pk.public.toString('hex');
$('#pubkey').text('Your key: '+pubkey); $('#pubkey').text('Your key: '+pubkey);
// show message
var show = function(from, text) {
$('#messages').append($('<li>').text(from+': ' + text));
};
// send chat handler // send chat handler
$('form').submit(function() $('form').submit(function(e)
{ {
e.preventDefault();
var text = $('#m').val() var text = $('#m').val()
if (text.length === 0) { if (text.length === 0) {
return false; return;
} }
var otherPubkey = $('#other').val(); var otherPubkey = $('#other').val();
var data = AuthMessage.encode(otherPubkey, pk, new Buffer(text)); var data = AuthMessage.encode(otherPubkey, pk, text);
data.to = otherPubkey;
socket.emit('message', data); socket.emit('message', data);
data.from = 'You'; show('You', text);
show(data);
$('#m').val(''); $('#m').val('');
return false; return;
}); });
// receive chat handler // receive chat handler
socket.emit('subscribe', pubkey); socket.emit('subscribe', pubkey);
socket.on('message', function(msg) socket.on('message', function(msg)
{ {
show(msg); try {
var data = AuthMessage.decode(pk, msg);
} catch(e) {
alert(e);
}
show(msg.pubkey, data.payload);
}); });
}); });
</script> </script>

View File

@ -8,10 +8,10 @@ var async = require('async');
var logger = require('./logger').logger; var logger = require('./logger').logger;
var util = require('util'); var util = require('util');
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var sockets = require('../app/controllers/socket.js');
var microtime = require('microtime'); var microtime = require('microtime');
var bitcore = require('bitcore'); var bitcore = require('bitcore');
var AuthMessage = bitcore.AuthMessage; var AuthMessage = bitcore.AuthMessage;
var preconditions = require('preconditions').singleton();
var MESSAGE_PREFIX = 'msg-'; // msg-<sin1>-<sin2> => <message> var MESSAGE_PREFIX = 'msg-'; // msg-<sin1>-<sin2> => <message>
@ -37,13 +37,13 @@ util.inherits(MessageDb, EventEmitter);
MessageDb.prototype.initEvents = function() { MessageDb.prototype.initEvents = function() {
if (db) return; if (db) return;
var self = this;
this.db.on('put', function(key, value) { this.db.on('put', function(key, value) {
var spl = key.split('-'); var data = {};
var from = spl[1]; data.key = key;
var to = spl[2]; data.value = value;
var ts = spl[3]; var message = MessageDb.fromStorage(data);
var message = value; self.emit('message', message);
sockets.broadcastMessage(from, to, ts, message);
}); });
this.db.on('ready', function() { this.db.on('ready', function() {
//console.log('Database ready!'); //console.log('Database ready!');
@ -55,49 +55,58 @@ MessageDb.prototype.close = function(cb) {
}; };
var messageKey = function(from, to, ts) { var messageKey = function(pubkey, to, ts) {
if (!ts) ts = Math.round(microtime.now()); if (!ts) ts = Math.round(microtime.now());
return MESSAGE_PREFIX + from.toString() + '-' + to.toString() + '-' + ts; return MESSAGE_PREFIX + pubkey.toString() + '-' + to.toString() + '-' + ts;
}; };
MessageDb.prototype.addMessage = function(m, from, to, cb) { MessageDb.prototype.addMessage = function(m, cb) {
if (!this.authenticate(m)) { if (!this.authenticate(m)) {
cb(new Error('Authentication failed')); cb(new Error('Authentication failed'));
return; return;
} }
var key = messageKey(from, to); var key = messageKey(m.pubkey, m.to);
var value = m; var value = m;
this.db.put(key, value, cb); this.db.put(key, value, cb);
}; };
MessageDb.prototype.authenticate = function(m) { MessageDb.prototype.authenticate = function(m) {
preconditions.checkArgument(m.pubkey);
preconditions.checkArgument(m.sig);
preconditions.checkArgument(m.encrypted);
var frompubkey = new Buffer(m.pubkey, 'hex'); var frompubkey = new Buffer(m.pubkey, 'hex');
var sig = new Buffer(m.sig, 'hex'); var sig = new Buffer(m.sig, 'hex');
var encrypted = new Buffer(m.encrypted, 'hex'); var encrypted = new Buffer(m.encrypted, 'hex');
return AuthMessage._verify(frompubkey, sig, encrypted); return AuthMessage._verify(frompubkey, sig, encrypted);
}; };
MessageDb.prototype.getMessages = function(from, to, lower_ts, upper_ts, cb) { MessageDb.fromStorage = function(data) {
var spl = data.key.split('-');
var pubkey = spl[1];
var to = spl[2];
var ts = +spl[3];
var message = data.value;
message.ts = ts;
message.to = to;
return message;
};
MessageDb.prototype.getMessages = function(pubkey, to, lower_ts, upper_ts, cb) {
var list = []; var list = [];
var opts = { var opts = {
end: messageKey(from, to, lower_ts), end: messageKey(pubkey, to, lower_ts),
start: messageKey(from, to, upper_ts), start: messageKey(pubkey, to, upper_ts),
// limit: limit, TODO // limit: limit, TODO
reverse: true, reverse: true,
}; };
db.createReadStream(opts) db.createReadStream(opts)
.on('data', function(data) { .on('data', function(data) {
var spl = data.key.split('-'); var message = MessageDb.fromStorage(data);
var from = spl[1]; list.push(message);
var to = spl[2];
var ts = +spl[3];
list.push({
ts: ts,
message: data.value,
});
}) })
.on('error', function(err) { .on('error', function(err) {
return cb(err); return cb(err);

View File

@ -51,24 +51,25 @@
"start": "node node_modules/grunt-cli/bin/grunt" "start": "node node_modules/grunt-cli/bin/grunt"
}, },
"dependencies": { "dependencies": {
"bitcore": "git://github.com/bitpay/bitcore.git#4d8af75ae9916984c52ee2eda1870d5980656341",
"base58-native": "0.1.2",
"async": "*", "async": "*",
"base58-native": "0.1.2",
"bignum": "*",
"bitcore": "git://github.com/bitpay/bitcore.git#4d8af75ae9916984c52ee2eda1870d5980656341",
"bufferput": "git://github.com/bitpay/node-bufferput.git",
"buffertools": "*",
"commander": "*",
"express": "~3.4.7",
"glob": "*",
"leveldown": "*", "leveldown": "*",
"levelup": "*", "levelup": "*",
"glob": "*",
"soop": "=0.1.5",
"commander": "*",
"bignum": "*",
"winston": "*",
"express": "~3.4.7",
"buffertools": "*",
"should": "~2.1.1",
"socket.io": "~1.0.4",
"moment": "~2.5.0", "moment": "~2.5.0",
"preconditions": "^1.0.7",
"should": "~2.1.1",
"sinon": "~1.7.3", "sinon": "~1.7.3",
"xmlhttprequest": "~1.6.0", "socket.io": "~1.0.4",
"bufferput": "git://github.com/bitpay/node-bufferput.git" "soop": "=0.1.5",
"winston": "*",
"xmlhttprequest": "~1.6.0"
}, },
"devDependencies": { "devDependencies": {
"chai": "*", "chai": "*",

View File

@ -4,12 +4,14 @@ var chai = require('chai');
var should = chai.should; var should = chai.should;
var expect = chai.expect; var expect = chai.expect;
var MessageDb = require('../lib/MessageDb');
var bitcore = require('bitcore');
var SIN = bitcore.SIN;
var levelup = require('levelup'); var levelup = require('levelup');
var memdown = require('memdown'); var memdown = require('memdown');
var microtime = require('microtime'); var microtime = require('microtime');
var MessageDb = require('../lib/MessageDb');
var bitcore = require('bitcore');
var SIN = bitcore.SIN;
var Key = bitcore.Key;
var AuthMessage = bitcore.AuthMessage;
describe('MessageDb', function() { describe('MessageDb', function() {
var opts = { var opts = {
@ -28,18 +30,23 @@ describe('MessageDb', function() {
var mdb = MessageDb.default(); var mdb = MessageDb.default();
expect(mdb).to.exist; expect(mdb).to.exist;
}); });
var from = new SIN(new Buffer('dadbad00', 'hex')); var fpk = Key.generateSync();
var to = new SIN(new Buffer('bacacafe', 'hex')); var tpk = Key.generateSync();
var message = { var from = fpk.public.toString('hex');
var to = tpk.public.toString('hex');
var messageData = {
a: 1, a: 1,
b: 2 b: 2
}; };
var message2 = {}; var messageData2 = {};
var message3 = ['a', 'b']; var messageData3 = ['a', 'b'];
var message = AuthMessage.encode(to, fpk, messageData);
var message2 = AuthMessage.encode(to, fpk, messageData2);
var message3 = AuthMessage.encode(to, fpk, messageData3);
it('should be able to add and read a message', function(done) { it('should be able to add and read a message', function(done) {
var mdb = new MessageDb(opts); var mdb = new MessageDb(opts);
var lower_ts = microtime.now(); var lower_ts = microtime.now();
mdb.addMessage(message, from, to, function(err) { mdb.addMessage(message, function(err) {
expect(err).to.not.exist; expect(err).to.not.exist;
var upper_ts = microtime.now(); var upper_ts = microtime.now();
mdb.getMessages(from, to, lower_ts, upper_ts, function(err, messages) { mdb.getMessages(from, to, lower_ts, upper_ts, function(err, messages) {
@ -47,7 +54,7 @@ describe('MessageDb', function() {
messages.length.should.equal(1); messages.length.should.equal(1);
messages[0].ts.should.be.below(upper_ts); messages[0].ts.should.be.below(upper_ts);
messages[0].ts.should.be.above(lower_ts); messages[0].ts.should.be.above(lower_ts);
var m = messages[0].message; var m = AuthMessage.decode(tpk, messages[0]).payload;
m.a.should.equal(1); m.a.should.equal(1);
m.b.should.equal(2); m.b.should.equal(2);
done(); done();
@ -57,23 +64,25 @@ describe('MessageDb', function() {
it('should be able to add many messages and read them', function(done) { it('should be able to add many messages and read them', function(done) {
var mdb = new MessageDb(opts); var mdb = new MessageDb(opts);
var lower_ts = microtime.now(); var lower_ts = microtime.now();
mdb.addMessage(message, from, to, function(err) { mdb.addMessage(message, function(err) {
expect(err).to.not.exist; expect(err).to.not.exist;
mdb.addMessage(message2, from, to, function(err) { mdb.addMessage(message2, function(err) {
expect(err).to.not.exist; expect(err).to.not.exist;
var upper_ts = microtime.now(); var upper_ts = microtime.now();
setTimeout(function() { setTimeout(function() {
mdb.addMessage(message3, from, to, function(err) { mdb.addMessage(message3, function(err) {
expect(err).to.not.exist; expect(err).to.not.exist;
mdb.getMessages(from, to, lower_ts, upper_ts, function(err, messages) { mdb.getMessages(from, to, lower_ts, upper_ts, function(err, messages) {
expect(err).to.not.exist; expect(err).to.not.exist;
messages.length.should.equal(2); messages.length.should.equal(2);
messages[0].ts.should.be.below(upper_ts); messages[0].ts.should.be.below(upper_ts);
messages[0].ts.should.be.above(lower_ts); messages[0].ts.should.be.above(lower_ts);
JSON.stringify(messages[0].message).should.equal('{"a":1,"b":2}'); var m0 = AuthMessage.decode(tpk, messages[0]).payload;
JSON.stringify(m0).should.equal('{"a":1,"b":2}');
messages[1].ts.should.be.below(upper_ts); messages[1].ts.should.be.below(upper_ts);
messages[1].ts.should.be.above(lower_ts); messages[1].ts.should.be.above(lower_ts);
JSON.stringify(messages[1].message).should.equal('{}'); var m1 = AuthMessage.decode(tpk, messages[1]).payload;
JSON.stringify(m1).should.equal('{}');
done(); done();
}); });
}); });