Merge pull request #441 from sachaaaaa/outgoing_messages

[multi-device] Outgoing messages
pull/454/head
sachaaaaa 6 years ago committed by GitHub
commit eaddf18cc5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -113,18 +113,8 @@
}
}
function savePairingAuthorisation({
primaryDevicePubKey,
secondaryDevicePubKey,
requestSignature,
grantSignature,
}) {
return window.Signal.Data.createOrUpdatePairingAuthorisation({
primaryDevicePubKey,
secondaryDevicePubKey,
requestSignature,
grantSignature,
});
function savePairingAuthorisation(authorisation) {
return window.Signal.Data.createOrUpdatePairingAuthorisation(authorisation);
}
function getGrantAuthorisationForSecondaryPubKey(secondaryPubKey) {

@ -86,17 +86,19 @@ OutgoingMessage.prototype = {
},
reloadDevicesAndSend(number, recurse) {
return () =>
textsecure.storage.protocol.getDeviceIds(number).then(deviceIds => {
if (deviceIds.length === 0) {
libloki.storage
.getAllDevicePubKeysForPrimaryPubKey(number)
.then(devicesPubKeys => {
if (devicesPubKeys.length === 0) {
// eslint-disable-next-line no-param-reassign
deviceIds = [1];
devicesPubKeys = [number];
// return this.registerError(
// number,
// 'Got empty device list when loading device keys',
// null
// );
}
return this.doSendMessage(number, deviceIds, recurse);
return this.doSendMessage(number, devicesPubKeys, recurse);
});
},
@ -257,9 +259,11 @@ OutgoingMessage.prototype = {
const bytes = new Uint8Array(websocketMessage.encode().toArrayBuffer());
return bytes;
},
doSendMessage(number, deviceIds, recurse) {
doSendMessage(number, devicesPubKeys, recurse) {
const ciphers = {};
this.numbers = devicesPubKeys;
/* Disabled because i'm not sure how senderCertificate works :thinking:
const { numberInfo, senderCertificate } = this;
const info = numberInfo && numberInfo[number] ? numberInfo[number] : {};
@ -291,8 +295,14 @@ OutgoingMessage.prototype = {
*/
return Promise.all(
deviceIds.map(async deviceId => {
const address = new libsignal.SignalProtocolAddress(number, deviceId);
devicesPubKeys.map(async devicePubKey => {
// Loki Messenger doesn't use the deviceId scheme, it's always 1.
// Instead, there are multiple device public keys.
const deviceId = 1;
const address = new libsignal.SignalProtocolAddress(
devicePubKey,
deviceId
);
const ourKey = textsecure.storage.user.getNumber();
const options = {};
const fallBackCipher = new libloki.crypto.FallBackSessionCipher(
@ -302,6 +312,23 @@ OutgoingMessage.prototype = {
// Check if we need to attach the preKeys
let sessionCipher;
const isFriendRequest = this.messageType === 'friend-request';
const isSecondaryDevice = !!window.storage.get('isSecondaryDevice');
if (isFriendRequest && isSecondaryDevice) {
// Attach authorisation from primary device ONLY FOR FRIEND REQUEST
const ourPubKeyHex = textsecure.storage.user.getNumber();
const pairingAuthorisation = await libloki.storage.getGrantAuthorisationForSecondaryPubKey(
ourPubKeyHex
);
if (pairingAuthorisation) {
this.message.pairingAuthorisation = libloki.api.createPairingAuthorisationProtoMessage(
pairingAuthorisation
);
} else {
window.log.error(
'Could not find authorisation for our own pubkey while being secondary device.'
);
}
}
this.fallBackEncryption = this.fallBackEncryption || isFriendRequest;
const flags = this.message.dataMessage
? this.message.dataMessage.get_flags()
@ -362,20 +389,41 @@ OutgoingMessage.prototype = {
sourceDevice: 1,
destinationRegistrationId: ciphertext.registrationId,
content: ciphertext.body,
pubKey: devicePubKey,
};
})
)
.then(async outgoingObjects => {
// TODO: handle multiple devices/messages per transmit
const outgoingObject = outgoingObjects[0];
const socketMessage = await this.wrapInWebsocketMessage(outgoingObject);
const promises = outgoingObjects.map(async outgoingObject => {
const destination = outgoingObject.pubKey;
try {
const socketMessage = await this.wrapInWebsocketMessage(
outgoingObject
);
await this.transmitMessage(
number,
destination,
socketMessage,
this.timestamp,
outgoingObject.ttl
);
this.successfulNumbers[this.successfulNumbers.length] = number;
this.successfulNumbers.push(destination);
} catch (e) {
e.number = destination;
this.errors.push(e);
}
});
await Promise.all(promises);
// TODO: the retrySend should only send to the devices
// for which the transmission failed.
// ensure numberCompleted() will execute the callback
this.numbersCompleted +=
this.errors.length + this.successfulNumbers.length;
// Absorb errors if message sent to at least 1 device
if (this.successfulNumbers.length > 0) {
this.errors = [];
}
this.numberCompleted();
})
.catch(error => {
@ -431,7 +479,7 @@ OutgoingMessage.prototype = {
window.log.error(
'Got "key changed" error from encrypt - no identityKey for application layer',
number,
deviceIds
devicesPubKeys
);
throw error;
} else {

Loading…
Cancel
Save