|
|
|
@ -307,23 +307,20 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (dataMessage.hasGroup) {
|
|
|
|
|
TSGroupThread *_Nullable gThread =
|
|
|
|
|
TSGroupThread *_Nullable groupThread =
|
|
|
|
|
[TSGroupThread threadWithGroupId:dataMessage.group.id transaction:transaction];
|
|
|
|
|
BOOL unknownGroup = NO;
|
|
|
|
|
if (gThread == nil && dataMessage.group.type != OWSSignalServiceProtosGroupContextTypeUpdate) {
|
|
|
|
|
unknownGroup = YES;
|
|
|
|
|
}
|
|
|
|
|
if (unknownGroup) {
|
|
|
|
|
if (dataMessage.group.type == OWSSignalServiceProtosGroupContextTypeRequestInfo) {
|
|
|
|
|
DDLogInfo(@"%@ Ignoring group info request for unknown group from: %@", self.tag, envelope.source);
|
|
|
|
|
return;
|
|
|
|
|
} else if (dataMessage.group.type == OWSSignalServiceProtosGroupContextTypeQuit) {
|
|
|
|
|
DDLogInfo(@"%@ Ignoring group quit for unknown group from: %@", self.tag, envelope.source);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!groupThread) {
|
|
|
|
|
// Unknown group.
|
|
|
|
|
if (dataMessage.group.type == OWSSignalServiceProtosGroupContextTypeUpdate) {
|
|
|
|
|
// Accept group updates for unknown groups.
|
|
|
|
|
} else if (dataMessage.group.type == OWSSignalServiceProtosGroupContextTypeDeliver) {
|
|
|
|
|
[self sendGroupInfoRequest:dataMessage.group.id envelope:envelope transaction:transaction];
|
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
DDLogInfo(@"%@ Ignoring group message for unknown group from: %@", self.tag, envelope.source);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -846,13 +843,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
NSString *body = dataMessage.body;
|
|
|
|
|
NSData *groupId = dataMessage.hasGroup ? dataMessage.group.id : nil;
|
|
|
|
|
|
|
|
|
|
__block TSIncomingMessage *_Nullable incomingMessage;
|
|
|
|
|
__block TSThread *thread;
|
|
|
|
|
|
|
|
|
|
// Do this outside of a transaction to avoid deadlock
|
|
|
|
|
OWSAssert([TSAccountManager isRegistered]);
|
|
|
|
|
NSString *localNumber = [TSAccountManager localNumber];
|
|
|
|
|
|
|
|
|
|
if (dataMessage.group.type == OWSSignalServiceProtosGroupContextTypeRequestInfo) {
|
|
|
|
|
[self handleGroupInfoRequest:envelope dataMessage:dataMessage transaction:transaction];
|
|
|
|
|
return nil;
|
|
|
|
@ -866,9 +856,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
// We distinguish between the old group state (if any) and the new group state.
|
|
|
|
|
TSGroupThread *_Nullable oldGroupThread = [TSGroupThread threadWithGroupId:groupId transaction:transaction];
|
|
|
|
|
if (oldGroupThread) {
|
|
|
|
|
// Don't trust other clients; ensure all known group members leave the group
|
|
|
|
|
// _unless_ it is a "quit" message in which case we should explicitly remove
|
|
|
|
|
// just the quiting member below.
|
|
|
|
|
// Don't trust other clients; ensure all known group members remain in the
|
|
|
|
|
// group unless it is a "quit" message in which case we should only remove
|
|
|
|
|
// the quiting member below.
|
|
|
|
|
[newMemberIds addObjectsFromArray:oldGroupThread.groupModel.groupMemberIds];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -880,7 +870,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
|
|
|
|
|
TSGroupModel *newGroupModel = [[TSGroupModel alloc] initWithTitle:dataMessage.group.name
|
|
|
|
|
memberIds:[newMemberIds.allObjects mutableCopy]
|
|
|
|
|
image:nil
|
|
|
|
|
image:oldGroupThread.groupModel.groupImage
|
|
|
|
|
groupId:dataMessage.group.id];
|
|
|
|
|
NSString *updateGroupInfo = [newGroupThread.groupModel getInfoStringAboutUpdateTo:newGroupModel
|
|
|
|
|
contactsManager:self.contactsManager];
|
|
|
|
@ -891,8 +881,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
inThread:newGroupThread
|
|
|
|
|
messageType:TSInfoMessageTypeGroupUpdate
|
|
|
|
|
customMessage:updateGroupInfo] saveWithTransaction:transaction];
|
|
|
|
|
thread = newGroupThread;
|
|
|
|
|
break;
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
case OWSSignalServiceProtosGroupContextTypeQuit: {
|
|
|
|
|
if (!oldGroupThread) {
|
|
|
|
@ -910,12 +899,11 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
inThread:oldGroupThread
|
|
|
|
|
messageType:TSInfoMessageTypeGroupUpdate
|
|
|
|
|
customMessage:updateGroupInfo] saveWithTransaction:transaction];
|
|
|
|
|
thread = oldGroupThread;
|
|
|
|
|
break;
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
case OWSSignalServiceProtosGroupContextTypeDeliver: {
|
|
|
|
|
if (!oldGroupThread) {
|
|
|
|
|
OWSFail(@"%@ ignoring quit group message from unknown group.", self.tag);
|
|
|
|
|
OWSFail(@"%@ ignoring deliver group message from unknown group.", self.tag);
|
|
|
|
|
return nil;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -933,17 +921,21 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
envelopeAddress(envelope),
|
|
|
|
|
groupId,
|
|
|
|
|
(unsigned long)timestamp);
|
|
|
|
|
incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timestamp
|
|
|
|
|
TSIncomingMessage *incomingMessage =
|
|
|
|
|
[[TSIncomingMessage alloc] initWithTimestamp:timestamp
|
|
|
|
|
inThread:oldGroupThread
|
|
|
|
|
authorId:envelope.source
|
|
|
|
|
sourceDeviceId:envelope.sourceDevice
|
|
|
|
|
messageBody:body
|
|
|
|
|
attachmentIds:attachmentIds
|
|
|
|
|
expiresInSeconds:dataMessage.expireTimer];
|
|
|
|
|
|
|
|
|
|
[incomingMessage saveWithTransaction:transaction];
|
|
|
|
|
thread = oldGroupThread;
|
|
|
|
|
break;
|
|
|
|
|
[self finalizeIncomingMessage:incomingMessage
|
|
|
|
|
thread:oldGroupThread
|
|
|
|
|
envelope:envelope
|
|
|
|
|
dataMessage:dataMessage
|
|
|
|
|
attachmentIds:attachmentIds
|
|
|
|
|
transaction:transaction];
|
|
|
|
|
return incomingMessage;
|
|
|
|
|
}
|
|
|
|
|
default: {
|
|
|
|
|
DDLogWarn(@"%@ Ignoring unknown group message type: %d", self.tag, (int)dataMessage.group.type);
|
|
|
|
@ -963,26 +955,57 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
self.tag,
|
|
|
|
|
envelopeAddress(envelope),
|
|
|
|
|
(unsigned long)timestamp);
|
|
|
|
|
TSContactThread *cThread = [TSContactThread getOrCreateThreadWithContactId:envelope.source
|
|
|
|
|
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:envelope.source
|
|
|
|
|
transaction:transaction
|
|
|
|
|
relay:envelope.relay];
|
|
|
|
|
|
|
|
|
|
incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timestamp
|
|
|
|
|
inThread:cThread
|
|
|
|
|
authorId:[cThread contactIdentifier]
|
|
|
|
|
TSIncomingMessage *incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timestamp
|
|
|
|
|
inThread:thread
|
|
|
|
|
authorId:[thread contactIdentifier]
|
|
|
|
|
sourceDeviceId:envelope.sourceDevice
|
|
|
|
|
messageBody:body
|
|
|
|
|
attachmentIds:attachmentIds
|
|
|
|
|
expiresInSeconds:dataMessage.expireTimer];
|
|
|
|
|
|
|
|
|
|
[incomingMessage saveWithTransaction:transaction];
|
|
|
|
|
thread = cThread;
|
|
|
|
|
[self finalizeIncomingMessage:incomingMessage
|
|
|
|
|
thread:thread
|
|
|
|
|
envelope:envelope
|
|
|
|
|
dataMessage:dataMessage
|
|
|
|
|
attachmentIds:attachmentIds
|
|
|
|
|
transaction:transaction];
|
|
|
|
|
return incomingMessage;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)finalizeIncomingMessage:(TSIncomingMessage *)incomingMessage
|
|
|
|
|
thread:(TSThread *)thread
|
|
|
|
|
envelope:(OWSSignalServiceProtosEnvelope *)envelope
|
|
|
|
|
dataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
|
|
|
|
|
attachmentIds:(NSArray<NSString *> *)attachmentIds
|
|
|
|
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
|
|
|
{
|
|
|
|
|
OWSAssert(thread);
|
|
|
|
|
OWSAssert(incomingMessage);
|
|
|
|
|
OWSAssert(envelope);
|
|
|
|
|
OWSAssert(dataMessage);
|
|
|
|
|
OWSAssert(attachmentIds);
|
|
|
|
|
OWSAssert(transaction);
|
|
|
|
|
|
|
|
|
|
OWSAssert([TSAccountManager isRegistered]);
|
|
|
|
|
NSString *localNumber = [TSAccountManager localNumber];
|
|
|
|
|
NSString *body = dataMessage.body;
|
|
|
|
|
uint64_t timestamp = envelope.timestamp;
|
|
|
|
|
|
|
|
|
|
if (!thread) {
|
|
|
|
|
OWSFail(@"%@ Can't finalize without thread", self.tag);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!incomingMessage) {
|
|
|
|
|
OWSFail(@"%@ Can't finalize missing message", self.tag);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[incomingMessage saveWithTransaction:transaction];
|
|
|
|
|
|
|
|
|
|
if (thread && incomingMessage) {
|
|
|
|
|
// Any messages sent from the current user - from this device or another - should be
|
|
|
|
|
// automatically marked as read.
|
|
|
|
|
BOOL shouldMarkMessageAsRead = [envelope.source isEqualToString:localNumber];
|
|
|
|
@ -1025,9 +1048,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|
|
|
|
transaction:transaction];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return incomingMessage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#pragma mark - helpers
|
|
|
|
|
|
|
|
|
|
- (BOOL)isDataMessageGroupAvatarUpdate:(OWSSignalServiceProtosDataMessage *)dataMessage
|
|
|
|
|