/// <summary> /// /// </summary> /// <param name="metadata"></param> /// <param name="content"></param> /// <returns></returns> /// <exception cref="ProtocolInvalidMessageException"></exception> /// <exception cref="ProtocolInvalidKeyException"></exception> private static SignalServiceSyncMessage CreateSynchronizeMessage(SignalServiceMetadata metadata, SyncMessage content) { if (content.Sent != null) { var unidentifiedStatuses = new Dictionary <SignalServiceAddress, bool>(); SyncMessage.Types.Sent sentContent = content.Sent; SignalServiceDataMessage dataMessage = CreateSignalServiceMessage(metadata, sentContent.Message); SignalServiceAddress? address = SignalServiceAddress.IsValidAddress(sentContent.DestinationUuid, sentContent.Destination) ? new SignalServiceAddress(UuidUtil.ParseOrNull(sentContent.DestinationUuid), sentContent.Destination) : null; if (address == null && dataMessage.Group == null) { throw new ProtocolInvalidMessageException(new InvalidMessageException("SyncMessage missing both destination and group ID!"), null, 0); } foreach (var status in sentContent.UnidentifiedStatus) { if (SignalServiceAddress.IsValidAddress(status.DestinationUuid, status.Destination)) { SignalServiceAddress recipient = new SignalServiceAddress(UuidUtil.ParseOrNull(status.DestinationUuid), status.Destination); unidentifiedStatuses.Add(recipient, status.Unidentified); } else { logger.LogWarning("Encountered an invalid UnidentifiedDeliveryStatus in a SentTranscript! Ignoring."); } } return(SignalServiceSyncMessage.ForSentTranscript(new SentTranscriptMessage(address !, (long)sentContent.Timestamp, CreateSignalServiceMessage(metadata, sentContent.Message), (long)sentContent.ExpirationStartTimestamp, unidentifiedStatuses, sentContent.IsRecipientUpdate))); } if (content.Request != null) { return(SignalServiceSyncMessage.ForRequest(new RequestMessage(content.Request))); } if (content.Read.Count > 0) { List <ReadMessage> readMessages = new List <ReadMessage>(); foreach (SyncMessage.Types.Read read in content.Read) { if (SignalServiceAddress.IsValidAddress(read.SenderUuid, read.Sender)) { SignalServiceAddress address = new SignalServiceAddress(UuidUtil.ParseOrNull(read.SenderUuid), read.Sender); readMessages.Add(new ReadMessage(address, (long)read.Timestamp)); } else { logger.LogWarning("Encountered an invalid ReadMessage! Ignoring."); } } return(SignalServiceSyncMessage.ForRead(readMessages)); } if (content.ViewOnceOpen != null) { if (SignalServiceAddress.IsValidAddress(content.ViewOnceOpen.SenderUuid, content.ViewOnceOpen.Sender)) { SignalServiceAddress address = new SignalServiceAddress(UuidUtil.ParseOrNull(content.ViewOnceOpen.SenderUuid), content.ViewOnceOpen.Sender); ViewOnceOpenMessage timerRead = new ViewOnceOpenMessage(address, (long)content.ViewOnceOpen.Timestamp); return(SignalServiceSyncMessage.ForViewOnceOpen(timerRead)); } else { throw new ProtocolInvalidMessageException(new InvalidMessageException("ViewOnceOpen message has no sender!"), null, 0); } } if (content.Contacts != null) { AttachmentPointer pointer = content.Contacts.Blob; return(SignalServiceSyncMessage.ForContacts(new ContactsMessage(CreateAttachmentPointer(pointer), content.Contacts.Complete))); } if (content.Groups != null) { AttachmentPointer pointer = content.Groups.Blob; return(SignalServiceSyncMessage.ForGroups(CreateAttachmentPointer(pointer))); } if (content.Verified != null) { if (SignalServiceAddress.IsValidAddress(content.Verified.DestinationUuid, content.Verified.Destination)) { try { Verified verified = content.Verified; SignalServiceAddress destination = new SignalServiceAddress(UuidUtil.ParseOrNull(verified.DestinationUuid), verified.Destination); IdentityKey identityKey = new IdentityKey(verified.IdentityKey.ToByteArray(), 0); VerifiedMessage.VerifiedState verifiedState; if (verified.State == Verified.Types.State.Default) { verifiedState = VerifiedMessage.VerifiedState.Default; } else if (verified.State == Verified.Types.State.Verified) { verifiedState = VerifiedMessage.VerifiedState.Verified; } else if (verified.State == Verified.Types.State.Unverified) { verifiedState = VerifiedMessage.VerifiedState.Unverified; } else { throw new ProtocolInvalidMessageException(new InvalidMessageException($"Unknown state: {(int)verified.State}"), metadata.Sender.GetIdentifier(), metadata.SenderDevice); } return(SignalServiceSyncMessage.ForVerified(new VerifiedMessage(destination, identityKey, verifiedState, Util.CurrentTimeMillis()))); } catch (InvalidKeyException ex) { throw new ProtocolInvalidKeyException(ex, metadata.Sender.GetIdentifier(), metadata.SenderDevice); } } else { throw new ProtocolInvalidMessageException(new InvalidMessageException("Verified message has no sender!"), null, 0); } } if (content.StickerPackOperation.Count > 0) { List <StickerPackOperationMessage> operations = new List <StickerPackOperationMessage>(); foreach (var operation in content.StickerPackOperation) { byte[]? packId = operation.HasPackId ? operation.PackId.ToByteArray() : null; byte[]? packKey = operation.HasPackKey ? operation.PackKey.ToByteArray() : null; StickerPackOperationMessage.OperationType?type = null; if (operation.HasType) { switch (operation.Type) { case SyncMessage.Types.StickerPackOperation.Types.Type.Install: type = StickerPackOperationMessage.OperationType.Install; break; case SyncMessage.Types.StickerPackOperation.Types.Type.Remove: type = StickerPackOperationMessage.OperationType.Remove; break; } } operations.Add(new StickerPackOperationMessage(packId, packKey, type)); } return(SignalServiceSyncMessage.ForStickerPackOperations(operations)); } if (content.Blocked != null) { List <string> numbers = content.Blocked.Numbers.ToList(); List <string> uuids = content.Blocked.Uuids.ToList(); List <SignalServiceAddress> addresses = new List <SignalServiceAddress>(numbers.Count + uuids.Count); List <byte[]> groupIds = new List <byte[]>(content.Blocked.GroupIds.Count); foreach (string e164 in numbers) { SignalServiceAddress?address = SignalServiceAddress.FromRaw(null, e164); if (address != null) { addresses.Add(address); } } foreach (string uuid in uuids) { SignalServiceAddress?address = SignalServiceAddress.FromRaw(uuid, null); if (address != null) { addresses.Add(address); } } foreach (ByteString groupId in content.Blocked.GroupIds) { groupIds.Add(groupId.ToByteArray()); } return(SignalServiceSyncMessage.ForBlocked(new BlockedListMessage(addresses, groupIds))); } if (content.Configuration != null) { bool?readReceipts = content.Configuration.HasReadReceipts ? content.Configuration.ReadReceipts : (bool?)null; bool?unidentifiedDeliveryIndicators = content.Configuration.HasUnidentifiedDeliveryIndicators ? content.Configuration.UnidentifiedDeliveryIndicators : (bool?)null; bool?typingIndicators = content.Configuration.HasTypingIndicators ? content.Configuration.TypingIndicators : (bool?)null; bool?linkPreviews = content.Configuration.HasLinkPreviews ? content.Configuration.LinkPreviews : (bool?)null; return(SignalServiceSyncMessage.ForConfiguration(new ConfigurationMessage(readReceipts, unidentifiedDeliveryIndicators, typingIndicators, linkPreviews))); } return(SignalServiceSyncMessage.Empty()); }