Document/clean up SendableMessage
This commit is contained in:
parent
408cf0c14c
commit
a097061fae
@ -123,23 +123,21 @@ public final class OutgoingEditMessage: TransientOutgoingMessage {
|
||||
)
|
||||
}
|
||||
|
||||
override public func buildTranscriptSyncMessage(
|
||||
override public func buildSyncTranscriptMessage(
|
||||
localThread: TSContactThread,
|
||||
transaction: DBWriteTransaction,
|
||||
) -> OutgoingSyncMessage? {
|
||||
guard let thread = thread(tx: transaction) else {
|
||||
owsFailDebug("Missing thread for interaction.")
|
||||
return nil
|
||||
tx: DBWriteTransaction,
|
||||
) throws -> OutgoingSyncMessage {
|
||||
guard let thread = thread(tx: tx) else {
|
||||
throw OWSAssertionError("missing thread for interaction")
|
||||
}
|
||||
|
||||
let transcript = OutgoingEditMessageSyncTranscript(
|
||||
return OutgoingEditMessageSyncTranscript(
|
||||
localThread: localThread,
|
||||
messageThread: thread,
|
||||
message: self,
|
||||
isRecipientUpdate: false,
|
||||
tx: transaction,
|
||||
tx: tx,
|
||||
)
|
||||
return transcript
|
||||
}
|
||||
|
||||
/// This override is required to properly update the correct interaction row
|
||||
|
||||
@ -61,7 +61,7 @@ final class OutgoingStaticMessage: TransientOutgoingMessage {
|
||||
|
||||
override func shouldSyncTranscript() -> Bool { false }
|
||||
|
||||
override func buildPlainTextData(_ thread: TSThread, transaction: DBWriteTransaction) -> Data? {
|
||||
override func buildPlaintextData(inThread thread: TSThread, tx: DBWriteTransaction) throws -> Data {
|
||||
return self.plaintextData
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,7 +196,9 @@ NS_DESIGNATED_INITIALIZER NS_SWIFT_NAME(init(grdbId:uniqueId:receivedAtTimestamp
|
||||
/**
|
||||
* The data representation of this message, to be encrypted, before being sent.
|
||||
*/
|
||||
- (nullable NSData *)buildPlainTextData:(TSThread *)thread transaction:(DBWriteTransaction *)transaction;
|
||||
- (nullable NSData *)buildPlaintextDataInThread:(TSThread *)thread
|
||||
tx:(DBWriteTransaction *)transaction
|
||||
error:(NSError **)error NS_SWIFT_NAME(buildPlaintextData(inThread:tx:));
|
||||
|
||||
/**
|
||||
* Intermediate protobuf representation
|
||||
@ -222,9 +224,10 @@ NS_DESIGNATED_INITIALIZER NS_SWIFT_NAME(init(grdbId:uniqueId:receivedAtTimestamp
|
||||
*/
|
||||
- (BOOL)shouldSyncTranscript;
|
||||
|
||||
- (nullable OWSOutgoingSyncMessage *)buildTranscriptSyncMessageWithLocalThread:(TSContactThread *)localThread
|
||||
- (nullable OWSOutgoingSyncMessage *)buildSyncTranscriptMessageWithLocalThread:(TSContactThread *)localThread
|
||||
transaction:(DBWriteTransaction *)transaction
|
||||
NS_SWIFT_NAME(buildTranscriptSyncMessage(localThread:transaction:));
|
||||
error:(NSError **)error
|
||||
NS_SWIFT_NAME(buildSyncTranscriptMessage(localThread:tx:));
|
||||
|
||||
#pragma mark - Update With... Methods
|
||||
|
||||
|
||||
@ -546,23 +546,11 @@ NSUInteger const TSOutgoingMessageSchemaVersion = 1;
|
||||
return contentBuilder;
|
||||
}
|
||||
|
||||
- (nullable NSData *)buildPlainTextData:(TSThread *)thread transaction:(DBWriteTransaction *)transaction
|
||||
- (nullable NSData *)buildPlaintextDataInThread:(TSThread *)thread
|
||||
tx:(DBWriteTransaction *)transaction
|
||||
error:(NSError **)error
|
||||
{
|
||||
SSKProtoContentBuilder *_Nullable contentBuilder = [self contentBuilderWithThread:thread transaction:transaction];
|
||||
if (!contentBuilder) {
|
||||
OWSFailDebug(@"could not build protobuf.");
|
||||
return nil;
|
||||
}
|
||||
|
||||
[contentBuilder setPniSignatureMessage:[self buildPniSignatureMessageIfNeededWithTransaction:transaction]];
|
||||
|
||||
NSError *error;
|
||||
NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error];
|
||||
if (error || !contentData) {
|
||||
OWSFailDebug(@"could not serialize protobuf: %@", error);
|
||||
return nil;
|
||||
}
|
||||
return contentData;
|
||||
return [self _buildPlaintextDataInThread:thread tx:transaction error:error];
|
||||
}
|
||||
|
||||
- (BOOL)shouldSyncTranscript
|
||||
@ -570,10 +558,11 @@ NSUInteger const TSOutgoingMessageSchemaVersion = 1;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (nullable OWSOutgoingSyncMessage *)buildTranscriptSyncMessageWithLocalThread:(TSContactThread *)localThread
|
||||
- (nullable OWSOutgoingSyncMessage *)buildSyncTranscriptMessageWithLocalThread:(TSContactThread *)localThread
|
||||
transaction:(DBWriteTransaction *)transaction
|
||||
error:(NSError **)error
|
||||
{
|
||||
return [self _buildTranscriptSyncMessageWithLocalThread:localThread tx:transaction];
|
||||
return [self _buildSyncTranscriptMessageWithLocalThread:localThread tx:transaction error:error];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -371,6 +371,17 @@ extension TSOutgoingMessage {
|
||||
@objc
|
||||
public var isStorySend: Bool { isGroupStoryReply }
|
||||
|
||||
@objc
|
||||
func _buildPlaintextData(inThread thread: TSThread, tx: DBWriteTransaction) throws -> Data {
|
||||
guard let contentBuilder = self.contentBuilder(thread: thread, transaction: tx) else {
|
||||
throw OWSAssertionError("couldn't build protobuf")
|
||||
}
|
||||
if let pniSignatureMessage = self.buildPniSignatureMessageIfNeeded(tx: tx) {
|
||||
contentBuilder.setPniSignatureMessage(pniSignatureMessage)
|
||||
}
|
||||
return try contentBuilder.buildSerializedData()
|
||||
}
|
||||
|
||||
@objc
|
||||
func _dataMessageBuilder(thread: TSThread, tx: DBReadTransaction) -> SSKProtoDataMessageBuilder? {
|
||||
let builder = SSKProtoDataMessage.builder()
|
||||
@ -535,11 +546,11 @@ extension TSOutgoingMessage {
|
||||
}
|
||||
|
||||
@objc
|
||||
func _buildTranscriptSyncMessage(localThread: TSContactThread, tx: DBWriteTransaction) -> OutgoingSyncMessage? {
|
||||
func _buildSyncTranscriptMessage(localThread: TSContactThread, tx: DBWriteTransaction) throws -> OutgoingSyncMessage {
|
||||
owsAssertDebug(self.shouldSyncTranscript())
|
||||
|
||||
guard let messageThread = self.thread(tx: tx) else {
|
||||
return nil
|
||||
throw OWSAssertionError("missing thread for sent message")
|
||||
}
|
||||
|
||||
return OutgoingSentMessageTranscript(
|
||||
@ -551,8 +562,7 @@ extension TSOutgoingMessage {
|
||||
)
|
||||
}
|
||||
|
||||
@objc(buildPniSignatureMessageIfNeededWithTransaction:)
|
||||
func buildPniSignatureMessageIfNeeded(transaction tx: DBReadTransaction) -> SSKProtoPniSignatureMessage? {
|
||||
private func buildPniSignatureMessageIfNeeded(tx: DBReadTransaction) -> SSKProtoPniSignatureMessage? {
|
||||
guard recipientAddressStates?.count == 1 else {
|
||||
// This is probably a group message, nothing to be alarmed about.
|
||||
return nil
|
||||
|
||||
@ -9,18 +9,8 @@ import LibSignalClient
|
||||
// MARK: - Message "isXYZ" properties
|
||||
|
||||
extension TSOutgoingMessage {
|
||||
var isTransientSKDM: Bool {
|
||||
(self as? OutgoingSenderKeyDistributionMessage)?.isSentOnBehalfOfOnlineMessage ?? false
|
||||
}
|
||||
|
||||
var isResendRequest: Bool {
|
||||
self is OutgoingResendRequest
|
||||
}
|
||||
|
||||
var isSyncMessage: Bool { self is OutgoingSyncMessage }
|
||||
|
||||
var canSendToLocalAddress: Bool {
|
||||
return isSyncMessage ||
|
||||
return self is OutgoingSyncMessage ||
|
||||
self is OutgoingCallMessage ||
|
||||
self is OutgoingResendRequest ||
|
||||
self is OWSOutgoingResendResponse
|
||||
@ -471,7 +461,7 @@ public class MessageSender {
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
tx: DBReadTransaction,
|
||||
) throws -> [SignalServiceAddress] {
|
||||
if message.isSyncMessage {
|
||||
if message is OutgoingSyncMessage {
|
||||
return [localIdentifiers.aciAddress]
|
||||
}
|
||||
|
||||
@ -1149,7 +1139,7 @@ public class MessageSender {
|
||||
// transcript is sent.
|
||||
//
|
||||
// NOTE: This only applies to the 'note to self' conversation.
|
||||
if message.isSyncMessage {
|
||||
if message is OutgoingSyncMessage {
|
||||
return
|
||||
}
|
||||
let thread = SSKEnvironment.shared.databaseStorageRef.read { tx in message.thread(tx: tx) }
|
||||
@ -1203,9 +1193,7 @@ public class MessageSender {
|
||||
let messageSend = try await databaseStorage.awaitableWrite { tx in
|
||||
let localThread = TSContactThread.getOrCreateThread(withContactAddress: localIdentifiers.aciAddress, transaction: tx)
|
||||
|
||||
guard let transcript = message.buildTranscriptSyncMessage(localThread: localThread, transaction: tx) else {
|
||||
throw OWSAssertionError("Failed to build transcript")
|
||||
}
|
||||
let transcript = try message.buildSyncTranscriptMessage(localThread: localThread, tx: tx)
|
||||
|
||||
let serializedMessage = try buildAndRecordMessage(transcript, in: localThread, tx: tx)
|
||||
|
||||
@ -1233,9 +1221,7 @@ public class MessageSender {
|
||||
in thread: TSThread,
|
||||
tx: DBWriteTransaction,
|
||||
) throws -> SerializedMessage {
|
||||
guard let plaintextData = message.buildPlainTextData(thread, transaction: tx) else {
|
||||
throw OWSAssertionError("couldn't serialize message")
|
||||
}
|
||||
let plaintextData = try message.buildPlaintextData(inThread: thread, tx: tx)
|
||||
let messageSendLog = SSKEnvironment.shared.messageSendLogRef
|
||||
let payloadId = messageSendLog.recordPayload(plaintextData, for: message, tx: tx)
|
||||
return SerializedMessage(plaintextData: plaintextData, payloadId: payloadId)
|
||||
@ -1376,15 +1362,12 @@ public class MessageSender {
|
||||
messageSend: OWSMessageSend,
|
||||
sealedSenderParameters: SealedSenderParameters?,
|
||||
) async throws -> [DeviceMessage] {
|
||||
guard messageSend.message.encryptionStyle == .whisper || messageSend.message.isResendRequest else {
|
||||
throw OWSAssertionError("Unexpected message type")
|
||||
}
|
||||
return try await buildDeviceMessages(
|
||||
serviceId: messageSend.serviceId,
|
||||
isSelfSend: messageSend.isSelfSend,
|
||||
encryptionStyle: messageSend.message.encryptionStyle,
|
||||
buildPlaintextContent: { _, _ in messageSend.plaintextContent },
|
||||
isTransient: messageSend.message.isOnline || messageSend.message.isTransientSKDM,
|
||||
isTransient: messageSend.message.isOnline || (messageSend.message as? OutgoingSenderKeyDistributionMessage)?.isSentOnBehalfOfOnlineMessage == true,
|
||||
sealedSenderParameters: sealedSenderParameters,
|
||||
)
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ final class SealedSenderParameters {
|
||||
self.endorsement = endorsement
|
||||
}
|
||||
|
||||
/// Indicates desired behavior on the case of decryption error.
|
||||
/// Indicates desired behavior if decryption fails.
|
||||
var contentHint: SealedSenderContentHint {
|
||||
return message.contentHint
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ final class OWSOutgoingResendResponse: TransientOutgoingMessage {
|
||||
|
||||
override func envelopeGroupIdWithTransaction(_ transaction: DBReadTransaction) -> Data? { self.originalGroupId }
|
||||
|
||||
override func buildPlainTextData(_ thread: TSThread, transaction tx: DBWriteTransaction) -> Data? {
|
||||
override func buildPlaintextData(inThread thread: TSThread, tx: DBWriteTransaction) throws -> Data {
|
||||
owsAssertDebug(self.recipientAddresses().count == 1)
|
||||
|
||||
let contentBuilder: SSKProtoContentBuilder = {
|
||||
@ -188,12 +188,7 @@ final class OWSOutgoingResendResponse: TransientOutgoingMessage {
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
return try contentBuilder.buildSerializedData()
|
||||
} catch {
|
||||
owsFailDebug("Failed to build plaintext message: \(error)")
|
||||
return nil
|
||||
}
|
||||
return try contentBuilder.buildSerializedData()
|
||||
}
|
||||
|
||||
private func resentProtoBuilder(from plaintextData: Data) throws -> SSKProtoContentBuilder {
|
||||
|
||||
@ -92,14 +92,9 @@ final class OutgoingResendRequest: TransientOutgoingMessage {
|
||||
return self.failedEnvelopeGroupId
|
||||
}
|
||||
|
||||
override func buildPlainTextData(_ thread: TSThread, transaction: DBWriteTransaction) -> Data? {
|
||||
do {
|
||||
let decryptionErrorMessage = try DecryptionErrorMessage(bytes: decryptionErrorData)
|
||||
let plaintextContent = PlaintextContent(decryptionErrorMessage)
|
||||
return plaintextContent.serialize()
|
||||
} catch {
|
||||
owsFailDebug("Failed to build plaintext: \(error)")
|
||||
return nil
|
||||
}
|
||||
override func buildPlaintextData(inThread thread: TSThread, tx: DBWriteTransaction) throws -> Data {
|
||||
let decryptionErrorMessage = try DecryptionErrorMessage(bytes: decryptionErrorData)
|
||||
let plaintextContent = PlaintextContent(decryptionErrorMessage)
|
||||
return plaintextContent.serialize()
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,26 +15,32 @@ protocol SendableMessage {
|
||||
|
||||
var timestamp: UInt64 { get }
|
||||
|
||||
var isSyncMessage: Bool { get }
|
||||
|
||||
/// If true, this message corresponds to a story and should use story=true
|
||||
/// authentication and story account existence semantics.
|
||||
var isStorySend: Bool { get }
|
||||
|
||||
/// If true, this message should set the "online" flag to indicate that it
|
||||
/// should only be delivered if the recipient is currently online (e.g.,
|
||||
/// typing indicator messages).
|
||||
var isOnline: Bool { get }
|
||||
|
||||
var isTransientSKDM: Bool { get }
|
||||
|
||||
/// If true, this message should set the "urgent" flag (e.g., text messages
|
||||
/// are urgent and receipts are not).
|
||||
var isUrgent: Bool { get }
|
||||
|
||||
var isResendRequest: Bool { get }
|
||||
|
||||
var canSendToLocalAddress: Bool { get }
|
||||
|
||||
/// Indicates desired behavior if decryption fails.
|
||||
var contentHint: SealedSenderContentHint { get }
|
||||
|
||||
/// Indicates how the message should be encrypted.
|
||||
var encryptionStyle: EncryptionStyle { get }
|
||||
|
||||
func buildPlainTextData(_ thread: TSThread, transaction: DBWriteTransaction) -> Data?
|
||||
// TODO: Remove the thread parameter?
|
||||
/// Builds the serialized Content protobuf for this message.
|
||||
func buildPlaintextData(inThread thread: TSThread, tx: DBWriteTransaction) throws -> Data
|
||||
|
||||
// TODO: Merge this into the return value when sending a message.
|
||||
var wasSentToAnyRecipient: Bool { get }
|
||||
|
||||
func recipientAddresses() -> [SignalServiceAddress]
|
||||
@ -57,12 +63,23 @@ protocol SendableMessage {
|
||||
|
||||
func update(withViewedRecipient recipientAddress: SignalServiceAddress, deviceId: DeviceId, viewedTimestamp timestamp: UInt64, tx: DBWriteTransaction)
|
||||
|
||||
// TODO: Add SyncTranscriptableMessage protocol for these properties.
|
||||
|
||||
/// Indicates that this message needs a sync transcript.
|
||||
///
|
||||
/// If true, `buildSyncTranscriptMessage` will be invoked.
|
||||
func shouldSyncTranscript() -> Bool
|
||||
|
||||
/// Builds a sync transcript for this message.
|
||||
///
|
||||
/// Only invoked if `shouldSyncTranscript` returns true.
|
||||
func buildSyncTranscriptMessage(localThread: TSContactThread, tx: DBWriteTransaction) throws -> OutgoingSyncMessage
|
||||
|
||||
func thread(tx: DBReadTransaction) -> TSThread?
|
||||
|
||||
var shouldBeSaved: Bool { get }
|
||||
|
||||
/// True if this message should be stored in the Message Send Log.
|
||||
var shouldRecordSendLog: Bool { get }
|
||||
|
||||
var relatedUniqueIds: Set<String> { get }
|
||||
@ -73,11 +90,6 @@ protocol SendableMessage {
|
||||
|
||||
var isViewOnceMessage: Bool { get }
|
||||
|
||||
func buildTranscriptSyncMessage(
|
||||
localThread: TSContactThread,
|
||||
transaction: DBWriteTransaction,
|
||||
) -> OutgoingSyncMessage?
|
||||
|
||||
func update(withHasSyncedTranscript: Bool, transaction: DBWriteTransaction)
|
||||
|
||||
func allAttachments(transaction: DBReadTransaction) -> [ReferencedAttachment]
|
||||
|
||||
@ -125,19 +125,18 @@ public class OutgoingStoryMessage: TransientOutgoingMessage {
|
||||
|
||||
override public func shouldSyncTranscript() -> Bool { !skipSyncTranscript }
|
||||
|
||||
override public func buildTranscriptSyncMessage(
|
||||
override public func buildSyncTranscriptMessage(
|
||||
localThread: TSContactThread,
|
||||
transaction: DBWriteTransaction,
|
||||
) -> OutgoingSyncMessage? {
|
||||
guard let storyMessage = StoryMessage.anyFetch(uniqueId: storyMessageId, transaction: transaction) else {
|
||||
owsFailDebug("Missing story message")
|
||||
return nil
|
||||
tx: DBWriteTransaction,
|
||||
) throws -> OutgoingSyncMessage {
|
||||
guard let storyMessage = StoryMessage.anyFetch(uniqueId: storyMessageId, transaction: tx) else {
|
||||
throw OWSAssertionError("missing story message")
|
||||
}
|
||||
|
||||
return OutgoingStorySentMessageTranscript(
|
||||
localThread: localThread,
|
||||
storyMessage: storyMessage,
|
||||
transaction: transaction,
|
||||
transaction: tx,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -93,7 +93,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
|
||||
messageBuilder.timestamp = 100
|
||||
let message = messageBuilder.build(transaction: transaction)
|
||||
message.anyInsert(transaction: transaction)
|
||||
let messageData = message.buildPlainTextData(thread, transaction: transaction)!
|
||||
let messageData = try! message.buildPlaintextData(inThread: thread, tx: transaction)
|
||||
let content = try! SSKProtoContent(serializedData: messageData)
|
||||
XCTAssertNil(content.pniSignatureMessage)
|
||||
}
|
||||
@ -110,7 +110,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
|
||||
messageBuilder.timestamp = 100
|
||||
let message = messageBuilder.build(transaction: transaction)
|
||||
message.anyInsert(transaction: transaction)
|
||||
let messageData = message.buildPlainTextData(thread, transaction: transaction)!
|
||||
let messageData = try! message.buildPlaintextData(inThread: thread, tx: transaction)
|
||||
let content = try! SSKProtoContent(serializedData: messageData)
|
||||
|
||||
let messagePni = content.pniSignatureMessage!.pni
|
||||
@ -136,7 +136,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
|
||||
messageBuilder.timestamp = Date.ows_millisecondTimestamp()
|
||||
let message = messageBuilder.build(transaction: transaction)
|
||||
message.anyInsert(transaction: transaction)
|
||||
let messageData = message.buildPlainTextData(thread, transaction: transaction)!
|
||||
let messageData = try! message.buildPlaintextData(inThread: thread, tx: transaction)
|
||||
|
||||
message.updateWithSentRecipients([otherAci], wasSentByUD: true, transaction: transaction)
|
||||
|
||||
@ -176,7 +176,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
|
||||
messageBuilder.timestamp = Date.ows_millisecondTimestamp()
|
||||
let message = messageBuilder.build(transaction: transaction)
|
||||
message.anyInsert(transaction: transaction)
|
||||
let messageData = message.buildPlainTextData(thread, transaction: transaction)!
|
||||
let messageData = try! message.buildPlaintextData(inThread: thread, tx: transaction)
|
||||
|
||||
message.updateWithSentRecipients([otherAci], wasSentByUD: true, transaction: transaction)
|
||||
|
||||
@ -235,7 +235,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
|
||||
messageBuilder.timestamp = Date.ows_millisecondTimestamp()
|
||||
let message = messageBuilder.build(transaction: transaction)
|
||||
message.anyInsert(transaction: transaction)
|
||||
let messageData = message.buildPlainTextData(thread, transaction: transaction)!
|
||||
let messageData = try! message.buildPlaintextData(inThread: thread, tx: transaction)
|
||||
|
||||
message.updateWithSentRecipients([otherAci], wasSentByUD: false, transaction: transaction)
|
||||
|
||||
@ -275,7 +275,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
|
||||
messageBuilder.timestamp = Date.ows_millisecondTimestamp()
|
||||
let message = messageBuilder.build(transaction: transaction)
|
||||
message.anyInsert(transaction: transaction)
|
||||
let messageData = message.buildPlainTextData(thread, transaction: transaction)!
|
||||
let messageData = try! message.buildPlaintextData(inThread: thread, tx: transaction)
|
||||
|
||||
message.updateWithSentRecipients([otherAci], wasSentByUD: true, transaction: transaction)
|
||||
|
||||
@ -319,7 +319,7 @@ class TSOutgoingMessageTest: SSKBaseTest {
|
||||
messageBuilder.timestamp = Date.ows_millisecondTimestamp()
|
||||
message = messageBuilder.build(transaction: transaction)
|
||||
message.anyInsert(transaction: transaction)
|
||||
let messageData = message.buildPlainTextData(thread, transaction: transaction)!
|
||||
let messageData = try! message.buildPlaintextData(inThread: thread, tx: transaction)
|
||||
|
||||
message.updateWithSentRecipients([otherAci], wasSentByUD: true, transaction: transaction)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user