Let the application layer send sync messages

Previously, libtextsecure would send a sync message automatically
when appropriate. This fails if any recipient has a key conflict
or if our network connection fails mid-send.

Instead, when appropriate, return a the DataMessage encoded as an array
buffer for later syncing. This lets the application choose when to send
it, which we now do after any successful send to a recipient, rather
than after all recipients are successfully sent to.

Eventually we should move the DataMessage protobuf construction and
group sending logic to the application layer entirely, in which case
we wouldn't need libtextsecure to construct the sync message either.

Fixes #408
pull/749/head
lilia 10 years ago
parent 5c37c3d6ce
commit 07702c4ee5

@ -37334,13 +37334,14 @@ MessageSender.prototype = {
}.bind(this)); }.bind(this));
}, },
sendSyncMessage: function(message, timestamp, destination) { sendSyncMessage: function(encodedDataMessage, timestamp, destination) {
var myNumber = textsecure.storage.user.getNumber(); var myNumber = textsecure.storage.user.getNumber();
var myDevice = textsecure.storage.user.getDeviceId(); var myDevice = textsecure.storage.user.getDeviceId();
if (myDevice != 1) { if (myDevice != 1) {
var dataMessage = textsecure.protobuf.DataMessage.decode(encodedDataMessage);
var sentMessage = new textsecure.protobuf.SyncMessage.Sent(); var sentMessage = new textsecure.protobuf.SyncMessage.Sent();
sentMessage.timestamp = timestamp; sentMessage.timestamp = timestamp;
sentMessage.message = message; sentMessage.message = dataMessage;
if (destination) { if (destination) {
sentMessage.destination = destination; sentMessage.destination = destination;
} }
@ -37348,7 +37349,6 @@ MessageSender.prototype = {
syncMessage.sent = sentMessage; syncMessage.sent = sentMessage;
var contentMessage = new textsecure.protobuf.Content(); var contentMessage = new textsecure.protobuf.Content();
contentMessage.syncMessage = syncMessage; contentMessage.syncMessage = syncMessage;
return this.sendIndividualProto(myNumber, contentMessage, Date.now()); return this.sendIndividualProto(myNumber, contentMessage, Date.now());
} }
}, },
@ -37393,12 +37393,13 @@ MessageSender.prototype = {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
this.sendMessageProto(timestamp, numbers, proto, function(res) { this.sendMessageProto(timestamp, numbers, proto, function(res) {
res.dataMessage = proto.toArrayBuffer();
if (res.errors.length > 0) if (res.errors.length > 0)
reject(res); reject(res);
else else
resolve(res); resolve(res);
}); }.bind(this));
}.bind(this)).then(this.sendSyncMessage.bind(this, proto, timestamp)); }.bind(this));
}, },
sendMessageToNumber: function(number, messageText, attachments, timestamp) { sendMessageToNumber: function(number, messageText, attachments, timestamp) {
@ -37407,8 +37408,12 @@ MessageSender.prototype = {
return Promise.all(attachments.map(this.makeAttachmentPointer.bind(this))).then(function(attachmentsArray) { return Promise.all(attachments.map(this.makeAttachmentPointer.bind(this))).then(function(attachmentsArray) {
proto.attachments = attachmentsArray; proto.attachments = attachmentsArray;
return this.sendIndividualProto(number, proto, timestamp).then(function() { return this.sendIndividualProto(number, proto, timestamp).then(function(res) {
return this.sendSyncMessage(proto, timestamp, number); res.dataMessage = proto.toArrayBuffer();
return res;
}.bind(this)).catch(function(res) {
res.dataMessage = proto.toArrayBuffer();
throw res;
}.bind(this)); }.bind(this));
}.bind(this)); }.bind(this));
}, },
@ -37573,6 +37578,7 @@ textsecure.MessageSender = function(url, username, password, attachment_server_u
this.setGroupName = sender.setGroupName .bind(sender); this.setGroupName = sender.setGroupName .bind(sender);
this.setGroupAvatar = sender.setGroupAvatar .bind(sender); this.setGroupAvatar = sender.setGroupAvatar .bind(sender);
this.leaveGroup = sender.leaveGroup .bind(sender); this.leaveGroup = sender.leaveGroup .bind(sender);
this.sendSyncMessage = sender.sendSyncMessage .bind(sender);
}; };
textsecure.MessageSender.prototype = { textsecure.MessageSender.prototype = {

@ -98,6 +98,9 @@
sent_at : now, sent_at : now,
received_at : now received_at : now
}); });
if (this.isPrivate()) {
message.set({destination: this.id});
}
message.save(); message.save();
this.save({ this.save({

@ -140,13 +140,36 @@
send: function(promise) { send: function(promise) {
this.trigger('pending'); this.trigger('pending');
return promise.then(function() { return promise.then(function(result) {
this.trigger('done'); this.trigger('done');
if (result.dataMessage) {
this.set({dataMessage: result.dataMessage});
}
this.save({sent: true}); this.save({sent: true});
}.bind(this)).catch(function(errors) { this.sendSyncMessage();
}.bind(this)).catch(function(result) {
this.trigger('done'); this.trigger('done');
if (result.dataMessage) {
this.set({dataMessage: result.dataMessage});
}
this.set({sent: true}); this.set({sent: true});
this.saveErrors(result.errors); this.saveErrors(result.errors);
if (result.successfulNumbers.length > 0) {
this.sendSyncMessage();
}
}.bind(this));
},
sendSyncMessage: function() {
var dataMessage = this.get('dataMessage');
if (this.get('synced') || !dataMessage) {
return;
}
textsecure.messaging.sendSyncMessage(
dataMessage, this.get('sent_at'), this.get('destination')
).then(function() {
this.save({synced: true, dataMessage: null});
}.bind(this)); }.bind(this));
}, },

@ -66,13 +66,14 @@ MessageSender.prototype = {
}.bind(this)); }.bind(this));
}, },
sendSyncMessage: function(message, timestamp, destination) { sendSyncMessage: function(encodedDataMessage, timestamp, destination) {
var myNumber = textsecure.storage.user.getNumber(); var myNumber = textsecure.storage.user.getNumber();
var myDevice = textsecure.storage.user.getDeviceId(); var myDevice = textsecure.storage.user.getDeviceId();
if (myDevice != 1) { if (myDevice != 1) {
var dataMessage = textsecure.protobuf.DataMessage.decode(encodedDataMessage);
var sentMessage = new textsecure.protobuf.SyncMessage.Sent(); var sentMessage = new textsecure.protobuf.SyncMessage.Sent();
sentMessage.timestamp = timestamp; sentMessage.timestamp = timestamp;
sentMessage.message = message; sentMessage.message = dataMessage;
if (destination) { if (destination) {
sentMessage.destination = destination; sentMessage.destination = destination;
} }
@ -80,7 +81,6 @@ MessageSender.prototype = {
syncMessage.sent = sentMessage; syncMessage.sent = sentMessage;
var contentMessage = new textsecure.protobuf.Content(); var contentMessage = new textsecure.protobuf.Content();
contentMessage.syncMessage = syncMessage; contentMessage.syncMessage = syncMessage;
return this.sendIndividualProto(myNumber, contentMessage, Date.now()); return this.sendIndividualProto(myNumber, contentMessage, Date.now());
} }
}, },
@ -125,12 +125,13 @@ MessageSender.prototype = {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
this.sendMessageProto(timestamp, numbers, proto, function(res) { this.sendMessageProto(timestamp, numbers, proto, function(res) {
res.dataMessage = proto.toArrayBuffer();
if (res.errors.length > 0) if (res.errors.length > 0)
reject(res); reject(res);
else else
resolve(res); resolve(res);
}); }.bind(this));
}.bind(this)).then(this.sendSyncMessage.bind(this, proto, timestamp)); }.bind(this));
}, },
sendMessageToNumber: function(number, messageText, attachments, timestamp) { sendMessageToNumber: function(number, messageText, attachments, timestamp) {
@ -139,8 +140,12 @@ MessageSender.prototype = {
return Promise.all(attachments.map(this.makeAttachmentPointer.bind(this))).then(function(attachmentsArray) { return Promise.all(attachments.map(this.makeAttachmentPointer.bind(this))).then(function(attachmentsArray) {
proto.attachments = attachmentsArray; proto.attachments = attachmentsArray;
return this.sendIndividualProto(number, proto, timestamp).then(function() { return this.sendIndividualProto(number, proto, timestamp).then(function(res) {
return this.sendSyncMessage(proto, timestamp, number); res.dataMessage = proto.toArrayBuffer();
return res;
}.bind(this)).catch(function(res) {
res.dataMessage = proto.toArrayBuffer();
throw res;
}.bind(this)); }.bind(this));
}.bind(this)); }.bind(this));
}, },
@ -305,6 +310,7 @@ textsecure.MessageSender = function(url, username, password, attachment_server_u
this.setGroupName = sender.setGroupName .bind(sender); this.setGroupName = sender.setGroupName .bind(sender);
this.setGroupAvatar = sender.setGroupAvatar .bind(sender); this.setGroupAvatar = sender.setGroupAvatar .bind(sender);
this.leaveGroup = sender.leaveGroup .bind(sender); this.leaveGroup = sender.leaveGroup .bind(sender);
this.sendSyncMessage = sender.sendSyncMessage .bind(sender);
}; };
textsecure.MessageSender.prototype = { textsecure.MessageSender.prototype = {

Loading…
Cancel
Save