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

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

@ -140,13 +140,36 @@
send: function(promise) {
this.trigger('pending');
return promise.then(function() {
return promise.then(function(result) {
this.trigger('done');
if (result.dataMessage) {
this.set({dataMessage: result.dataMessage});
}
this.save({sent: true});
}.bind(this)).catch(function(errors) {
this.sendSyncMessage();
}.bind(this)).catch(function(result) {
this.trigger('done');
if (result.dataMessage) {
this.set({dataMessage: result.dataMessage});
}
this.set({sent: true});
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));
},

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

Loading…
Cancel
Save