diff --git a/js/modules/data.js b/js/modules/data.js index 8c17b596c..996bd07bb 100644 --- a/js/modules/data.js +++ b/js/modules/data.js @@ -625,8 +625,7 @@ async function createOrUpdatePairingAuthorisation(data) { } async function getPairingAuthorisationsFor(pubKey) { - const authorisations = channels.getPairingAuthorisationsFor(pubKey); - + const authorisations = await channels.getPairingAuthorisationsFor(pubKey); return authorisations.map(authorisation => ({ ...authorisation, requestSignature: base64ToArrayBuffer(authorisation.requestSignature), diff --git a/libloki/api.js b/libloki/api.js index 81b4aa6ae..c0e3cd533 100644 --- a/libloki/api.js +++ b/libloki/api.js @@ -1,4 +1,4 @@ -/* global window, textsecure, dcodeIO, StringView, ConversationController, _ */ +/* global window, textsecure, dcodeIO, StringView, ConversationController, _, libsession */ /* eslint-disable no-bitwise */ // eslint-disable-next-line func-names @@ -55,12 +55,12 @@ } async function sendSessionEstablishedMessage(pubKey) { - // This message shouldn't be routed through multi-device. - // It needs to go directly to the pubKey specified. - const message = textsecure.OutgoingMessage.buildSessionEstablishedMessage( - pubKey + const user = libsession.Types.PubKey.from(pubKey); + + const sessionEstablished = new window.libsession.Messages.Outgoing.SessionEstablished( + { timestamp: Date.now() } ); - await message.sendToNumber(pubKey, false); + await libsession.messageQueue.send(user, sessionEstablished); } async function sendBackgroundMessage(pubKey, debugMessageType) { @@ -71,36 +71,7 @@ await backgroundMessage.sendToNumber(pubKey, false); } - function createPairingAuthorisationProtoMessage({ - primaryDevicePubKey, - secondaryDevicePubKey, - requestSignature, - grantSignature, - }) { - if (!primaryDevicePubKey || !secondaryDevicePubKey || !requestSignature) { - throw new Error( - 'createPairingAuthorisationProtoMessage: pubkeys missing' - ); - } - if (requestSignature.constructor !== ArrayBuffer) { - throw new Error( - 'createPairingAuthorisationProtoMessage expects a signature as ArrayBuffer' - ); - } - if (grantSignature && grantSignature.constructor !== ArrayBuffer) { - throw new Error( - 'createPairingAuthorisationProtoMessage expects a signature as ArrayBuffer' - ); - } - return new textsecure.protobuf.PairingAuthorisationMessage({ - requestSignature: new Uint8Array(requestSignature), - grantSignature: grantSignature ? new Uint8Array(grantSignature) : null, - primaryDevicePubKey, - secondaryDevicePubKey, - }); - } - - function sendUnpairingMessageToSecondary(pubKey) { + function sendUnpairingMessageToSecondary(pubKey) { const unpairingMessage = textsecure.OutgoingMessage.buildUnpairingMessage( pubKey ); @@ -216,39 +187,6 @@ }); return syncMessage; } - async function sendPairingAuthorisation(authorisation, recipientPubKey) { - const pairingAuthorisation = createPairingAuthorisationProtoMessage( - authorisation - ); - const ourNumber = textsecure.storage.user.getNumber(); - const ourConversation = await ConversationController.getOrCreateAndWait( - ourNumber, - 'private' - ); - // Send - const p = new Promise((resolve, reject) => { - const callback = result => { - // callback - if (result.errors.length > 0) { - reject(result.errors[0]); - } else { - resolve(); - } - }; - const pairingRequestMessage = textsecure.OutgoingMessage.buildPairingRequestMessage( - recipientPubKey, - ourNumber, - ourConversation, - authorisation, - pairingAuthorisation, - callback - ); - - pairingRequestMessage.sendToNumber(recipientPubKey, false); - }); - return p; - } - function sendSessionRequestsToMembers(members = []) { // For every member, see if we need to establish a session: members.forEach(memberPubKey => { @@ -284,8 +222,6 @@ sendSessionEstablishedMessage, sendBackgroundMessage, sendSessionRequestsToMembers, - sendPairingAuthorisation, - createPairingAuthorisationProtoMessage, sendUnpairingMessageToSecondary, createContactSyncProtoMessage, createGroupSyncProtoMessage, diff --git a/libtextsecure/account_manager.js b/libtextsecure/account_manager.js index 7ed7c684a..144017b67 100644 --- a/libtextsecure/account_manager.js +++ b/libtextsecure/account_manager.js @@ -545,37 +545,48 @@ primaryDevicePubKey, libloki.crypto.PairingType.REQUEST ); - const authorisation = { - primaryDevicePubKey, - secondaryDevicePubKey: ourPubKey, - requestSignature, - }; - await libloki.api.sendPairingAuthorisation( - authorisation, - primaryDevicePubKey + + const primaryDevice = libsession.Types.PubKey.from(primaryDevicePubKey); + + const requestPairingMessage = new window.libsession.Messages.Outgoing.DeviceLinkRequestMessage( + { + timestamp: Date.now(), + primaryDevicePubKey, + secondaryDevicePubKey: ourPubKey, + requestSignature, + } ); + await libsession.messageQueue.send(primaryDevice, requestPairingMessage); }, - async authoriseSecondaryDevice(secondaryDevicePubKey) { + async authoriseSecondaryDevice(secondaryDeviceStr) { const ourPubKey = textsecure.storage.user.getNumber(); - if (secondaryDevicePubKey === ourPubKey) { + if (secondaryDeviceStr === ourPubKey) { throw new Error( 'Cannot register primary device pubkey as secondary device' ); } + const secondaryDevicePubKey = libsession.Types.PubKey.from( + secondaryDeviceStr + ); - // throws if invalid - this.validatePubKeyHex(secondaryDevicePubKey); + if (!secondaryDevicePubKey) { + window.console.error( + 'Invalid secondary pubkey on authoriseSecondaryDevice' + ); + + return; + } // we need a conversation for sending a message const secondaryConversation = await ConversationController.getOrCreateAndWait( - secondaryDevicePubKey, + secondaryDeviceStr, 'private' ); const grantSignature = await libloki.crypto.generateSignatureForPairing( - secondaryDevicePubKey, + secondaryDeviceStr, libloki.crypto.PairingType.GRANT ); const authorisations = await libsession.Protocols.MultiDeviceProtocol.getPairingAuthorisations( - secondaryDevicePubKey + secondaryDeviceStr ); const existingAuthorisation = authorisations.some( pairing => pairing.secondaryDevicePubKey === secondaryDevicePubKey @@ -588,7 +599,7 @@ const { requestSignature } = existingAuthorisation; const authorisation = { primaryDevicePubKey: ourPubKey, - secondaryDevicePubKey, + secondaryDevicePubKey: secondaryDeviceStr, requestSignature, grantSignature, }; @@ -597,13 +608,34 @@ await libsession.Protocols.MultiDeviceProtocol.savePairingAuthorisation( authorisation ); + const ourConversation = await ConversationController.getOrCreateAndWait( + ourPubKey, + 'private' + ); + + // We need to send the our profile to the secondary device + const { displayName } = ourConversation.getLokiProfile(); + const avatarPointer = ourConversation.get('avatarPointer'); + const profileKey = window.storage.get('profileKey'); + const lokiProfile = { + displayName, + profileKey, + avatarPointer, + }; // Try to upload to the file server and then send a message try { await lokiFileServerAPI.updateOurDeviceMapping(); - await libloki.api.sendPairingAuthorisation( - authorisation, - secondaryDevicePubKey + const requestPairingMessage = new libsession.Messages.Outgoing.DeviceLinkGrantMessageParams( + { + timestamp: Date.now(), + ...authorisation, + lokiProfile, + } + ); + await libsession.messageQueue.send( + secondaryDevicePubKey, + requestPairingMessage ); } catch (e) { log.error( @@ -612,7 +644,7 @@ ); // File server upload failed or message sending failed, we should rollback changes await libsession.Protocols.MultiDeviceProtocol.removePairingAuthorisations( - secondaryDevicePubKey + secondaryDeviceStr ); await lokiFileServerAPI.updateOurDeviceMapping(); throw e; diff --git a/libtextsecure/outgoing_message.js b/libtextsecure/outgoing_message.js index e3a2534ca..a40491639 100644 --- a/libtextsecure/outgoing_message.js +++ b/libtextsecure/outgoing_message.js @@ -113,7 +113,6 @@ const DebugMessageType = { OPEN_GROUP_SYNC_SEND: 'open-group-sync-send', DEVICE_UNPAIRING_SEND: 'device-unpairing-send', - PAIRING_REQUEST_SEND: 'pairing-request', }; function OutgoingMessage( @@ -746,50 +745,6 @@ OutgoingMessage.buildUnpairingMessage = function buildUnpairingMessage(pubKey) { return outgoingMessage; }; -OutgoingMessage.buildPairingRequestMessage = function buildPairingRequestMessage( - pubKey, - ourNumber, - ourConversation, - authorisation, - pairingAuthorisation, - callback -) { - const content = new textsecure.protobuf.Content({ - pairingAuthorisation, - }); - const isGrant = authorisation.primaryDevicePubKey === ourNumber; - if (isGrant) { - // Send profile name to secondary device - const lokiProfile = ourConversation.getLokiProfile(); - // profile.avatar is the path to the local image - // replace with the avatar URL - const avatarPointer = ourConversation.get('avatarPointer'); - lokiProfile.avatar = avatarPointer; - const profile = new textsecure.protobuf.DataMessage.LokiProfile( - lokiProfile - ); - const profileKey = window.storage.get('profileKey'); - const dataMessage = new textsecure.protobuf.DataMessage({ - profile, - profileKey, - }); - content.dataMessage = dataMessage; - } - - const debugMessageType = DebugMessageType.PAIRING_REQUEST_SEND; - const options = { messageType: 'pairing-request', debugMessageType }; - const outgoingMessage = new textsecure.OutgoingMessage( - null, // server - Date.now(), // timestamp, - [pubKey], // numbers - content, // message - true, // silent - callback, // callback - options - ); - return outgoingMessage; -}; - OutgoingMessage.DebugMessageType = DebugMessageType; window.textsecure = window.textsecure || {}; diff --git a/ts/session/index.ts b/ts/session/index.ts index b0c1d659b..2982014c9 100644 --- a/ts/session/index.ts +++ b/ts/session/index.ts @@ -1,9 +1,8 @@ import * as Messages from './messages'; import * as Protocols from './protocols'; import * as Types from './types'; +import { MessageQueue } from './sending'; -// TODO: Do we export class instances here? -// E.g -// export const messageQueue = new MessageQueue() +const messageQueue = new MessageQueue(); -export { Messages, Protocols, Types }; +export { Messages, Protocols, Types, messageQueue }; diff --git a/ts/session/sending/MessageQueue.ts b/ts/session/sending/MessageQueue.ts index ac0f24f81..51747f784 100644 --- a/ts/session/sending/MessageQueue.ts +++ b/ts/session/sending/MessageQueue.ts @@ -168,9 +168,7 @@ export class MessageQueue implements MessageQueueInterface { } if (message instanceof SessionRequestMessage) { - void SessionProtocol.sendSessionRequest(message, device); - - return; + return SessionProtocol.sendSessionRequest(message, device); } await this.pendingMessageCache.add(device, message);