diff --git a/js/models/conversations.js b/js/models/conversations.js index 1f62f4b78..d4274e3af 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -653,7 +653,9 @@ await this.respondToAllPendingFriendRequests({ response: 'accepted', }); + return true; } + return false; }, async onFriendRequestTimeout() { // Unset the timer diff --git a/libloki/api.js b/libloki/api.js index 80dda5b6b..6c5c8365f 100644 --- a/libloki/api.js +++ b/libloki/api.js @@ -5,33 +5,48 @@ window.libloki = window.libloki || {}; async function sendFriendRequestAccepted(pubKey) { - return sendEmptyMessage(pubKey); + return sendEmptyMessage(pubKey, true); } - async function sendEmptyMessage(pubKey) { - // empty content message - const content = new textsecure.protobuf.Content(); - - // will be called once the transmission succeeded or failed - const callback = res => { - if (res.errors.length > 0) { - res.errors.forEach(error => log.error(error)); - } else { - log.info('empty message sent successfully'); - } - }; + async function sendEmptyMessage(pubKey, sendContentMessage = false) { const options = {}; - // send an empty message. The logic in ougoing_message will attach the prekeys. - const outgoingMessage = new textsecure.OutgoingMessage( - null, // server - Date.now(), // timestamp, - [pubKey], // numbers - content, // message - true, // silent - callback, // callback - options - ); - await outgoingMessage.sendToNumber(pubKey); + // send an empty message. + if (sendContentMessage) { + // The logic downstream will attach the prekeys and our profile. + await textsecure.messaging.sendMessageToNumber( + pubKey, // number + null, // messageText + [], // attachments + null, // quote + Date.now(), // timestamp + null, // expireTimer + null, // profileKey + options + ); + } else { + // empty content message + const content = new textsecure.protobuf.Content(); + + // will be called once the transmission succeeded or failed + const callback = res => { + if (res.errors.length > 0) { + res.errors.forEach(error => log.error(error)); + } else { + log.info('empty message sent successfully'); + } + }; + // send an empty message. The logic in ougoing_message will attach the prekeys. + const outgoingMessage = new textsecure.OutgoingMessage( + null, // server + Date.now(), // timestamp, + [pubKey], // numbers + content, // message + true, // silent + callback, // callback + options + ); + await outgoingMessage.sendToNumber(pubKey); + } } window.libloki.api = { diff --git a/libtextsecure/message_receiver.js b/libtextsecure/message_receiver.js index eeda84461..e8a2dcb71 100644 --- a/libtextsecure/message_receiver.js +++ b/libtextsecure/message_receiver.js @@ -907,56 +907,75 @@ MessageReceiver.prototype.extend({ p = this.handleEndSession(envelope.source); } return p.then(() => - this.processDecrypted(envelope, msg, envelope.source).then(message => { - const groupId = message.group && message.group.id; - const isBlocked = this.isGroupBlocked(groupId); - const isMe = envelope.source === textsecure.storage.user.getNumber(); - const conversation = window.ConversationController.get(envelope.source); - const isLeavingGroup = Boolean( - message.group && - message.group.type === textsecure.protobuf.GroupContext.Type.QUIT - ); - const friendRequest = - envelope.type === textsecure.protobuf.Envelope.Type.FRIEND_REQUEST; - - // Check if we need to update any profile names - if (!isMe && conversation) { - let profile = null; - if (message.profile) { - profile = JSON.parse(message.profile.encodeJSON()); + this.processDecrypted(envelope, msg, envelope.source).then( + async message => { + const groupId = message.group && message.group.id; + const isBlocked = this.isGroupBlocked(groupId); + const isMe = envelope.source === textsecure.storage.user.getNumber(); + const conversation = window.ConversationController.get( + envelope.source + ); + const isLeavingGroup = Boolean( + message.group && + message.group.type === textsecure.protobuf.GroupContext.Type.QUIT + ); + const friendRequest = + envelope.type === textsecure.protobuf.Envelope.Type.FRIEND_REQUEST; + + // Check if we need to update any profile names + if (!isMe && conversation) { + let profile = null; + if (message.profile) { + profile = JSON.parse(message.profile.encodeJSON()); + } + + // Update the conversation + await conversation.setProfile(profile); } - // Update the conversation - conversation.setProfile(profile); - } + if (friendRequest && isMe) { + window.log.info('refusing to add a friend request to ourselves'); + throw new Error('Cannot add a friend request for ourselves!'); + } - if (friendRequest && isMe) { - window.log.info('refusing to add a friend request to ourselves'); - throw new Error('Cannot add a friend request for ourselves!'); - } + if (groupId && isBlocked && !(isMe && isLeavingGroup)) { + window.log.warn( + `Message ${this.getEnvelopeId( + envelope + )} ignored; destined for blocked group` + ); + return this.removeFromCache(envelope); + } - if (groupId && isBlocked && !(isMe && isLeavingGroup)) { - window.log.warn( - `Message ${this.getEnvelopeId( - envelope - )} ignored; destined for blocked group` - ); - return this.removeFromCache(envelope); - } + if (!message.body) { + // Trigger conversation friend request event for empty message + if (conversation && !message.flags) { + const isFriendRequestAccept = await conversation.onFriendRequestAccepted(); + if (isFriendRequestAccept) { + await conversation.notifyFriendRequest( + envelope.source, + 'accepted' + ); + } + } + this.removeFromCache(envelope); + return null; + } - const ev = new Event('message'); - ev.confirm = this.removeFromCache.bind(this, envelope); - ev.data = { - friendRequest, - source: envelope.source, - sourceDevice: envelope.sourceDevice, - timestamp: envelope.timestamp.toNumber(), - receivedAt: envelope.receivedAt, - unidentifiedDeliveryReceived: envelope.unidentifiedDeliveryReceived, - message, - }; - return this.dispatchAndWait(ev); - }) + const ev = new Event('message'); + ev.confirm = this.removeFromCache.bind(this, envelope); + ev.data = { + friendRequest, + source: envelope.source, + sourceDevice: envelope.sourceDevice, + timestamp: envelope.timestamp.toNumber(), + receivedAt: envelope.receivedAt, + unidentifiedDeliveryReceived: envelope.unidentifiedDeliveryReceived, + message, + }; + return this.dispatchAndWait(ev); + } + ) ); }, handleLegacyMessage(envelope) { @@ -1007,13 +1026,6 @@ MessageReceiver.prototype.extend({ if (content.typingMessage) return this.handleTypingMessage(envelope, content.typingMessage); - // Trigger conversation friend request event for empty message - const conversation = window.ConversationController.get(envelope.source); - if (conversation) { - conversation.onFriendRequestAccepted(); - conversation.notifyFriendRequest(envelope.source, 'accepted'); - } - this.removeFromCache(envelope); return null; }, handleCallMessage(envelope) {