Added new protos for online broadcast messages, added db hits for getting friends, local server now instantiated on the window, now sending online broadcast messages when the local server starts

pull/157/head
Beaudan 6 years ago
parent 637ee12ade
commit b417edfc9b

@ -90,6 +90,7 @@ module.exports = {
updateConversation, updateConversation,
removeConversation, removeConversation,
getAllConversations, getAllConversations,
getAllFriendIds,
getAllConversationIds, getAllConversationIds,
getAllPrivateConversations, getAllPrivateConversations,
getAllGroupsInvolvingId, getAllGroupsInvolvingId,
@ -1280,6 +1281,14 @@ async function getAllConversations() {
return map(rows, row => jsonToObject(row.json)); return map(rows, row => jsonToObject(row.json));
} }
async function getAllFriendIds() {
// TODO: Maybe don't have this hardcoded to 4 (friends status in the enum)
const rows = await db.all(
'SELECT id FROM conversations WHERE friendRequestStatus = 4 ORDER BY id ASC;'
);
return map(rows, row => row.id);
}
async function getAllConversationIds() { async function getAllConversationIds() {
const rows = await db.all('SELECT id FROM conversations ORDER BY id ASC;'); const rows = await db.all('SELECT id FROM conversations ORDER BY id ASC;');
return map(rows, row => row.id); return map(rows, row => row.id);

@ -1,6 +1,7 @@
{ {
"serverUrl": "random.snode", "serverUrl": "random.snode",
"cdnUrl": "random.snode", "cdnUrl": "random.snode",
"localServerPort": "8081",
"messageServerPort": "8080", "messageServerPort": "8080",
"swarmServerPort": "8079", "swarmServerPort": "8079",
"disableAutoUpdate": false, "disableAutoUpdate": false,

@ -120,6 +120,7 @@ module.exports = {
_removeConversations, _removeConversations,
getAllConversations, getAllConversations,
getAllFriendIds,
getAllConversationIds, getAllConversationIds,
getAllPrivateConversations, getAllPrivateConversations,
getAllGroupsInvolvingId, getAllGroupsInvolvingId,
@ -721,6 +722,14 @@ async function _removeConversations(ids) {
await channels.removeConversation(ids); await channels.removeConversation(ids);
} }
async function getAllFriendIds() {
const ids = (await channels.getAllFriendIds()).map(c =>
setifyProperty(c, 'swarmNodes')
);
return ids;
}
async function getAllConversations({ ConversationCollection }) { async function getAllConversations({ ConversationCollection }) {
const conversations = await channels.getAllConversations(); const conversations = await channels.getAllConversations();

@ -8,6 +8,45 @@
return sendEmptyMessage(pubKey, true); return sendEmptyMessage(pubKey, true);
} }
async function broadcastOnlineStatus() {
const friendKeys = await window.Signal.Data.getAllFriendIds();
friendKeys.forEach(pubKey => {
sendOnlineBroadcastMessage(pubKey)
});
}
async function sendOnlineBroadcastMessage(pubKey) {
const onlineBroadcastMessage = new textsecure.protobuf.OnlineBroadcastMessage({
snappAddress: 'testAddress',
port: parseInt(window.localServerPort, 10),
timestamp: Date.now(),
});
const content = new textsecure.protobuf.Content({
onlineBroadcastMessage,
});
// will be called once the transmission succeeded or failed
const callback = res => {
if (res.errors.length > 0) {
res.errors.forEach(error => log.error(error));
} else {
log.info('Online broadcast message sent successfully');
}
};
const options = { messageType: 'onlineBroadcast' };
// Send a empty message with information about how to contact us directly
const outgoingMessage = new textsecure.OutgoingMessage(
null, // server
Date.now(), // timestamp,
[pubKey], // numbers
content, // message
true, // silent
callback, // callback
options
);
await outgoingMessage.sendToNumber(pubKey);
}
async function sendEmptyMessage(pubKey, sendContentMessage = false) { async function sendEmptyMessage(pubKey, sendContentMessage = false) {
const options = {}; const options = {};
// send an empty message. // send an empty message.
@ -52,5 +91,7 @@
window.libloki.api = { window.libloki.api = {
sendFriendRequestAccepted, sendFriendRequestAccepted,
sendEmptyMessage, sendEmptyMessage,
sendOnlineBroadcastMessage,
broadcastOnlineStatus,
}; };
})(); })();

@ -68,6 +68,7 @@ class LocalLokiServer extends EventEmitter {
// Async wrapper for http server close // Async wrapper for http server close
close() { close() {
this.removeAllListeners();
if (this.server) { if (this.server) {
return new Promise(res => { return new Promise(res => {
this.server.close(() => res()); this.server.close(() => res());

@ -23,7 +23,7 @@ function MessageReceiver(username, password, signalingKey, options = {}) {
this.username = username; this.username = username;
this.password = password; this.password = password;
this.lokiMessageAPI = window.LokiMessageAPI; this.lokiMessageAPI = window.LokiMessageAPI;
this.localServer = new window.LocalLokiServer(); this.localServer = window.LocalLokiServer;
if (!options.serverTrustRoot) { if (!options.serverTrustRoot) {
throw new Error('Server trust root is required!'); throw new Error('Server trust root is required!');
@ -82,15 +82,13 @@ MessageReceiver.prototype.extend({
} }
}); });
this.localServer.removeAllListeners();
this.localServer.on('message', this.httpPollingResource.handleMessage);
// Passing 0 as the port will automatically assign an unused port
this.localServer this.localServer
.start(0) .start(window.localServerPort)
.then(port => .then(port => {
window.log.info(`Local Server started at localhost:${port}`) window.log.info(`Local Server started at localhost:${port}`);
); window.libloki.api.broadcastOnlineStatus();
this.localServer.on('message', this.httpPollingResource.handleMessage);
});
// TODO: Rework this socket stuff to work with online messaging // TODO: Rework this socket stuff to work with online messaging
const useWebSocket = false; const useWebSocket = false;
@ -135,7 +133,7 @@ MessageReceiver.prototype.extend({
} }
if (this.localServer) { if (this.localServer) {
this.localServer.removeAllListeners(); this.localServer.removeListener('message', this.httpPollingResource.handleMessage);
this.localServer = null; this.localServer = null;
} }
}, },
@ -713,6 +711,13 @@ MessageReceiver.prototype.extend({
.then(this.unpad) .then(this.unpad)
.then(handleSessionReset); .then(handleSessionReset);
break; break;
case textsecure.protobuf.Envelope.Type.ONLINE_BROADCAST:
window.log.info('Online broadcast message from', this.getEnvelopeId(envelope));
promise = captureActiveSession()
.then(() => sessionCipher.decryptWhisperMessage(ciphertext))
.then(this.unpad)
.then(handleSessionReset);
break;
case textsecure.protobuf.Envelope.Type.FRIEND_REQUEST: { case textsecure.protobuf.Envelope.Type.FRIEND_REQUEST: {
window.log.info('friend-request message from ', envelope.source); window.log.info('friend-request message from ', envelope.source);
promise = fallBackSessionCipher promise = fallBackSessionCipher
@ -899,6 +904,9 @@ MessageReceiver.prototype.extend({
}) })
); );
}, },
handleOnlineBroadcastMessage(envelope, onlineBroadcastMessage) {
return this.removeFromCache(envelope);
},
handleDataMessage(envelope, msg) { handleDataMessage(envelope, msg) {
window.log.info('data message from', this.getEnvelopeId(envelope)); window.log.info('data message from', this.getEnvelopeId(envelope));
let p = Promise.resolve(); let p = Promise.resolve();
@ -1013,6 +1021,8 @@ MessageReceiver.prototype.extend({
envelope.source, envelope.source,
content.preKeyBundleMessage content.preKeyBundleMessage
); );
if (content.onlineBroadcastMessage)
return this.handleOnlineBroadcastMessage(envelope, content.onlineBroadcastMessage);
if (content.syncMessage) if (content.syncMessage)
return this.handleSyncMessage(envelope, content.syncMessage); return this.handleSyncMessage(envelope, content.syncMessage);
if (content.dataMessage) if (content.dataMessage)

@ -336,8 +336,13 @@ OutgoingMessage.prototype = {
dcodeIO.ByteBuffer.wrap(ciphertext.body, 'binary').toArrayBuffer() dcodeIO.ByteBuffer.wrap(ciphertext.body, 'binary').toArrayBuffer()
); );
} }
const outgoingObjectType =
this.messageType === 'onlineBroadcast'
? textsecure.protobuf.Envelope.Type.ONLINE_BROADCAST
: ciphertext.type; // FallBackSessionCipher sets this to FRIEND_REQUEST
return { return {
type: ciphertext.type, // FallBackSessionCipher sets this to FRIEND_REQUEST type: outgoingObjectType,
ourKey, ourKey,
sourceDevice: 1, sourceDevice: 1,
destinationRegistrationId: ciphertext.registrationId, destinationRegistrationId: ciphertext.registrationId,
@ -350,14 +355,18 @@ OutgoingMessage.prototype = {
const outgoingObject = outgoingObjects[0]; const outgoingObject = outgoingObjects[0];
const socketMessage = await this.wrapInWebsocketMessage(outgoingObject); const socketMessage = await this.wrapInWebsocketMessage(outgoingObject);
let ttl; let ttl;
if ( switch (outgoingObject.type) {
outgoingObject.type === case textsecure.protobuf.Envelope.Type.FRIEND_REQUEST:
textsecure.protobuf.Envelope.Type.FRIEND_REQUEST ttl = 4 * 24 * 60 * 60; // 4 days for friend request message
) { break;
ttl = 4 * 24 * 60 * 60; // 4 days for friend request message case textsecure.protobuf.Envelope.Type.ONLINE_BROADCAST:
} else { ttl = 10 * 60; // 10 minutes for online broadcast message
const hours = window.getMessageTTL() || 24; // 1 day default for any other message break;
ttl = hours * 60 * 60; default: {
const hours = window.getMessageTTL() || 24; // 1 day default for any other message
ttl = hours * 60 * 60;
break;
}
} }
await this.transmitMessage(number, socketMessage, this.timestamp, ttl); await this.transmitMessage(number, socketMessage, this.timestamp, ttl);
this.successfulNumbers[this.successfulNumbers.length] = number; this.successfulNumbers[this.successfulNumbers.length] = number;

@ -146,6 +146,7 @@ function prepareURL(pathSegments, moreKeys) {
cdnUrl: config.get('cdnUrl'), cdnUrl: config.get('cdnUrl'),
messageServerPort: config.get('messageServerPort'), messageServerPort: config.get('messageServerPort'),
swarmServerPort: config.get('swarmServerPort'), swarmServerPort: config.get('swarmServerPort'),
localServerPort: config.get('localServerPort'),
certificateAuthority: config.get('certificateAuthority'), certificateAuthority: config.get('certificateAuthority'),
environment: config.environment, environment: config.environment,
node_version: process.versions.node, node_version: process.versions.node,

@ -285,7 +285,8 @@ window.LokiMessageAPI = new LokiMessageAPI({
const { LocalLokiServer } = require('./libloki/local_loki_server'); const { LocalLokiServer } = require('./libloki/local_loki_server');
window.LocalLokiServer = LocalLokiServer; window.localServerPort = config.localServerPort;
window.LocalLokiServer = new LocalLokiServer();
window.mnemonic = require('./libloki/mnemonic'); window.mnemonic = require('./libloki/mnemonic');
const { WorkerInterface } = require('./js/modules/util_worker_interface'); const { WorkerInterface } = require('./js/modules/util_worker_interface');

@ -13,6 +13,7 @@ message Envelope {
RECEIPT = 5; RECEIPT = 5;
UNIDENTIFIED_SENDER = 6; UNIDENTIFIED_SENDER = 6;
FRIEND_REQUEST = 101; // contains prekeys + message and is using simple encryption FRIEND_REQUEST = 101; // contains prekeys + message and is using simple encryption
ONLINE_BROADCAST = 102; // Contains address and port information for p2p messaging
} }
optional Type type = 1; optional Type type = 1;
@ -35,6 +36,12 @@ message Content {
optional ReceiptMessage receiptMessage = 5; optional ReceiptMessage receiptMessage = 5;
optional TypingMessage typingMessage = 6; optional TypingMessage typingMessage = 6;
optional PreKeyBundleMessage preKeyBundleMessage = 101; optional PreKeyBundleMessage preKeyBundleMessage = 101;
optional OnlineBroadcastMessage onlineBroadcastMessage = 102;
}
message OnlineBroadcastMessage {
optional string snappAddress = 1;
optional uint32 port = 2;
} }
message PreKeyBundleMessage { message PreKeyBundleMessage {

Loading…
Cancel
Save