Refactor outgoing identity key conflict handling
saveKeysToDeviceObject is the detector of outgoing identity key errors. Catch these key errors closer to the source by pulling the getKeysForNumber into the context of sendMessageToDevices, which lets it access registerError and the message protobuf. Previously identity key errors would be uncaught if all existing sessions with a recipient were closed/deleted, since we would preemptively fetch the new identity key. The old error handling only kicked in after a 409/410 response from the server when posting a message encrypted for a stale session. // FREEBIE
This commit is contained in:
parent
27016e1919
commit
67f25214d3
2 changed files with 72 additions and 76 deletions
|
@ -39723,34 +39723,6 @@ window.textsecure.messaging = function() {
|
|||
|
||||
var self = {};
|
||||
|
||||
//TODO: Dont hit disk for any of the key-fetching!
|
||||
function getKeysForNumber(number, updateDevices) {
|
||||
var handleResult = function(response) {
|
||||
return Promise.all(response.devices.map(function(device) {
|
||||
if (updateDevices === undefined || updateDevices.indexOf(device.deviceId) > -1)
|
||||
return textsecure.storage.devices.saveKeysToDeviceObject({
|
||||
encodedNumber: number + "." + device.deviceId,
|
||||
identityKey: response.identityKey,
|
||||
preKey: device.preKey.publicKey,
|
||||
preKeyId: device.preKey.keyId,
|
||||
signedKey: device.signedPreKey.publicKey,
|
||||
signedKeyId: device.signedPreKey.keyId,
|
||||
signedKeySignature: device.signedPreKey.signature,
|
||||
registrationId: device.registrationId
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
var promises = [];
|
||||
if (updateDevices !== undefined)
|
||||
for (var i in updateDevices)
|
||||
promises[promises.length] = TextSecureServer.getKeysForNumber(number, updateDevices[i]).then(handleResult);
|
||||
else
|
||||
return TextSecureServer.getKeysForNumber(number).then(handleResult);
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
// success_callback(server success/failure map), error_callback(error_msg)
|
||||
// message == PushMessageContentProto (NOT STRING)
|
||||
function sendMessageToDevices(timestamp, number, deviceObjectList, message, success_callback, error_callback) {
|
||||
|
@ -39882,6 +39854,40 @@ window.textsecure.messaging = function() {
|
|||
}
|
||||
};
|
||||
|
||||
function getKeysForNumber(number, updateDevices) {
|
||||
var handleResult = function(response) {
|
||||
return Promise.all(response.devices.map(function(device) {
|
||||
if (updateDevices === undefined || updateDevices.indexOf(device.deviceId) > -1)
|
||||
return textsecure.storage.devices.saveKeysToDeviceObject({
|
||||
encodedNumber: number + "." + device.deviceId,
|
||||
identityKey: response.identityKey,
|
||||
preKey: device.preKey.publicKey,
|
||||
preKeyId: device.preKey.keyId,
|
||||
signedKey: device.signedPreKey.publicKey,
|
||||
signedKeyId: device.signedPreKey.keyId,
|
||||
signedKeySignature: device.signedPreKey.signature,
|
||||
registrationId: device.registrationId
|
||||
}).catch(function(error) {
|
||||
if (error.message === "Identity key changed") {
|
||||
error = new textsecure.OutgoingIdentityKeyError(number, message.toArrayBuffer(), timestamp, error.identityKey);
|
||||
registerError(number, "Identity key changed", error);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
if (updateDevices === undefined) {
|
||||
return TextSecureServer.getKeysForNumber(number).then(handleResult);
|
||||
} else {
|
||||
var promises = [];
|
||||
for (var i in updateDevices)
|
||||
promises[promises.length] = TextSecureServer.getKeysForNumber(number, updateDevices[i]).then(handleResult);
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
}
|
||||
|
||||
var doSendMessage = function(number, devicesForNumber, recurse) {
|
||||
var groupUpdate = Promise.resolve(true);
|
||||
if (message.group && message.group.id && message.group.type != textsecure.protobuf.GroupContext.Type.QUIT)
|
||||
|
@ -39910,19 +39916,11 @@ window.textsecure.messaging = function() {
|
|||
getKeysForNumber(number, resetDevices)
|
||||
.then(reloadDevicesAndSend(number, false))
|
||||
.catch(function(error) {
|
||||
if (error.message !== "Identity key changed at session save time")
|
||||
registerError(number, "Failed to reload device keys", error);
|
||||
else {
|
||||
error = new textsecure.OutgoingIdentityKeyError(number, message.toArrayBuffer(), timestamp, e.identityKey);
|
||||
registerError(number, "Identity key changed", error);
|
||||
}
|
||||
registerError(number, "Failed to reload device keys", error);
|
||||
});
|
||||
});
|
||||
} else if (error.message !== "Identity key changed at session save time") {
|
||||
registerError(number, "Failed to create or send message", error);
|
||||
} else {
|
||||
error = new textsecure.OutgoingIdentityKeyError(number, message.toArrayBuffer(), timestamp, e.identityKey);
|
||||
registerError(number, "Identity key changed", error);
|
||||
registerError(number, "Failed to create or send message", error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -19,34 +19,6 @@ window.textsecure.messaging = function() {
|
|||
|
||||
var self = {};
|
||||
|
||||
//TODO: Dont hit disk for any of the key-fetching!
|
||||
function getKeysForNumber(number, updateDevices) {
|
||||
var handleResult = function(response) {
|
||||
return Promise.all(response.devices.map(function(device) {
|
||||
if (updateDevices === undefined || updateDevices.indexOf(device.deviceId) > -1)
|
||||
return textsecure.storage.devices.saveKeysToDeviceObject({
|
||||
encodedNumber: number + "." + device.deviceId,
|
||||
identityKey: response.identityKey,
|
||||
preKey: device.preKey.publicKey,
|
||||
preKeyId: device.preKey.keyId,
|
||||
signedKey: device.signedPreKey.publicKey,
|
||||
signedKeyId: device.signedPreKey.keyId,
|
||||
signedKeySignature: device.signedPreKey.signature,
|
||||
registrationId: device.registrationId
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
var promises = [];
|
||||
if (updateDevices !== undefined)
|
||||
for (var i in updateDevices)
|
||||
promises[promises.length] = TextSecureServer.getKeysForNumber(number, updateDevices[i]).then(handleResult);
|
||||
else
|
||||
return TextSecureServer.getKeysForNumber(number).then(handleResult);
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
// success_callback(server success/failure map), error_callback(error_msg)
|
||||
// message == PushMessageContentProto (NOT STRING)
|
||||
function sendMessageToDevices(timestamp, number, deviceObjectList, message, success_callback, error_callback) {
|
||||
|
@ -178,6 +150,40 @@ window.textsecure.messaging = function() {
|
|||
}
|
||||
};
|
||||
|
||||
function getKeysForNumber(number, updateDevices) {
|
||||
var handleResult = function(response) {
|
||||
return Promise.all(response.devices.map(function(device) {
|
||||
if (updateDevices === undefined || updateDevices.indexOf(device.deviceId) > -1)
|
||||
return textsecure.storage.devices.saveKeysToDeviceObject({
|
||||
encodedNumber: number + "." + device.deviceId,
|
||||
identityKey: response.identityKey,
|
||||
preKey: device.preKey.publicKey,
|
||||
preKeyId: device.preKey.keyId,
|
||||
signedKey: device.signedPreKey.publicKey,
|
||||
signedKeyId: device.signedPreKey.keyId,
|
||||
signedKeySignature: device.signedPreKey.signature,
|
||||
registrationId: device.registrationId
|
||||
}).catch(function(error) {
|
||||
if (error.message === "Identity key changed") {
|
||||
error = new textsecure.OutgoingIdentityKeyError(number, message.toArrayBuffer(), timestamp, error.identityKey);
|
||||
registerError(number, "Identity key changed", error);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}));
|
||||
};
|
||||
|
||||
if (updateDevices === undefined) {
|
||||
return TextSecureServer.getKeysForNumber(number).then(handleResult);
|
||||
} else {
|
||||
var promises = [];
|
||||
for (var i in updateDevices)
|
||||
promises[promises.length] = TextSecureServer.getKeysForNumber(number, updateDevices[i]).then(handleResult);
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
}
|
||||
|
||||
var doSendMessage = function(number, devicesForNumber, recurse) {
|
||||
var groupUpdate = Promise.resolve(true);
|
||||
if (message.group && message.group.id && message.group.type != textsecure.protobuf.GroupContext.Type.QUIT)
|
||||
|
@ -206,19 +212,11 @@ window.textsecure.messaging = function() {
|
|||
getKeysForNumber(number, resetDevices)
|
||||
.then(reloadDevicesAndSend(number, false))
|
||||
.catch(function(error) {
|
||||
if (error.message !== "Identity key changed at session save time")
|
||||
registerError(number, "Failed to reload device keys", error);
|
||||
else {
|
||||
error = new textsecure.OutgoingIdentityKeyError(number, message.toArrayBuffer(), timestamp, e.identityKey);
|
||||
registerError(number, "Identity key changed", error);
|
||||
}
|
||||
registerError(number, "Failed to reload device keys", error);
|
||||
});
|
||||
});
|
||||
} else if (error.message !== "Identity key changed at session save time") {
|
||||
registerError(number, "Failed to create or send message", error);
|
||||
} else {
|
||||
error = new textsecure.OutgoingIdentityKeyError(number, message.toArrayBuffer(), timestamp, e.identityKey);
|
||||
registerError(number, "Identity key changed", error);
|
||||
registerError(number, "Failed to create or send message", error);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue