diff --git a/_locales/en/messages.json b/_locales/en/messages.json index c37ea1854..ac474f002 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1124,11 +1124,6 @@ "message": " Type your message", "description": "Placeholder text in the message entry field" }, - "secondaryDeviceDefaultFR": { - "message": "Please accept to enable messages to be synced across devices", - "description": - "Placeholder text in the message entry field when it is disabled because a secondary device conversation is visible" - }, "sendMessageDisabledSecondary": { "message": "This pubkey belongs to a secondary device. You should never see this message", diff --git a/js/models/conversations.js b/js/models/conversations.js index 10bc72834..d77fa9807 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -14,7 +14,8 @@ clipboard, BlockedNumberController, lokiPublicChatAPI, - JobQueue + JobQueue, + libloki */ /* eslint-disable more/no-then */ @@ -1074,6 +1075,14 @@ window.textsecure.OutgoingMessage.DebugMessageType .INCOMING_FR_ACCEPTED ); + + // send an AFR to other device of that user (or none) + const primaryPubKey = await libloki.api.getPrimaryDevicePubkey(this.id); + + const autoFrMessage = textsecure.OutgoingMessage.buildAutoFriendRequestMessage( + primaryPubKey + ); + await autoFrMessage.sendToNumber(primaryPubKey, true, this.id); } }, // Our outgoing friend request has been accepted diff --git a/js/models/messages.js b/js/models/messages.js index 91e381252..43245c7aa 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -2152,7 +2152,7 @@ // still go through one of the previous two codepaths const ourNumber = textsecure.storage.user.getNumber(); const message = this; - let source = message.get('source'); + const source = message.get('source'); let conversationId = message.get('conversationId'); const authorisation = await libloki.storage.getGrantAuthorisationForSecondaryPubKey( source @@ -2234,7 +2234,7 @@ } } const conversation = conversationPrimary; - source = primarySource; + // source = primarySource; return conversation.queueJob(async () => { window.log.info( @@ -2569,7 +2569,8 @@ } } - if (source !== ourNumber) { + // We need to map the original message source to the primary device + if (source !== ourNumber && !message.isFriendRequest()) { message.set({ source: primarySource }); } diff --git a/libloki/api.js b/libloki/api.js index dabfd4bff..5eeedf11b 100644 --- a/libloki/api.js +++ b/libloki/api.js @@ -90,38 +90,22 @@ const message = textsecure.OutgoingMessage.buildSessionEstablishedMessage( pubKey ); - await message.sendToNumber(pubKey); + await message.sendToNumber(pubKey, false); } async function sendBackgroundMessage(pubKey, debugMessageType) { - const primaryPubKey = await getPrimaryDevicePubkey(pubKey); - if (primaryPubKey !== pubKey) { - // if we got the secondary device pubkey first, - // call ourself again with the primary device pubkey - await sendBackgroundMessage(primaryPubKey, debugMessageType); - return; - } - const backgroundMessage = textsecure.OutgoingMessage.buildBackgroundMessage( pubKey, debugMessageType ); - await backgroundMessage.sendToNumber(pubKey); + await backgroundMessage.sendToNumber(pubKey, false); } async function sendAutoFriendRequestMessage(pubKey) { - const primaryPubKey = await getPrimaryDevicePubkey(pubKey); - if (primaryPubKey !== pubKey) { - // if we got the secondary device pubkey first, - // call ourself again with the primary device pubkey - await sendAutoFriendRequestMessage(primaryPubKey); - return; - } - const autoFrMessage = textsecure.OutgoingMessage.buildAutoFriendRequestMessage( pubKey ); - await autoFrMessage.sendToNumber(pubKey); + await autoFrMessage.sendToNumber(pubKey, false); } function createPairingAuthorisationProtoMessage({ @@ -157,7 +141,7 @@ const unpairingMessage = textsecure.OutgoingMessage.buildUnpairingMessage( pubKey ); - return unpairingMessage.sendToNumber(pubKey); + return unpairingMessage.sendToNumber(pubKey, false); } // Serialise as ... // This is an implementation of the reciprocal of contacts_parser.js @@ -296,7 +280,7 @@ callback ); - pairingRequestMessage.sendToNumber(recipientPubKey); + pairingRequestMessage.sendToNumber(recipientPubKey, false); }); return p; } @@ -346,6 +330,7 @@ createContactSyncProtoMessage, createGroupSyncProtoMessage, createOpenGroupsSyncProtoMessage, + getPrimaryDevicePubkey, debug, }; })(); diff --git a/libtextsecure/outgoing_message.js b/libtextsecure/outgoing_message.js index 9e2aafcc4..2762f1af5 100644 --- a/libtextsecure/outgoing_message.js +++ b/libtextsecure/outgoing_message.js @@ -216,17 +216,26 @@ OutgoingMessage.prototype = { this.errors[this.errors.length] = error; this.numberCompleted(); }, - reloadDevicesAndSend(primaryPubKey) { + reloadDevicesAndSend(primaryPubKey, multiDevice = true, excludedDevices = []) { const ourNumber = textsecure.storage.user.getNumber(); + if (!multiDevice) { + if (primaryPubKey === ourNumber) { + return Promise.resolve(); + } + + return this.doSendMessage(primaryPubKey, [primaryPubKey]); + } + return ( libloki.storage .getAllDevicePubKeysForPrimaryPubKey(primaryPubKey) // Don't send to ourselves .then(devicesPubKeys => - devicesPubKeys.filter(pubKey => pubKey !== ourNumber) + devicesPubKeys.filter(pubKey => pubKey !== ourNumber && !excludedDevices.includes(pubKey)) ) .then(devicesPubKeys => { + if (devicesPubKeys.length === 0) { // No need to start the sending of message without a recipient return Promise.resolve(); @@ -349,7 +358,7 @@ OutgoingMessage.prototype = { const updatedDevices = await getStaleDeviceIdsForNumber(devicePubKey); const keysFound = await this.getKeysForNumber(devicePubKey, updatedDevices); - let isMultiDeviceRequest = false; + // let isMultiDeviceRequest = false; let thisDeviceMessageType = this.messageType; if ( thisDeviceMessageType !== 'pairing-request' && @@ -370,7 +379,7 @@ OutgoingMessage.prototype = { // - We haven't received a friend request from this device // - We haven't sent a friend request recently if (conversation.friendRequestTimerIsExpired()) { - isMultiDeviceRequest = true; + // isMultiDeviceRequest = true; thisDeviceMessageType = 'friend-request'; } else { // Throttle automated friend requests @@ -412,27 +421,11 @@ OutgoingMessage.prototype = { window.log.info('attaching prekeys to outgoing message'); } - let messageBuffer; - let logDetails; - if (isMultiDeviceRequest) { - const tempMessage = new textsecure.protobuf.Content(); - const tempDataMessage = new textsecure.protobuf.DataMessage(); - tempDataMessage.body = i18n('secondaryDeviceDefaultFR'); - if (this.message.dataMessage && this.message.dataMessage.profile) { - tempDataMessage.profile = this.message.dataMessage.profile; - } - tempMessage.preKeyBundleMessage = this.message.preKeyBundleMessage; - tempMessage.dataMessage = tempDataMessage; - messageBuffer = tempMessage.toArrayBuffer(); - logDetails = { - tempMessage, - }; - } else { - messageBuffer = this.message.toArrayBuffer(); - logDetails = { - message: this.message, - }; - } + const messageBuffer = this.message.toArrayBuffer(); + const logDetails = { + message: this.message, + }; + const messageTypeStr = this.debugMessageType; const ourPubKey = textsecure.storage.user.getNumber(); @@ -489,6 +482,7 @@ OutgoingMessage.prototype = { plaintext, pubKey, isSessionRequest, + isFriendRequest, enableFallBackEncryption, } = clearMessage; // Session doesn't use the deviceId scheme, it's always 1. @@ -534,7 +528,7 @@ OutgoingMessage.prototype = { sourceDevice, content, pubKey, - isFriendRequest: enableFallBackEncryption, + isFriendRequest, isSessionRequest, }; }, @@ -708,14 +702,14 @@ OutgoingMessage.prototype = { return promise; }, - sendToNumber(number) { + sendToNumber(number, multiDevice = true, excludedDevices = []) { let conversation; try { conversation = ConversationController.get(number); } catch (e) { // do nothing } - return this.reloadDevicesAndSend(number).catch(error => { + return this.reloadDevicesAndSend(number, multiDevice, excludedDevices).catch(error => { conversation.resetPendingSend(); if (error.message === 'Identity key changed') { // eslint-disable-next-line no-param-reassign @@ -740,9 +734,7 @@ OutgoingMessage.prototype = { OutgoingMessage.buildAutoFriendRequestMessage = function buildAutoFriendRequestMessage( pubKey ) { - const body = - '(If you see this message, you must be using an out-of-date client)'; - + const body = 'Please accept to enable messages to be synced across devices'; const dataMessage = new textsecure.protobuf.DataMessage({ body }); const content = new textsecure.protobuf.Content({ @@ -750,7 +742,7 @@ OutgoingMessage.buildAutoFriendRequestMessage = function buildAutoFriendRequestM }); const options = { - messageType: 'onlineBroadcast', + messageType: 'friend-request', debugMessageType: DebugMessageType.AUTO_FR_REQUEST, }; // Send a empty message with information about how to contact us directly @@ -768,9 +760,12 @@ OutgoingMessage.buildAutoFriendRequestMessage = function buildAutoFriendRequestM OutgoingMessage.buildSessionRequestMessage = function buildSessionRequestMessage( pubKey ) { + const body = + '(If you see this message, you must be using an out-of-date client)'; + const flags = textsecure.protobuf.DataMessage.Flags.SESSION_REQUEST; - const dataMessage = new textsecure.protobuf.DataMessage({ flags }); + const dataMessage = new textsecure.protobuf.DataMessage({ flags, body }); const content = new textsecure.protobuf.Content({ dataMessage,