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({ function savePairingAuthorisation(authorisation) {
primaryDevicePubKey, return window.Signal.Data.createOrUpdatePairingAuthorisation(authorisation);
secondaryDevicePubKey,
requestSignature,
grantSignature,
}) {
return window.Signal.Data.createOrUpdatePairingAuthorisation({
primaryDevicePubKey,
secondaryDevicePubKey,
requestSignature,
grantSignature,
});
} }
function getGrantAuthorisationForSecondaryPubKey(secondaryPubKey) { function getGrantAuthorisationForSecondaryPubKey(secondaryPubKey) {

@ -86,17 +86,19 @@ OutgoingMessage.prototype = {
}, },
reloadDevicesAndSend(number, recurse) { reloadDevicesAndSend(number, recurse) {
return () => return () =>
textsecure.storage.protocol.getDeviceIds(number).then(deviceIds => { libloki.storage
if (deviceIds.length === 0) { .getAllDevicePubKeysForPrimaryPubKey(number)
.then(devicesPubKeys => {
if (devicesPubKeys.length === 0) {
// eslint-disable-next-line no-param-reassign // eslint-disable-next-line no-param-reassign
deviceIds = [1]; devicesPubKeys = [number];
// return this.registerError( // return this.registerError(
// number, // number,
// 'Got empty device list when loading device keys', // 'Got empty device list when loading device keys',
// null // 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()); const bytes = new Uint8Array(websocketMessage.encode().toArrayBuffer());
return bytes; return bytes;
}, },
doSendMessage(number, deviceIds, recurse) { doSendMessage(number, devicesPubKeys, recurse) {
const ciphers = {}; const ciphers = {};
this.numbers = devicesPubKeys;
/* Disabled because i'm not sure how senderCertificate works :thinking: /* Disabled because i'm not sure how senderCertificate works :thinking:
const { numberInfo, senderCertificate } = this; const { numberInfo, senderCertificate } = this;
const info = numberInfo && numberInfo[number] ? numberInfo[number] : {}; const info = numberInfo && numberInfo[number] ? numberInfo[number] : {};
@ -291,8 +295,14 @@ OutgoingMessage.prototype = {
*/ */
return Promise.all( return Promise.all(
deviceIds.map(async deviceId => { devicesPubKeys.map(async devicePubKey => {
const address = new libsignal.SignalProtocolAddress(number, deviceId); // 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 ourKey = textsecure.storage.user.getNumber();
const options = {}; const options = {};
const fallBackCipher = new libloki.crypto.FallBackSessionCipher( const fallBackCipher = new libloki.crypto.FallBackSessionCipher(
@ -302,6 +312,23 @@ OutgoingMessage.prototype = {
// Check if we need to attach the preKeys // Check if we need to attach the preKeys
let sessionCipher; let sessionCipher;
const isFriendRequest = this.messageType === 'friend-request'; 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; this.fallBackEncryption = this.fallBackEncryption || isFriendRequest;
const flags = this.message.dataMessage const flags = this.message.dataMessage
? this.message.dataMessage.get_flags() ? this.message.dataMessage.get_flags()
@ -362,20 +389,41 @@ OutgoingMessage.prototype = {
sourceDevice: 1, sourceDevice: 1,
destinationRegistrationId: ciphertext.registrationId, destinationRegistrationId: ciphertext.registrationId,
content: ciphertext.body, content: ciphertext.body,
pubKey: devicePubKey,
}; };
}) })
) )
.then(async outgoingObjects => { .then(async outgoingObjects => {
// TODO: handle multiple devices/messages per transmit // TODO: handle multiple devices/messages per transmit
const outgoingObject = outgoingObjects[0]; const promises = outgoingObjects.map(async outgoingObject => {
const socketMessage = await this.wrapInWebsocketMessage(outgoingObject); const destination = outgoingObject.pubKey;
try {
const socketMessage = await this.wrapInWebsocketMessage(
outgoingObject
);
await this.transmitMessage( await this.transmitMessage(
number, destination,
socketMessage, socketMessage,
this.timestamp, this.timestamp,
outgoingObject.ttl 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(); this.numberCompleted();
}) })
.catch(error => { .catch(error => {
@ -431,7 +479,7 @@ OutgoingMessage.prototype = {
window.log.error( window.log.error(
'Got "key changed" error from encrypt - no identityKey for application layer', 'Got "key changed" error from encrypt - no identityKey for application layer',
number, number,
deviceIds devicesPubKeys
); );
throw error; throw error;
} else { } else {

Loading…
Cancel
Save