|
|
@ -4,8 +4,8 @@ define([
|
|
|
|
'/common/curve.js',
|
|
|
|
'/common/curve.js',
|
|
|
|
'/common/common-hash.js',
|
|
|
|
'/common/common-hash.js',
|
|
|
|
'/common/common-realtime.js'
|
|
|
|
'/common/common-realtime.js'
|
|
|
|
// '/bower_components/marked/marked.min.js'
|
|
|
|
|
|
|
|
], function ($, Crypto, Curve, Hash, Realtime) {
|
|
|
|
], function ($, Crypto, Curve, Hash, Realtime) {
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
var Msg = {
|
|
|
|
var Msg = {
|
|
|
|
inputs: [],
|
|
|
|
inputs: [],
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -37,7 +37,6 @@ define([
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// TODO make this async
|
|
|
|
|
|
|
|
var getFriend = function (proxy, pubkey) {
|
|
|
|
var getFriend = function (proxy, pubkey) {
|
|
|
|
if (pubkey === proxy.curvePublic) {
|
|
|
|
if (pubkey === proxy.curvePublic) {
|
|
|
|
var data = createData(proxy);
|
|
|
|
var data = createData(proxy);
|
|
|
@ -96,8 +95,7 @@ define([
|
|
|
|
var pendingRequests = [];
|
|
|
|
var pendingRequests = [];
|
|
|
|
|
|
|
|
|
|
|
|
/* Used to accept friend requests within apps other than /contacts/ */
|
|
|
|
/* Used to accept friend requests within apps other than /contacts/ */
|
|
|
|
// TODO move this into MSG.messenger
|
|
|
|
// TODO rename as _openGroupChannel_
|
|
|
|
// as _openGroupChannel_
|
|
|
|
|
|
|
|
Msg.addDirectMessageHandler = function (common) {
|
|
|
|
Msg.addDirectMessageHandler = function (common) {
|
|
|
|
var network = common.getNetwork();
|
|
|
|
var network = common.getNetwork();
|
|
|
|
var proxy = common.getProxy();
|
|
|
|
var proxy = common.getProxy();
|
|
|
@ -239,18 +237,10 @@ define([
|
|
|
|
stack.push(f);
|
|
|
|
stack.push(f);
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// TODO openGroupChannel
|
|
|
|
/* messenger.openGroupChannel = function (hash, cb) {
|
|
|
|
messenger.openGroupChannel = function (hash, cb) {
|
|
|
|
// TODO set up infrastructure for a many to many channel
|
|
|
|
// sets up infrastructure for a one to one channel using curve cryptography
|
|
|
|
|
|
|
|
cb = cb;
|
|
|
|
cb = cb;
|
|
|
|
};
|
|
|
|
}; */
|
|
|
|
|
|
|
|
|
|
|
|
//var ready = messenger.ready = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var DEBUG = function (label) {
|
|
|
|
|
|
|
|
console.log('event:' + label);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
DEBUG = DEBUG; // FIXME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var channels = messenger.channels = {};
|
|
|
|
var channels = messenger.channels = {};
|
|
|
|
|
|
|
|
|
|
|
@ -286,10 +276,22 @@ define([
|
|
|
|
|
|
|
|
|
|
|
|
messenger.getMoreHistory = function (curvePublic, hash, count, cb) {
|
|
|
|
messenger.getMoreHistory = function (curvePublic, hash, count, cb) {
|
|
|
|
if (typeof(cb) !== 'function') { return; }
|
|
|
|
if (typeof(cb) !== 'function') { return; }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (typeof(hash) !== 'string') {
|
|
|
|
|
|
|
|
// FIXME hash is not necessarily defined.
|
|
|
|
|
|
|
|
// What does this mean?
|
|
|
|
|
|
|
|
console.error("not sure what to do here");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var chan = getChannel(curvePublic);
|
|
|
|
var chan = getChannel(curvePublic);
|
|
|
|
|
|
|
|
if (typeof(chan) === 'undefined') {
|
|
|
|
|
|
|
|
console.error("chan is undefined. we're going to have a problem here");
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var txid = common.uid();
|
|
|
|
var txid = common.uid();
|
|
|
|
initRangeRequest(txid, curvePublic, hash, cb);
|
|
|
|
initRangeRequest(txid, curvePublic, hash, cb);
|
|
|
|
// FIXME hash is not necessarily defined.
|
|
|
|
|
|
|
|
var msg = [ 'GET_HISTORY_RANGE', chan.id, {
|
|
|
|
var msg = [ 'GET_HISTORY_RANGE', chan.id, {
|
|
|
|
from: hash,
|
|
|
|
from: hash,
|
|
|
|
count: count,
|
|
|
|
count: count,
|
|
|
@ -337,13 +339,7 @@ define([
|
|
|
|
var decryptedMsg = channel.encryptor.decrypt(msg);
|
|
|
|
var decryptedMsg = channel.encryptor.decrypt(msg);
|
|
|
|
|
|
|
|
|
|
|
|
if (decryptedMsg === null) {
|
|
|
|
if (decryptedMsg === null) {
|
|
|
|
// console.error('unable to decrypt message');
|
|
|
|
return void console.error("Failed to decrypt message");
|
|
|
|
// console.error('potentially meant for yourself');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// message failed to parse, meaning somebody sent it to you but
|
|
|
|
|
|
|
|
// encrypted it with the wrong key, or you're sending a message to
|
|
|
|
|
|
|
|
// yourself in a different tab.
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!decryptedMsg) {
|
|
|
|
if (!decryptedMsg) {
|
|
|
@ -379,35 +375,27 @@ define([
|
|
|
|
var orderMessages = function (curvePublic, new_messages, sig) {
|
|
|
|
var orderMessages = function (curvePublic, new_messages, sig) {
|
|
|
|
var channel = getChannel(curvePublic);
|
|
|
|
var channel = getChannel(curvePublic);
|
|
|
|
var messages = channel.messages;
|
|
|
|
var messages = channel.messages;
|
|
|
|
var idx;
|
|
|
|
|
|
|
|
messages.some(function (msg, i) {
|
|
|
|
|
|
|
|
if (msg.sig === sig) { idx = i; }
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (typeof(idx) !== 'undefined') {
|
|
|
|
|
|
|
|
//console.error('found old message at %s', idx);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
//console.error("did not find desired message");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO improve performance
|
|
|
|
// TODO improve performance, guarantee correct ordering
|
|
|
|
new_messages.reverse().forEach(function (msg) {
|
|
|
|
new_messages.reverse().forEach(function (msg) {
|
|
|
|
messages.unshift(msg);
|
|
|
|
messages.unshift(msg);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var removeFromFriendList = function (curvePublic, cb) {
|
|
|
|
|
|
|
|
if (!proxy.friends) { return; }
|
|
|
|
|
|
|
|
var friends = proxy.friends;
|
|
|
|
|
|
|
|
delete friends[curvePublic];
|
|
|
|
|
|
|
|
Realtime.whenRealtimeSyncs(common, realtime, cb);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var pushMsg = function (channel, cryptMsg) {
|
|
|
|
var pushMsg = function (channel, cryptMsg) {
|
|
|
|
var msg = channel.encryptor.decrypt(cryptMsg);
|
|
|
|
var msg = channel.encryptor.decrypt(cryptMsg);
|
|
|
|
|
|
|
|
|
|
|
|
// TODO emit new message event or something
|
|
|
|
|
|
|
|
// extension point for other apps
|
|
|
|
|
|
|
|
//console.log(msg);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var sig = cryptMsg.slice(0, 64);
|
|
|
|
var sig = cryptMsg.slice(0, 64);
|
|
|
|
if (msgAlreadyKnown(channel, sig)) { return; }
|
|
|
|
if (msgAlreadyKnown(channel, sig)) { return; }
|
|
|
|
|
|
|
|
|
|
|
|
var parsedMsg = JSON.parse(msg);
|
|
|
|
var parsedMsg = JSON.parse(msg);
|
|
|
|
|
|
|
|
var curvePublic;
|
|
|
|
if (parsedMsg[0] === Types.message) {
|
|
|
|
if (parsedMsg[0] === Types.message) {
|
|
|
|
// TODO validate messages here
|
|
|
|
// TODO validate messages here
|
|
|
|
var res = {
|
|
|
|
var res = {
|
|
|
@ -420,9 +408,7 @@ define([
|
|
|
|
curve: getCurveForChannel(channel.id),
|
|
|
|
curve: getCurveForChannel(channel.id),
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// TODO emit message event
|
|
|
|
|
|
|
|
channel.messages.push(res);
|
|
|
|
channel.messages.push(res);
|
|
|
|
|
|
|
|
|
|
|
|
eachHandler('message', function (f) {
|
|
|
|
eachHandler('message', function (f) {
|
|
|
|
f(res);
|
|
|
|
f(res);
|
|
|
|
});
|
|
|
|
});
|
|
|
@ -431,7 +417,7 @@ define([
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (parsedMsg[0] === Types.update) {
|
|
|
|
if (parsedMsg[0] === Types.update) {
|
|
|
|
if (parsedMsg[1] === proxy.curvePublic) { return; }
|
|
|
|
if (parsedMsg[1] === proxy.curvePublic) { return; }
|
|
|
|
var curvePublic = parsedMsg[1];
|
|
|
|
curvePublic = parsedMsg[1];
|
|
|
|
var newdata = parsedMsg[3];
|
|
|
|
var newdata = parsedMsg[3];
|
|
|
|
var data = getFriend(proxy, parsedMsg[1]);
|
|
|
|
var data = getFriend(proxy, parsedMsg[1]);
|
|
|
|
var types = [];
|
|
|
|
var types = [];
|
|
|
@ -448,12 +434,16 @@ define([
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (parsedMsg[0] === Types.unfriend) {
|
|
|
|
if (parsedMsg[0] === Types.unfriend) {
|
|
|
|
console.log('UNFRIEND');
|
|
|
|
curvePublic = parsedMsg[1];
|
|
|
|
removeFromFriendList(proxy, realtime, channel.friendEd, function () {
|
|
|
|
delete friends[curvePublic];
|
|
|
|
channel.wc.leave(Types.unfriend);
|
|
|
|
|
|
|
|
//channel.removeUI();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
removeFromFriendList(parsedMsg[1], function () {
|
|
|
|
|
|
|
|
channel.wc.leave(Types.unfriend);
|
|
|
|
|
|
|
|
eachHandler('unfriend', function (f) {
|
|
|
|
|
|
|
|
f=f; // FIXME
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
|
|
|
|
console.log('unfriend');
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -479,13 +469,13 @@ define([
|
|
|
|
channel.wc.bcast(cryptMsg).then(function () {
|
|
|
|
channel.wc.bcast(cryptMsg).then(function () {
|
|
|
|
// TODO send event
|
|
|
|
// TODO send event
|
|
|
|
//channel.refresh();
|
|
|
|
//channel.refresh();
|
|
|
|
eachHandler('update', function (f) {
|
|
|
|
|
|
|
|
f(myData, myData.curvePublic);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}, function (err) {
|
|
|
|
}, function (err) {
|
|
|
|
console.error(err);
|
|
|
|
console.error(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
eachHandler('update', function (f) {
|
|
|
|
|
|
|
|
f(myData, myData.curvePublic);
|
|
|
|
|
|
|
|
});
|
|
|
|
friends.me = myData;
|
|
|
|
friends.me = myData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
@ -596,21 +586,43 @@ define([
|
|
|
|
messenger.removeFriend = function (curvePublic, cb) {
|
|
|
|
messenger.removeFriend = function (curvePublic, cb) {
|
|
|
|
if (typeof(cb) !== 'function') { throw new Error('NO_CALLBACK'); }
|
|
|
|
if (typeof(cb) !== 'function') { throw new Error('NO_CALLBACK'); }
|
|
|
|
var data = getFriend(proxy, curvePublic);
|
|
|
|
var data = getFriend(proxy, curvePublic);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!data) {
|
|
|
|
|
|
|
|
// friend is not valid
|
|
|
|
|
|
|
|
console.error('friend is not valid');
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var channel = channels[data.channel];
|
|
|
|
var channel = channels[data.channel];
|
|
|
|
|
|
|
|
if (!channel) {
|
|
|
|
|
|
|
|
return void cb("NO_SUCH_CHANNEL");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!network.webChannels.some(function (wc) {
|
|
|
|
|
|
|
|
return wc.id === channel.id;
|
|
|
|
|
|
|
|
})) {
|
|
|
|
|
|
|
|
console.error('bad channel: ', curvePublic);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var msg = [Types.unfriend, proxy.curvePublic, +new Date()];
|
|
|
|
var msg = [Types.unfriend, proxy.curvePublic, +new Date()];
|
|
|
|
var msgStr = JSON.stringify(msg);
|
|
|
|
var msgStr = JSON.stringify(msg);
|
|
|
|
var cryptMsg = channel.encryptor.encrypt(msgStr);
|
|
|
|
var cryptMsg = channel.encryptor.encrypt(msgStr);
|
|
|
|
|
|
|
|
|
|
|
|
// TODO emit remove_friend event?
|
|
|
|
// TODO emit remove_friend event?
|
|
|
|
channel.wc.bcast(cryptMsg).then(function () {
|
|
|
|
try {
|
|
|
|
delete friends[curvePublic];
|
|
|
|
channel.wc.bcast(cryptMsg).then(function () {
|
|
|
|
Realtime.whenRealtimeSyncs(realtime, function () {
|
|
|
|
delete friends[curvePublic];
|
|
|
|
cb();
|
|
|
|
delete channels[curvePublic];
|
|
|
|
|
|
|
|
Realtime.whenRealtimeSyncs(common, realtime, function () {
|
|
|
|
|
|
|
|
cb();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}, function (err) {
|
|
|
|
|
|
|
|
console.error(err);
|
|
|
|
|
|
|
|
cb(err);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}, function (err) {
|
|
|
|
} catch (e) {
|
|
|
|
console.error(err);
|
|
|
|
cb(e);
|
|
|
|
cb(err);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var getChannelMessagesSince = function (chan, data, keys) {
|
|
|
|
var getChannelMessagesSince = function (chan, data, keys) {
|
|
|
@ -823,8 +835,9 @@ define([
|
|
|
|
|
|
|
|
|
|
|
|
console.error(o, n, p);
|
|
|
|
console.error(o, n, p);
|
|
|
|
}).on('remove', ['friends'], function (o, p) {
|
|
|
|
}).on('remove', ['friends'], function (o, p) {
|
|
|
|
// TODO eachHandler('unfriend', function (f) { f(); });
|
|
|
|
eachHandler('unfriend', function (f) {
|
|
|
|
console.error(o, p);
|
|
|
|
f(p[1]); // TODO
|
|
|
|
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
Object.freeze(messenger);
|
|
|
|
Object.freeze(messenger);
|
|
|
|