Handle friend request messages before they're discarded by Signal

This commit is contained in:
Niels Andriesse 2019-05-17 11:39:54 +10:00
parent cd03dfd4c6
commit 4c6d09aa29
1 changed files with 40 additions and 34 deletions

View File

@ -1372,6 +1372,9 @@ NS_ASSUME_NONNULL_BEGIN
[incomingMessage.attachmentIds addObject:pointer.uniqueId];
}
// Loki: Do this before the check below
[self handleFriendRequestIfNeededWithEnvelope:envelope message:incomingMessage thread:oldGroupThread transaction:transaction];
if (body.length == 0 && attachmentPointers.count < 1 && !contact) {
OWSLogWarn(@"ignoring empty incoming message from: %@ for group: %@ with timestamp: %lu",
envelopeAddress(envelope),
@ -1439,6 +1442,9 @@ NS_ASSUME_NONNULL_BEGIN
[incomingMessage.attachmentIds addObject:pointer.uniqueId];
}
// Loki: Do this before the check below
[self handleFriendRequestIfNeededWithEnvelope:envelope message:incomingMessage thread:thread transaction:transaction];
if (body.length == 0 && attachmentPointers.count < 1 && !contact) {
OWSLogWarn(@"ignoring empty incoming message from: %@ with timestamp: %lu",
envelopeAddress(envelope),
@ -1454,6 +1460,40 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (void)handleFriendRequestIfNeededWithEnvelope:(SSKProtoEnvelope *)envelope message:(TSIncomingMessage *)message thread:(TSThread *)thread transaction:(YapDatabaseReadWriteTransaction *)transaction
{
if (envelope.type == SSKProtoEnvelopeTypeFriendRequest) {
if (thread.hasCurrentUserSentFriendRequest) {
// This can happen if Alice sent Bob a friend request, Bob declined, but then Bob changed his
// mind and sent a friend request to Alice. In this case we want Alice to auto-accept the request
// and send a friend request accepted message back to Bob. We don't check that sending the
// friend request accepted message succeeded. Even if it doesn't, the thread's current friend
// request status will be set to TSThreadFriendRequestStatusFriends for Alice making it possible
// for Alice to send messages to Bob. When Bob receives a message, his thread's friend request status
// will then be set to TSThreadFriendRequestStatusFriends. If we do check for a successful send
// before updating Alice's thread's friend request status to TSThreadFriendRequestStatusFriends,
// we can end up in a deadlock where both users' threads' friend request statuses are
// TSThreadFriendRequestStatusRequestSent.
[thread setFriendRequestStatus:TSThreadFriendRequestStatusFriends withTransaction:transaction];
// The two lines below are equivalent to calling [ThreadUtil enqueueAcceptFriendRequestMessageInThread:thread]
TSOutgoingMessage *acceptFriendRequestMessage = [TSOutgoingMessage createEmptyOutgoingMessageInThread:thread];
[self.messageSenderJobQueue addMessage:acceptFriendRequestMessage transaction:transaction];
} else if (!thread.isContactFriend) {
// Checking that the sender of the message isn't already a friend is necessary because otherwise
// the following situation can occur: Alice and Bob are friends. Bob loses his database and his
// friend request status is reset to TSThreadFriendRequestStatusNone. Bob now sends Alice a friend
// request. Alice's thread's friend request status is reset to
// TSThreadFriendRequestStatusRequestReceived.
[thread setFriendRequestStatus:TSThreadFriendRequestStatusRequestReceived withTransaction:transaction];
message.isFriendRequest = YES; // Saved below
}
} else if (!thread.isContactFriend) {
// If the thread's friend request status is not TSThreadFriendRequestStatusFriends, but we're receiving a message,
// it must be a friend request accepted message. Declining a friend request doesn't send a message.
[thread setFriendRequestStatus:TSThreadFriendRequestStatusFriends withTransaction:transaction];
}
}
- (void)finalizeIncomingMessage:(TSIncomingMessage *)incomingMessage
thread:(TSThread *)thread
envelope:(SSKProtoEnvelope *)envelope
@ -1476,40 +1516,6 @@ NS_ASSUME_NONNULL_BEGIN
return;
}
// Loki:
// ========
if (envelope.type == SSKProtoEnvelopeTypeFriendRequest) {
if (thread.hasCurrentUserSentFriendRequest) {
// This can happen if Alice sent Bob a friend request, Bob declined, but then Bob changed his
// mind and sent a friend request to Alice. In this case we want Alice to auto-accept the request
// and send a friend request accepted message back to Bob. We don't check that sending the
// friend request accepted message succeeded. Even if it doesn't, the thread's current friend
// request status will be set to TSThreadFriendRequestStatusFriends for Alice making it possible
// for Alice to send messages to Bob. When Bob receives a message, his thread's friend request status
// will then be set to TSThreadFriendRequestStatusFriends. If we do check for a successful send
// before updating Alice's thread's friend request status to TSThreadFriendRequestStatusFriends,
// we can end up in a deadlock where both users' threads' friend request statuses are
// TSThreadFriendRequestStatusRequestSent.
[thread setFriendRequestStatus:TSThreadFriendRequestStatusFriends withTransaction:transaction];
// The two lines below are equivalent to calling [ThreadUtil enqueueAcceptFriendRequestMessageInThread:thread]
TSOutgoingMessage *message = [TSOutgoingMessage createEmptyOutgoingMessageInThread:thread];
[self.messageSenderJobQueue addMessage:message transaction:transaction];
} else if (!thread.isContactFriend) {
// Checking that the sender of the message isn't already a friend is necessary because otherwise
// the following situation can occur: Alice and Bob are friends. Bob loses his database and his
// friend request status is reset to TSThreadFriendRequestStatusNone. Bob now sends Alice a friend
// request. Alice's thread's friend request status is reset to
// TSThreadFriendRequestStatusRequestReceived.
[thread setFriendRequestStatus:TSThreadFriendRequestStatusRequestReceived withTransaction:transaction];
incomingMessage.isFriendRequest = YES; // Saved below
}
} else if (!thread.isContactFriend) {
// If the thread's friend request status is not TSThreadFriendRequestStatusFriends, but we're receiving a message,
// it must be a friend request accepted message. Declining a friend request doesn't send a message.
[thread setFriendRequestStatus:TSThreadFriendRequestStatusFriends withTransaction:transaction];
}
// ========
[incomingMessage saveWithTransaction:transaction];
// Any messages sent from the current user - from this device or another - should be automatically marked as read.