From fc6ca57e1e6b1669855eb45cd103b2df84d6d11c Mon Sep 17 00:00:00 2001 From: Mikunj Date: Mon, 10 Feb 2020 12:06:05 +1100 Subject: [PATCH] Added support for group request info --- js/background.js | 3 +- js/models/conversations.js | 17 ++++ js/models/messages.js | 128 ++++++++++++++++-------------- libtextsecure/message_receiver.js | 4 + libtextsecure/sendmessage.js | 11 ++- 5 files changed, 102 insertions(+), 61 deletions(-) diff --git a/js/background.js b/js/background.js index 859909b61..0a3b4f3be 100644 --- a/js/background.js +++ b/js/background.js @@ -787,6 +787,7 @@ 'group' ); + convo.updateGroupAdmins([primaryDeviceKey]); convo.updateGroup(ev.groupDetails); // Group conversations are automatically 'friends' @@ -795,8 +796,6 @@ window.friends.friendRequestStatusEnum.friends ); - convo.updateGroupAdmins([primaryDeviceKey]); - appView.openConversation(groupId, {}); }; diff --git a/js/models/conversations.js b/js/models/conversations.js index 7471c5798..b4f2a2485 100644 --- a/js/models/conversations.js +++ b/js/models/conversations.js @@ -2232,6 +2232,7 @@ this.get('name'), this.get('avatar'), this.get('members'), + this.get('groupAdmins'), groupUpdate.recipients, options ) @@ -2239,6 +2240,21 @@ ); }, + sendGroupInfo(recipients) { + if (this.isClosedGroup()) { + const options = this.getSendOptions(); + textsecure.messaging.updateGroup( + this.id, + this.get('name'), + this.get('avatar'), + this.get('members'), + this.get('groupAdmins'), + recipients, + options + ); + } + }, + async leaveGroup() { const now = Date.now(); if (this.get('type') === 'group') { @@ -2323,6 +2339,7 @@ const ourNumber = textsecure.storage.user.getNumber(); return !stillUnread.some( m => + m.propsForMessage && m.propsForMessage.text && m.propsForMessage.text.indexOf(`@${ourNumber}`) !== -1 ); diff --git a/js/models/messages.js b/js/models/messages.js index c79ca9c11..4aef00b64 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -1929,78 +1929,90 @@ } } - if ( - initialMessage.group && - initialMessage.group.members && - initialMessage.group.type === GROUP_TYPES.UPDATE - ) { - if (newGroup) { - conversation.updateGroupAdmins(initialMessage.group.admins); + if (initialMessage.group) { + if ( + initialMessage.group.type === GROUP_TYPES.REQUEST_INFO && + !newGroup + ) { + conversation.sendGroupInfo([source]); + return null; + } else if ( + initialMessage.group.members && + initialMessage.group.type === GROUP_TYPES.UPDATE + ) { + if (newGroup) { + conversation.updateGroupAdmins(initialMessage.group.admins); - conversation.setFriendRequestStatus( - window.friends.friendRequestStatusEnum.friends - ); - } + conversation.setFriendRequestStatus( + window.friends.friendRequestStatusEnum.friends + ); + } const fromAdmin = conversation .get('groupAdmins') .includes(primarySource); - if (!fromAdmin) { - // Make sure the message is not removing members / renaming the group - const nameChanged = - conversation.get('name') !== initialMessage.group.name; + if (!fromAdmin) { + // Make sure the message is not removing members / renaming the group + const nameChanged = + conversation.get('name') !== initialMessage.group.name; - if (nameChanged) { - window.log.warn( - 'Non-admin attempts to change the name of the group' - ); - } + if (nameChanged) { + window.log.warn( + 'Non-admin attempts to change the name of the group' + ); + } - const membersMissing = - _.difference( - conversation.get('members'), - initialMessage.group.members - ).length > 0; + const membersMissing = + _.difference( + conversation.get('members'), + initialMessage.group.members + ).length > 0; - if (membersMissing) { - window.log.warn('Non-admin attempts to remove group members'); - } + if (membersMissing) { + window.log.warn('Non-admin attempts to remove group members'); + } - const messageAllowed = !nameChanged && !membersMissing; + const messageAllowed = !nameChanged && !membersMissing; - if (!messageAllowed) { - confirm(); - return null; + if (!messageAllowed) { + confirm(); + return null; + } } - } - // For every member, see if we need to establish a session: - initialMessage.group.members.forEach(memberPubKey => { - const haveSession = _.some( - textsecure.storage.protocol.sessions, - s => s.number === memberPubKey - ); + // For every member, see if we need to establish a session: + initialMessage.group.members.forEach(memberPubKey => { + const haveSession = _.some( + textsecure.storage.protocol.sessions, + s => s.number === memberPubKey + ); - const ourPubKey = textsecure.storage.user.getNumber(); - if (!haveSession && memberPubKey !== ourPubKey) { - ConversationController.getOrCreateAndWait( - memberPubKey, - 'private' - ).then(() => { - textsecure.messaging.sendMessageToNumber( + const ourPubKey = textsecure.storage.user.getNumber(); + if (!haveSession && memberPubKey !== ourPubKey) { + ConversationController.getOrCreateAndWait( memberPubKey, - '(If you see this message, you must be using an out-of-date client)', - [], - undefined, - [], - Date.now(), - undefined, - undefined, - { messageType: 'friend-request', sessionRequest: true } - ); - }); - } - }); + 'private' + ).then(() => { + textsecure.messaging.sendMessageToNumber( + memberPubKey, + '(If you see this message, you must be using an out-of-date client)', + [], + undefined, + [], + Date.now(), + undefined, + undefined, + { messageType: 'friend-request', sessionRequest: true } + ); + }); + } + }); + } else if (newGroup) { + // We have an unknown group, we should request info + textsecure.messaging.requestGroupInfo(conversationId, [ + primarySource, + ]); + } } const isSessionRequest = diff --git a/libtextsecure/message_receiver.js b/libtextsecure/message_receiver.js index 757cfbcfa..893d549cc 100644 --- a/libtextsecure/message_receiver.js +++ b/libtextsecure/message_receiver.js @@ -1786,6 +1786,10 @@ MessageReceiver.prototype.extend({ decrypted.group.members = []; decrypted.group.avatar = null; break; + case textsecure.protobuf.GroupContext.Type.REQUEST_INFO: + decrypted.body = null; + decrypted.attachments = []; + break; default: this.removeFromCache(envelope); throw new Error('Unknown group message type'); diff --git a/libtextsecure/sendmessage.js b/libtextsecure/sendmessage.js index 57ebb6a6a..9386d2409 100644 --- a/libtextsecure/sendmessage.js +++ b/libtextsecure/sendmessage.js @@ -1107,7 +1107,7 @@ MessageSender.prototype = { return this.sendMessage(attrs, options); }, - updateGroup(groupId, name, avatar, members, recipients, options) { + updateGroup(groupId, name, avatar, members, admins, recipients, options) { const proto = new textsecure.protobuf.DataMessage(); proto.group = new textsecure.protobuf.GroupContext(); @@ -1164,6 +1164,14 @@ MessageSender.prototype = { }); }, + requestGroupInfo(groupId, groupNumbers, options) { + const proto = new textsecure.protobuf.DataMessage(); + proto.group = new textsecure.protobuf.GroupContext(); + proto.group.id = stringToArrayBuffer(groupId); + proto.group.type = textsecure.protobuf.GroupContext.Type.REQUEST_INFO; + return this.sendGroupProto(groupNumbers, proto, Date.now(), options); + }, + leaveGroup(groupId, groupNumbers, options) { const proto = new textsecure.protobuf.DataMessage(); proto.group = new textsecure.protobuf.GroupContext(); @@ -1263,6 +1271,7 @@ textsecure.MessageSender = function MessageSenderWrapper(username, password) { this.addNumberToGroup = sender.addNumberToGroup.bind(sender); this.setGroupName = sender.setGroupName.bind(sender); this.setGroupAvatar = sender.setGroupAvatar.bind(sender); + this.requestGroupInfo = sender.requestGroupInfo.bind(sender); this.leaveGroup = sender.leaveGroup.bind(sender); this.sendSyncMessage = sender.sendSyncMessage.bind(sender); this.getProfile = sender.getProfile.bind(sender);