Restructure

This commit is contained in:
nielsandriesse 2020-11-25 16:15:16 +11:00
parent 178ab7e3e2
commit 5dfd4b1965
229 changed files with 1311 additions and 3304 deletions

View File

@ -69,8 +69,11 @@ target 'SessionMessagingKit' do
pod 'AFNetworking', inhibit_warnings: true pod 'AFNetworking', inhibit_warnings: true
pod 'CryptoSwift', :inhibit_warnings => true pod 'CryptoSwift', :inhibit_warnings => true
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
pod 'HKDFKit', :inhibit_warnings => true
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
pod 'PromiseKit', :inhibit_warnings => true pod 'PromiseKit', :inhibit_warnings => true
pod 'Reachability', :inhibit_warnings => true
pod 'SAMKeychain', :inhibit_warnings => true
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
pod 'SwiftProtobuf', '~> 1.5.0', :inhibit_warnings => true pod 'SwiftProtobuf', '~> 1.5.0', :inhibit_warnings => true
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true
@ -92,13 +95,16 @@ target 'SessionSnodeKit' do
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
pod 'PromiseKit', :inhibit_warnings => true pod 'PromiseKit', :inhibit_warnings => true
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true
end end
target 'SessionUtilitiesKit' do target 'SessionUtilitiesKit' do
pod 'AFNetworking', inhibit_warnings: true
pod 'CryptoSwift', :inhibit_warnings => true pod 'CryptoSwift', :inhibit_warnings => true
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
pod 'PromiseKit', :inhibit_warnings => true pod 'PromiseKit', :inhibit_warnings => true
pod 'SAMKeychain', :inhibit_warnings => true
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true
end end

View File

@ -230,6 +230,6 @@ SPEC CHECKSUMS:
YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665 YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
PODFILE CHECKSUM: 62df79698293257648cb6e60724f720f8477bd0f PODFILE CHECKSUM: b12682bc3bf974c758ec8e4b9838639f7ec51d5e
COCOAPODS: 1.10.0.rc.1 COCOAPODS: 1.10.0.rc.1

View File

@ -66,31 +66,31 @@
#import <SessionUtilitiesKit/DataSource.h> #import <SessionUtilitiesKit/DataSource.h>
#import <SessionUtilitiesKit/MIMETypeUtil.h> #import <SessionUtilitiesKit/MIMETypeUtil.h>
#import <SessionUtilitiesKit/NSData+Image.h> #import <SessionUtilitiesKit/NSData+Image.h>
#import <SignalUtilitiesKit/NSNotificationCenter+OWS.h> #import <SessionUtilitiesKit/NSNotificationCenter+OWS.h>
#import <SignalUtilitiesKit/NSString+SSK.h> #import <SignalUtilitiesKit/NSString+SSK.h>
#import <SignalUtilitiesKit/OWSBackgroundTask.h> #import <SessionMessagingKit/OWSBackgroundTask.h>
#import <SignalUtilitiesKit/OWSContactsOutputStream.h> #import <SignalUtilitiesKit/OWSContactsOutputStream.h>
#import <SignalUtilitiesKit/OWSDispatch.h> #import <SignalUtilitiesKit/OWSDispatch.h>
#import <SignalUtilitiesKit/OWSError.h> #import <SignalUtilitiesKit/OWSError.h>
#import <SessionUtilitiesKit/OWSFileSystem.h> #import <SessionUtilitiesKit/OWSFileSystem.h>
#import <SignalUtilitiesKit/OWSIdentityManager.h> #import <SessionMessagingKit/OWSIdentityManager.h>
#import <SignalUtilitiesKit/OWSMediaGalleryFinder.h> #import <SignalUtilitiesKit/OWSMediaGalleryFinder.h>
#import <SignalUtilitiesKit/OWSPrimaryStorage+SessionStore.h> #import <SignalUtilitiesKit/OWSPrimaryStorage+SessionStore.h>
#import <SignalUtilitiesKit/OWSRecipientIdentity.h> #import <SignalUtilitiesKit/OWSRecipientIdentity.h>
#import <SignalUtilitiesKit/SignalAccount.h> #import <SignalUtilitiesKit/SignalAccount.h>
#import <SignalUtilitiesKit/SignalRecipient.h> #import <SignalUtilitiesKit/SignalRecipient.h>
#import <SignalUtilitiesKit/TSAccountManager.h> #import <SessionMessagingKit/TSAccountManager.h>
#import <SessionMessagingKit/TSAttachment.h> #import <SessionMessagingKit/TSAttachment.h>
#import <SessionMessagingKit/TSAttachmentPointer.h> #import <SessionMessagingKit/TSAttachmentPointer.h>
#import <SessionMessagingKit/TSAttachmentStream.h> #import <SessionMessagingKit/TSAttachmentStream.h>
#import <SignalUtilitiesKit/TSContactThread.h> #import <SessionMessagingKit/TSContactThread.h>
#import <SignalUtilitiesKit/TSErrorMessage.h> #import <SignalUtilitiesKit/TSErrorMessage.h>
#import <SignalUtilitiesKit/TSGroupThread.h> #import <SessionMessagingKit/TSGroupThread.h>
#import <SignalUtilitiesKit/TSIncomingMessage.h> #import <SessionMessagingKit/TSIncomingMessage.h>
#import <SignalUtilitiesKit/TSInfoMessage.h> #import <SignalUtilitiesKit/TSInfoMessage.h>
#import <SignalUtilitiesKit/TSOutgoingMessage.h> #import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SignalUtilitiesKit/TSPreKeyManager.h> #import <SignalUtilitiesKit/TSPreKeyManager.h>
#import <SignalUtilitiesKit/TSThread.h> #import <SessionMessagingKit/TSThread.h>
#import <SignalUtilitiesKit/LKGroupUtilities.h> #import <SignalUtilitiesKit/LKGroupUtilities.h>
#import <SessionUtilitiesKit/UIImage+OWS.h> #import <SessionUtilitiesKit/UIImage+OWS.h>
#import <WebRTC/RTCAudioSession.h> #import <WebRTC/RTCAudioSession.h>

View File

@ -8,8 +8,8 @@
#import <SignalUtilitiesKit/Environment.h> #import <SignalUtilitiesKit/Environment.h>
#import <SignalUtilitiesKit/OWSPreferences.h> #import <SignalUtilitiesKit/OWSPreferences.h>
#import <SignalUtilitiesKit/UIUtil.h> #import <SignalUtilitiesKit/UIUtil.h>
#import <SignalUtilitiesKit/OWSPrimaryStorage.h> #import <SessionMessagingKit/OWSPrimaryStorage.h>
#import <SignalUtilitiesKit/TSDatabaseView.h> #import <SessionMessagingKit/TSDatabaseView.h>
@implementation AboutTableViewController @implementation AboutTableViewController

View File

@ -4,8 +4,8 @@
#import "AddToBlockListViewController.h" #import "AddToBlockListViewController.h"
#import "BlockListUIUtils.h" #import "BlockListUIUtils.h"
#import <SignalUtilitiesKit/SSKEnvironment.h> #import <SessionMessagingKit/SSKEnvironment.h>
#import <SignalUtilitiesKit/OWSBlockingManager.h> #import <SessionMessagingKit/OWSBlockingManager.h>
#import <SignalUtilitiesKit/SignalAccount.h> #import <SignalUtilitiesKit/SignalAccount.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -18,17 +18,17 @@
#import <SignalUtilitiesKit/OWSPreferences.h> #import <SignalUtilitiesKit/OWSPreferences.h>
#import <SignalUtilitiesKit/OWSProfileManager.h> #import <SignalUtilitiesKit/OWSProfileManager.h>
#import <SignalUtilitiesKit/VersionMigrations.h> #import <SignalUtilitiesKit/VersionMigrations.h>
#import <SignalUtilitiesKit/AppReadiness.h> #import <SessionMessagingKit/AppReadiness.h>
#import <SignalUtilitiesKit/NSUserDefaults+OWS.h> #import <SessionUtilitiesKit/NSUserDefaults+OWS.h>
#import <SignalUtilitiesKit/OWSDisappearingMessagesJob.h> #import <SessionMessagingKit/OWSDisappearingMessagesJob.h>
#import <SignalUtilitiesKit/OWSFailedAttachmentDownloadsJob.h> #import <SignalUtilitiesKit/OWSFailedAttachmentDownloadsJob.h>
#import <SignalUtilitiesKit/OWSFailedMessagesJob.h> #import <SignalUtilitiesKit/OWSFailedMessagesJob.h>
#import <SignalUtilitiesKit/OWSMath.h> #import <SignalUtilitiesKit/OWSMath.h>
#import <SignalUtilitiesKit/OWSReadReceiptManager.h> #import <SessionMessagingKit/OWSReadReceiptManager.h>
#import <SignalUtilitiesKit/SSKEnvironment.h> #import <SessionMessagingKit/SSKEnvironment.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <SignalUtilitiesKit/TSAccountManager.h> #import <SessionMessagingKit/TSAccountManager.h>
#import <SignalUtilitiesKit/TSDatabaseView.h> #import <SessionMessagingKit/TSDatabaseView.h>
#import <SignalUtilitiesKit/TSPreKeyManager.h> #import <SignalUtilitiesKit/TSPreKeyManager.h>
#import <YapDatabase/YapDatabaseCryptoUtils.h> #import <YapDatabase/YapDatabaseCryptoUtils.h>
#import <sys/utsname.h> #import <sys/utsname.h>

View File

@ -10,8 +10,8 @@
#import <SignalUtilitiesKit/UIUtil.h> #import <SignalUtilitiesKit/UIUtil.h>
#import <SignalUtilitiesKit/TSGroupModel.h> #import <SignalUtilitiesKit/TSGroupModel.h>
#import <SignalUtilitiesKit/TSGroupThread.h> #import <SessionMessagingKit/TSGroupThread.h>
#import <SignalUtilitiesKit/TSThread.h> #import <SessionMessagingKit/TSThread.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -32,7 +32,7 @@
#import "TSGroupThread.h" #import "TSGroupThread.h"
#import "TSIncomingMessage.h" #import "TSIncomingMessage.h"
#import "TSInfoMessage.h" #import "TSInfoMessage.h"
#import <SignalUtilitiesKit/TSInvalidIdentityKeyErrorMessage.h> #import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
#import "UIFont+OWS.h" #import "UIFont+OWS.h"
#import "UIViewController+Permissions.h" #import "UIViewController+Permissions.h"
#import <AVFoundation/AVFoundation.h> #import <AVFoundation/AVFoundation.h>
@ -53,15 +53,15 @@
#import <SessionUtilitiesKit/MIMETypeUtil.h> #import <SessionUtilitiesKit/MIMETypeUtil.h>
#import <SignalUtilitiesKit/NSString+SSK.h> #import <SignalUtilitiesKit/NSString+SSK.h>
#import <SignalUtilitiesKit/OWSAttachmentDownloads.h> #import <SignalUtilitiesKit/OWSAttachmentDownloads.h>
#import <SignalUtilitiesKit/OWSBlockingManager.h> #import <SessionMessagingKit/OWSBlockingManager.h>
#import <SignalUtilitiesKit/OWSDisappearingMessagesConfiguration.h> #import <SessionMessagingKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalUtilitiesKit/OWSIdentityManager.h> #import <SessionMessagingKit/OWSIdentityManager.h>
#import <SignalUtilitiesKit/OWSMessageUtils.h> #import <SignalUtilitiesKit/OWSMessageUtils.h>
#import <SignalUtilitiesKit/OWSPrimaryStorage.h> #import <SessionMessagingKit/OWSPrimaryStorage.h>
#import <SignalUtilitiesKit/OWSPrimaryStorage+Loki.h> #import <SignalUtilitiesKit/OWSPrimaryStorage+Loki.h>
#import <SignalUtilitiesKit/OWSReadReceiptManager.h> #import <SessionMessagingKit/OWSReadReceiptManager.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <SignalUtilitiesKit/TSAccountManager.h> #import <SessionMessagingKit/TSAccountManager.h>
#import <SignalUtilitiesKit/TSGroupModel.h> #import <SignalUtilitiesKit/TSGroupModel.h>
#import <SignalUtilitiesKit/TSInvalidIdentityKeyReceivingErrorMessage.h> #import <SignalUtilitiesKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
#import <SignalUtilitiesKit/TSQuotedMessage.h> #import <SignalUtilitiesKit/TSQuotedMessage.h>

View File

@ -15,7 +15,7 @@
#import <SignalUtilitiesKit/NSString+SSK.h> #import <SignalUtilitiesKit/NSString+SSK.h>
#import <SignalUtilitiesKit/TSInteraction.h> #import <SignalUtilitiesKit/TSInteraction.h>
#import <SignalUtilitiesKit/SSKEnvironment.h> #import <SessionMessagingKit/SSKEnvironment.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -11,14 +11,14 @@
#import <SignalCoreKit/NSDate+OWS.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalUtilitiesKit/OWSUnreadIndicator.h> #import <SignalUtilitiesKit/OWSUnreadIndicator.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <SignalUtilitiesKit/OWSBlockingManager.h> #import <SessionMessagingKit/OWSBlockingManager.h>
#import <SignalUtilitiesKit/OWSPrimaryStorage.h> #import <SessionMessagingKit/OWSPrimaryStorage.h>
#import <SignalUtilitiesKit/SSKEnvironment.h> #import <SessionMessagingKit/SSKEnvironment.h>
#import <SignalUtilitiesKit/TSDatabaseView.h> #import <SessionMessagingKit/TSDatabaseView.h>
#import <SignalUtilitiesKit/TSIncomingMessage.h> #import <SessionMessagingKit/TSIncomingMessage.h>
#import <SignalUtilitiesKit/TSOutgoingMessage.h> #import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SignalUtilitiesKit/TSThread.h> #import <SessionMessagingKit/TSThread.h>
#import <SignalUtilitiesKit/TSGroupThread.h> #import <SessionMessagingKit/TSGroupThread.h>
#import <SignalUtilitiesKit/TSGroupModel.h> #import <SignalUtilitiesKit/TSGroupModel.h>
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseAutoView.h> #import <YapDatabase/YapDatabaseAutoView.h>

View File

@ -8,7 +8,7 @@
#import <SignalUtilitiesKit/Environment.h> #import <SignalUtilitiesKit/Environment.h>
#import <SignalUtilitiesKit/OWSProfileManager.h> #import <SignalUtilitiesKit/OWSProfileManager.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <SignalUtilitiesKit/OWSIdentityManager.h> #import <SessionMessagingKit/OWSIdentityManager.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -9,8 +9,8 @@
#import "Session-Swift.h" #import "Session-Swift.h"
#import <PromiseKit/AnyPromise.h> #import <PromiseKit/AnyPromise.h>
#import <SignalCoreKit/Randomness.h> #import <SignalCoreKit/Randomness.h>
#import <SignalUtilitiesKit/OWSIdentityManager.h> #import <SessionMessagingKit/OWSIdentityManager.h>
#import <SignalUtilitiesKit/YapDatabaseConnection+OWS.h> #import <SessionMessagingKit/YapDatabaseConnection+OWS.h>
@import CloudKit; @import CloudKit;

View File

@ -10,13 +10,13 @@
#import <SignalCoreKit/NSData+OWS.h> #import <SignalCoreKit/NSData+OWS.h>
#import <SignalCoreKit/NSDate+OWS.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalCoreKit/Threading.h> #import <SignalCoreKit/Threading.h>
#import <SignalUtilitiesKit/OWSBackgroundTask.h> #import <SessionMessagingKit/OWSBackgroundTask.h>
#import <SignalUtilitiesKit/OWSError.h> #import <SignalUtilitiesKit/OWSError.h>
#import <SessionUtilitiesKit/OWSFileSystem.h> #import <SessionUtilitiesKit/OWSFileSystem.h>
#import <SessionMessagingKit/TSAttachment.h> #import <SessionMessagingKit/TSAttachment.h>
#import <SessionMessagingKit/TSAttachmentStream.h> #import <SessionMessagingKit/TSAttachmentStream.h>
#import <SignalUtilitiesKit/TSMessage.h> #import <SignalUtilitiesKit/TSMessage.h>
#import <SignalUtilitiesKit/TSThread.h> #import <SessionMessagingKit/TSThread.h>
@import CloudKit; @import CloudKit;

View File

@ -9,11 +9,11 @@
#import "Session-Swift.h" #import "Session-Swift.h"
#import <PromiseKit/AnyPromise.h> #import <PromiseKit/AnyPromise.h>
#import <SignalCoreKit/NSData+OWS.h> #import <SignalCoreKit/NSData+OWS.h>
#import <SignalUtilitiesKit/OWSBackgroundTask.h> #import <SessionMessagingKit/OWSBackgroundTask.h>
#import <SessionUtilitiesKit/OWSFileSystem.h> #import <SessionUtilitiesKit/OWSFileSystem.h>
#import <SessionMessagingKit/TSAttachment.h> #import <SessionMessagingKit/TSAttachment.h>
#import <SignalUtilitiesKit/TSMessage.h> #import <SignalUtilitiesKit/TSMessage.h>
#import <SignalUtilitiesKit/TSThread.h> #import <SessionMessagingKit/TSThread.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -23,12 +23,12 @@
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <SignalUtilitiesKit/UIUtil.h> #import <SignalUtilitiesKit/UIUtil.h>
#import <SignalUtilitiesKit/OWSDisappearingConfigurationUpdateInfoMessage.h> #import <SignalUtilitiesKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
#import <SignalUtilitiesKit/OWSDisappearingMessagesConfiguration.h> #import <SessionMessagingKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalUtilitiesKit/OWSPrimaryStorage.h> #import <SessionMessagingKit/OWSPrimaryStorage.h>
#import <SignalUtilitiesKit/TSGroupThread.h> #import <SessionMessagingKit/TSGroupThread.h>
#import <SignalUtilitiesKit/TSOutgoingMessage.h> #import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SignalUtilitiesKit/TSThread.h> #import <SessionMessagingKit/TSThread.h>
@import ContactsUI; @import ContactsUI;
@import PromiseKit; @import PromiseKit;

View File

@ -7,17 +7,17 @@
#import <SignalCoreKit/NSDate+OWS.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalUtilitiesKit/OWSProfileManager.h> #import <SignalUtilitiesKit/OWSProfileManager.h>
#import <SignalUtilitiesKit/OWSUserProfile.h> #import <SignalUtilitiesKit/OWSUserProfile.h>
#import <SignalUtilitiesKit/AppReadiness.h> #import <SessionMessagingKit/AppReadiness.h>
#import <SignalUtilitiesKit/AppVersion.h> #import <SignalUtilitiesKit/AppVersion.h>
#import <SessionUtilitiesKit/SessionUtilitiesKit.h> #import <SessionUtilitiesKit/SessionUtilitiesKit.h>
#import <SessionUtilitiesKit/OWSFileSystem.h> #import <SessionUtilitiesKit/OWSFileSystem.h>
#import <SignalUtilitiesKit/OWSPrimaryStorage.h> #import <SessionMessagingKit/OWSPrimaryStorage.h>
#import <SessionMessagingKit/TSAttachmentStream.h> #import <SessionMessagingKit/TSAttachmentStream.h>
#import <SignalUtilitiesKit/TSInteraction.h> #import <SignalUtilitiesKit/TSInteraction.h>
#import <SignalUtilitiesKit/TSMessage.h> #import <SignalUtilitiesKit/TSMessage.h>
#import <SignalUtilitiesKit/TSQuotedMessage.h> #import <SignalUtilitiesKit/TSQuotedMessage.h>
#import <SignalUtilitiesKit/TSThread.h> #import <SessionMessagingKit/TSThread.h>
#import <SignalUtilitiesKit/YapDatabaseTransaction+OWS.h> #import <SessionMessagingKit/YapDatabaseTransaction+OWS.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>

View File

@ -2,7 +2,7 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/SSKJobRecord.h> #import <SessionMessagingKit/SSKJobRecord.h>
@class TSContactThread; @class TSContactThread;

View File

@ -3,7 +3,7 @@
// //
#import "OWSSessionResetJobRecord.h" #import "OWSSessionResetJobRecord.h"
#import <SignalUtilitiesKit/TSContactThread.h> #import <SessionMessagingKit/TSContactThread.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -13,7 +13,7 @@
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <SignalUtilitiesKit/NSString+SSK.h> #import <SignalUtilitiesKit/NSString+SSK.h>
#import <SignalUtilitiesKit/ThreadUtil.h> #import <SignalUtilitiesKit/ThreadUtil.h>
#import <SignalUtilitiesKit/OWSReadReceiptManager.h> #import <SessionMessagingKit/OWSReadReceiptManager.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -9,9 +9,9 @@
#import <SignalCoreKit/Threading.h> #import <SignalCoreKit/Threading.h>
#import <SignalUtilitiesKit/DebugLogger.h> #import <SignalUtilitiesKit/DebugLogger.h>
#import <SignalUtilitiesKit/Environment.h> #import <SignalUtilitiesKit/Environment.h>
#import <SignalUtilitiesKit/OWSPrimaryStorage.h> #import <SessionMessagingKit/OWSPrimaryStorage.h>
#import <SignalUtilitiesKit/TSContactThread.h> #import <SessionMessagingKit/TSContactThread.h>
#import <SignalUtilitiesKit/TSGroupThread.h> #import <SessionMessagingKit/TSGroupThread.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -2,15 +2,10 @@ import SessionProtocolKit
public struct Configuration { public struct Configuration {
public let storage: SessionMessagingKitStorageProtocol public let storage: SessionMessagingKitStorageProtocol
public let messageSenderDelegate: MessageSenderDelegate
public let messageReceiverDelegate: MessageReceiverDelegate
public let signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore public let signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore
public let identityKeyStore: IdentityKeyStore public let identityKeyStore: IdentityKeyStore
public let sessionRestorationImplementation: SessionRestorationProtocol public let sessionRestorationImplementation: SessionRestorationProtocol
public let certificateValidator: SMKCertificateValidator public let certificateValidator: SMKCertificateValidator
public let openGroupAPIDelegate: OpenGroupAPIDelegate
public let pnServerURL: String
public let pnServerPublicKey: String
internal static var shared: Configuration! internal static var shared: Configuration!
} }
@ -19,27 +14,17 @@ public enum SNMessagingKit { // Just to make the external API nice
public static func configure( public static func configure(
storage: SessionMessagingKitStorageProtocol, storage: SessionMessagingKitStorageProtocol,
messageSenderDelegate: MessageSenderDelegate,
messageReceiverDelegate: MessageReceiverDelegate,
signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore, signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore,
identityKeyStore: IdentityKeyStore, identityKeyStore: IdentityKeyStore,
sessionRestorationImplementation: SessionRestorationProtocol, sessionRestorationImplementation: SessionRestorationProtocol,
certificateValidator: SMKCertificateValidator, certificateValidator: SMKCertificateValidator
openGroupAPIDelegate: OpenGroupAPIDelegate,
pnServerURL: String,
pnServerPublicKey: String
) { ) {
Configuration.shared = Configuration( Configuration.shared = Configuration(
storage: storage, storage: storage,
messageSenderDelegate: messageSenderDelegate,
messageReceiverDelegate: messageReceiverDelegate,
signalStorage: signalStorage, signalStorage: signalStorage,
identityKeyStore: identityKeyStore, identityKeyStore: identityKeyStore,
sessionRestorationImplementation: sessionRestorationImplementation, sessionRestorationImplementation: sessionRestorationImplementation,
certificateValidator: certificateValidator, certificateValidator: certificateValidator
openGroupAPIDelegate: openGroupAPIDelegate,
pnServerURL: pnServerURL,
pnServerPublicKey: pnServerPublicKey
) )
} }
} }

View File

@ -2,7 +2,7 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/OWSStorage.h> #import <SessionMessagingKit/OWSStorage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -5,8 +5,6 @@
#import "OWSPrimaryStorage.h" #import "OWSPrimaryStorage.h"
#import "AppContext.h" #import "AppContext.h"
#import "OWSDisappearingMessagesFinder.h" #import "OWSDisappearingMessagesFinder.h"
#import "OWSFailedAttachmentDownloadsJob.h"
#import "OWSFailedMessagesJob.h"
#import "OWSFileSystem.h" #import "OWSFileSystem.h"
#import "OWSIncomingMessageFinder.h" #import "OWSIncomingMessageFinder.h"
#import "OWSMediaGalleryFinder.h" #import "OWSMediaGalleryFinder.h"
@ -14,7 +12,8 @@
#import "SSKEnvironment.h" #import "SSKEnvironment.h"
#import "TSDatabaseSecondaryIndexes.h" #import "TSDatabaseSecondaryIndexes.h"
#import "TSDatabaseView.h" #import "TSDatabaseView.h"
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SessionMessagingKit/SessionMessagingKit-Swift.h>
#import <YapDatabase/YapDatabaseConnectionPool.h>
#import "SSKAsserts.h" #import "SSKAsserts.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -201,8 +200,6 @@ void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage)
[FullTextSearchFinder asyncRegisterDatabaseExtensionWithStorage:self]; [FullTextSearchFinder asyncRegisterDatabaseExtensionWithStorage:self];
[OWSIncomingMessageFinder asyncRegisterExtensionWithPrimaryStorage:self]; [OWSIncomingMessageFinder asyncRegisterExtensionWithPrimaryStorage:self];
[OWSDisappearingMessagesFinder asyncRegisterDatabaseExtensions:self]; [OWSDisappearingMessagesFinder asyncRegisterDatabaseExtensions:self];
[OWSFailedMessagesJob asyncRegisterDatabaseExtensionsWithPrimaryStorage:self];
[OWSFailedAttachmentDownloadsJob asyncRegisterDatabaseExtensionsWithPrimaryStorage:self];
[OWSMediaGalleryFinder asyncRegisterDatabaseExtensionsWithPrimaryStorage:self]; [OWSMediaGalleryFinder asyncRegisterDatabaseExtensionsWithPrimaryStorage:self];
[TSDatabaseView asyncRegisterLazyRestoreAttachmentsDatabaseView:self]; [TSDatabaseView asyncRegisterLazyRestoreAttachmentsDatabaseView:self];
[SSKJobRecordFinder asyncRegisterDatabaseExtensionObjCWithStorage:self]; [SSKJobRecordFinder asyncRegisterDatabaseExtensionObjCWithStorage:self];

View File

@ -4,24 +4,24 @@
#import "OWSStorage.h" #import "OWSStorage.h"
#import "AppContext.h" #import "AppContext.h"
#import "NSNotificationCenter+OWS.h"
#import "NSUserDefaults+OWS.h"
#import "OWSBackgroundTask.h" #import "OWSBackgroundTask.h"
#import "OWSFileSystem.h" #import "OWSFileSystem.h"
#import "OWSPrimaryStorage.h" #import "OWSPrimaryStorage.h"
#import "OWSStorage+Subclass.h" #import "TSYapDatabaseObject.h"
#import "TSAttachmentStream.h" #import "TSAttachmentStream.h"
#import <SignalCoreKit/NSData+OWS.h> #import <SignalCoreKit/SignalCoreKit.h>
#import <SignalCoreKit/Randomness.h> #import <SignalCoreKit/Randomness.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseAutoView.h> #import <YapDatabase/YapDatabaseAutoView.h>
#import <YapDatabase/YapDatabaseCrossProcessNotification.h>
#import <YapDatabase/YapDatabaseCryptoUtils.h> #import <YapDatabase/YapDatabaseCryptoUtils.h>
#import <YapDatabase/YapDatabaseCrossProcessNotification.h>
#import <YapDatabase/YapDatabaseFullTextSearch.h> #import <YapDatabase/YapDatabaseFullTextSearch.h>
#import <YapDatabase/YapDatabaseFullTextSearchPrivate.h> #import <YapDatabase/YapDatabaseFullTextSearchPrivate.h>
#import <YapDatabase/YapDatabaseSecondaryIndex.h> #import <YapDatabase/YapDatabaseSecondaryIndex.h>
#import <YapDatabase/YapDatabaseSecondaryIndexPrivate.h> #import <YapDatabase/YapDatabaseSecondaryIndexPrivate.h>
#import <YapDatabase/YapDatabaseSecondaryIndexSetup.h>
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
#import <SessionUtilitiesKit/AppContext.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -59,8 +59,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
return self; return self;
} }
OWSAssertDebug(delegate);
self.delegate = delegate; self.delegate = delegate;
return self; return self;
@ -76,8 +74,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (void)readWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block - (void)readWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block
{ {
id<OWSDatabaseConnectionDelegate> delegate = self.delegate; id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
OWSAssertDebug(delegate);
OWSAssertDebug(delegate.areAllRegistrationsComplete);
OWSBackgroundTask *_Nullable backgroundTask = nil; OWSBackgroundTask *_Nullable backgroundTask = nil;
if (CurrentAppContext().isMainApp && !CurrentAppContext().isRunningTests) { if (CurrentAppContext().isMainApp && !CurrentAppContext().isRunningTests) {
@ -103,8 +99,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
completionBlock:(nullable dispatch_block_t)completionBlock completionBlock:(nullable dispatch_block_t)completionBlock
{ {
id<OWSDatabaseConnectionDelegate> delegate = self.delegate; id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
OWSAssertDebug(delegate);
OWSAssertDebug(delegate.areAllRegistrationsComplete);
__block OWSBackgroundTask *_Nullable backgroundTask = nil; __block OWSBackgroundTask *_Nullable backgroundTask = nil;
if (CurrentAppContext().isMainApp) { if (CurrentAppContext().isMainApp) {
@ -155,8 +149,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
return self; return self;
} }
OWSAssertDebug(delegate);
self.delegate = delegate; self.delegate = delegate;
return self; return self;
@ -169,7 +161,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (YapDatabaseConnection *)newConnection - (YapDatabaseConnection *)newConnection
{ {
id<OWSDatabaseConnectionDelegate> delegate = self.delegate; id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
OWSAssertDebug(delegate);
OWSDatabaseConnection *connection = [[OWSDatabaseConnection alloc] initWithDatabase:self delegate:delegate]; OWSDatabaseConnection *connection = [[OWSDatabaseConnection alloc] initWithDatabase:self delegate:delegate];
[self addConnection:connection]; [self addConnection:connection];
@ -201,8 +192,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (void)encodeWithCoder:(NSCoder *)aCoder - (void)encodeWithCoder:(NSCoder *)aCoder
{ {
OWSFailDebug(@"Tried to save object from unknown collection");
return [super encodeWithCoder:aCoder]; return [super encodeWithCoder:aCoder];
} }
@ -218,22 +207,16 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSFailDebug(@"Tried to save unknown object");
// No-op. // No-op.
} }
- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSFailDebug(@"Tried to touch unknown object");
// No-op. // No-op.
} }
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSFailDebug(@"Tried to remove unknown object");
// No-op. // No-op.
} }
@ -253,11 +236,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
cannotDecodeObjectOfClassName:(NSString *)name cannotDecodeObjectOfClassName:(NSString *)name
originalClasses:(NSArray<NSString *> *)classNames originalClasses:(NSArray<NSString *> *)classNames
{ {
if ([name isEqualToString:@"TSRecipient"]) {
OWSLogError(@"Could not decode object: %@", name);
} else {
NSLog(@"Could not decode object: %@", name);
}
return [OWSUnknownDBObject class]; return [OWSUnknownDBObject class];
} }
@ -295,9 +273,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (void)dealloc - (void)dealloc
{ {
// Surface memory leaks by logging the deallocation of this class.
OWSLogVerbose(@"Dealloc: %@", self.class);
[[NSNotificationCenter defaultCenter] removeObserver:self]; [[NSNotificationCenter defaultCenter] removeObserver:self];
} }
@ -308,7 +283,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// //
// The best we can try to do is to discard the current database // The best we can try to do is to discard the current database
// and behave like a clean install. // and behave like a clean install.
OWSFailDebug(@"Could not load database");
// Try to reset app by deleting all databases. // Try to reset app by deleting all databases.
// //
@ -316,34 +290,27 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// [OWSStorage deleteDatabaseFiles]; // [OWSStorage deleteDatabaseFiles];
if (![self tryToLoadDatabase]) { if (![self tryToLoadDatabase]) {
OWSFailDebug(@"Could not load database (second try)");
// Sleep to give analytics events time to be delivered. // Sleep to give analytics events time to be delivered.
[NSThread sleepForTimeInterval:15.0f]; [NSThread sleepForTimeInterval:15.0f];
OWSFail(@"Failed to initialize database."); NSAssert(NO, @"Couldn't load database");
} }
} }
} }
- (nullable id)dbNotificationObject - (nullable id)dbNotificationObject
{ {
OWSAssertDebug(self.database);
return self.database; return self.database;
} }
- (BOOL)areAsyncRegistrationsComplete - (BOOL)areAsyncRegistrationsComplete
{ {
OWSAbstractMethod();
return NO; return NO;
} }
- (BOOL)areSyncRegistrationsComplete - (BOOL)areSyncRegistrationsComplete
{ {
OWSAbstractMethod();
return NO; return NO;
} }
@ -354,26 +321,22 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (void)runSyncRegistrations - (void)runSyncRegistrations
{ {
OWSAbstractMethod();
} }
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion - (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion
{ {
OWSAbstractMethod();
} }
+ (void)registerExtensionsWithMigrationBlock:(OWSStorageMigrationBlock)migrationBlock + (void)registerExtensionsWithMigrationBlock:(OWSStorageMigrationBlock)migrationBlock
{ {
OWSAssertDebug(migrationBlock);
__block OWSBackgroundTask *_Nullable backgroundTask = __block OWSBackgroundTask *_Nullable backgroundTask =
[OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__]; [OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
[OWSPrimaryStorage.sharedManager runSyncRegistrations]; [OWSPrimaryStorage.sharedManager runSyncRegistrations];
[OWSPrimaryStorage.sharedManager runAsyncRegistrationsWithCompletion:^{ [OWSPrimaryStorage.sharedManager runAsyncRegistrationsWithCompletion:^{
OWSAssertDebug(self.isStorageReady);
[self postRegistrationCompleteNotification]; [self postRegistrationCompleteNotification];
migrationBlock(); migrationBlock();
@ -390,10 +353,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// Returns YES IFF all registrations are complete. // Returns YES IFF all registrations are complete.
+ (void)postRegistrationCompleteNotification + (void)postRegistrationCompleteNotification
{ {
OWSAssertDebug(self.isStorageReady);
OWSLogInfo(@"");
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
[[NSNotificationCenter defaultCenter] postNotificationNameAsync:StorageIsReadyNotification [[NSNotificationCenter defaultCenter] postNotificationNameAsync:StorageIsReadyNotification
@ -424,15 +383,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_migrate // https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_migrate
options.legacyCipherCompatibilityVersion = 3; options.legacyCipherCompatibilityVersion = 3;
// If any of these asserts fails, we need to verify and update
// OWSDatabaseConverter which assumes the values of these options.
OWSAssertDebug(options.cipherDefaultkdfIterNumber == 0);
OWSAssertDebug(options.kdfIterNumber == 0);
OWSAssertDebug(options.cipherPageSize == 0);
OWSAssertDebug(options.pragmaPageSize == 0);
OWSAssertDebug(options.pragmaJournalSizeLimit == 0);
OWSAssertDebug(options.pragmaMMapSize == 0);
return options; return options;
} }
@ -445,13 +395,11 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// (e.g. by using OWSAssertDebug()) or this database will contain a // (e.g. by using OWSAssertDebug()) or this database will contain a
// circular reference and will leak. // circular reference and will leak.
OWSStorage *strongSelf = weakSelf; OWSStorage *strongSelf = weakSelf;
OWSCAssertDebug(strongSelf);
// Rather than compute this once and capture the value of the key // Rather than compute this once and capture the value of the key
// in the closure, we prefer to fetch the key from the keychain multiple times // in the closure, we prefer to fetch the key from the keychain multiple times
// in order to keep the key out of application memory. // in order to keep the key out of application memory.
NSData *databaseKeySpec = [strongSelf databaseKeySpec]; NSData *databaseKeySpec = [strongSelf databaseKeySpec];
OWSCAssertDebug(databaseKeySpec.length == kSQLCipherKeySpecLength);
return databaseKeySpec; return databaseKeySpec;
}; };
@ -484,7 +432,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
return ^id(NSString __unused *collection, NSString __unused *key, NSData *data) { return ^id(NSString __unused *collection, NSString __unused *key, NSData *data) {
if (!data || data.length <= 0) { if (!data || data.length <= 0) {
OWSFailDebug(@"can't deserialize null object: %@", collection);
return [OWSUnknownDBObject new]; return [OWSUnknownDBObject new];
} }
@ -502,9 +449,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (YapDatabaseConnection *)newDatabaseConnection - (YapDatabaseConnection *)newDatabaseConnection
{ {
YapDatabaseConnection *dbConnection = self.database.newConnection; YapDatabaseConnection *dbConnection = self.database.newConnection;
if (!dbConnection) {
OWSFail(@"Storage could not open new database connection.");
}
return dbConnection; return dbConnection;
} }
@ -512,8 +456,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
+ (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName + (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName
{ {
OWSLogError(@"%@", extensionName);
// Don't increment version of a given extension more than once // Don't increment version of a given extension more than once
// per launch. // per launch.
static NSMutableSet<NSString *> *incrementedViewSet = nil; static NSMutableSet<NSString *> *incrementedViewSet = nil;
@ -523,14 +465,12 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
}); });
@synchronized(incrementedViewSet) { @synchronized(incrementedViewSet) {
if ([incrementedViewSet containsObject:extensionName]) { if ([incrementedViewSet containsObject:extensionName]) {
OWSLogInfo(@"Ignoring redundant increment: %@", extensionName);
return; return;
} }
[incrementedViewSet addObject:extensionName]; [incrementedViewSet addObject:extensionName];
} }
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults]; NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
OWSAssertDebug(appUserDefaults);
NSMutableDictionary<NSString *, NSNumber *> *_Nullable versionMap = NSMutableDictionary<NSString *, NSNumber *> *_Nullable versionMap =
[[appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap] mutableCopy]; [[appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap] mutableCopy];
if (!versionMap) { if (!versionMap) {
@ -545,10 +485,7 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (nullable NSString *)appendSuffixToDatabaseExtensionVersionIfNecessary:(nullable NSString *)versionTag - (nullable NSString *)appendSuffixToDatabaseExtensionVersionIfNecessary:(nullable NSString *)versionTag
extensionName:(NSString *)extensionName extensionName:(NSString *)extensionName
{ {
OWSAssertIsOnMainThread();
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults]; NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
OWSAssertDebug(appUserDefaults);
NSDictionary<NSString *, NSNumber *> *_Nullable versionMap = NSDictionary<NSString *, NSNumber *> *_Nullable versionMap =
[appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap]; [appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap];
NSNumber *_Nullable versionSuffix = versionMap[extensionName]; NSNumber *_Nullable versionSuffix = versionMap[extensionName];
@ -556,7 +493,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
if (versionSuffix) { if (versionSuffix) {
NSString *result = NSString *result =
[NSString stringWithFormat:@"%@.%@", (versionTag.length < 1 ? @"0" : versionTag), versionSuffix]; [NSString stringWithFormat:@"%@.%@", (versionTag.length < 1 ? @"0" : versionTag), versionSuffix];
OWSLogWarn(@"database extension version: %@ + %@ -> %@", versionTag, versionSuffix, result);
return result; return result;
} }
return versionTag; return versionTag;
@ -564,9 +500,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (YapDatabaseExtension *)updateExtensionVersion:(YapDatabaseExtension *)extension withName:(NSString *)extensionName - (YapDatabaseExtension *)updateExtensionVersion:(YapDatabaseExtension *)extension withName:(NSString *)extensionName
{ {
OWSAssertDebug(extension);
OWSAssertDebug(extensionName.length > 0);
if ([extension isKindOfClass:[YapDatabaseAutoView class]]) { if ([extension isKindOfClass:[YapDatabaseAutoView class]]) {
YapDatabaseAutoView *databaseView = (YapDatabaseAutoView *)extension; YapDatabaseAutoView *databaseView = (YapDatabaseAutoView *)extension;
YapDatabaseAutoView *databaseViewCopy = [[YapDatabaseAutoView alloc] YapDatabaseAutoView *databaseViewCopy = [[YapDatabaseAutoView alloc]
@ -578,8 +511,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
return databaseViewCopy; return databaseViewCopy;
} else if ([extension isKindOfClass:[YapDatabaseSecondaryIndex class]]) { } else if ([extension isKindOfClass:[YapDatabaseSecondaryIndex class]]) {
YapDatabaseSecondaryIndex *secondaryIndex = (YapDatabaseSecondaryIndex *)extension; YapDatabaseSecondaryIndex *secondaryIndex = (YapDatabaseSecondaryIndex *)extension;
OWSAssertDebug(secondaryIndex->setup);
OWSAssertDebug(secondaryIndex->handler);
YapDatabaseSecondaryIndex *secondaryIndexCopy = [[YapDatabaseSecondaryIndex alloc] YapDatabaseSecondaryIndex *secondaryIndexCopy = [[YapDatabaseSecondaryIndex alloc]
initWithSetup:secondaryIndex->setup initWithSetup:secondaryIndex->setup
handler:secondaryIndex->handler handler:secondaryIndex->handler
@ -606,7 +537,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// This method needs to be able to update the versionTag of all extensions. // This method needs to be able to update the versionTag of all extensions.
// If we start using other extension types, we need to modify this method to // If we start using other extension types, we need to modify this method to
// handle them as well. // handle them as well.
OWSFailDebug(@"Unknown extension type: %@", [extension class]);
return extension; return extension;
} }
@ -616,7 +546,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
{ {
extension = [self updateExtensionVersion:extension withName:extensionName]; extension = [self updateExtensionVersion:extension withName:extensionName];
OWSAssertDebug(![self.extensionNames containsObject:extensionName]);
[self.extensionNames addObject:extensionName]; [self.extensionNames addObject:extensionName];
return [self.database registerExtension:extension withName:extensionName]; return [self.database registerExtension:extension withName:extensionName];
@ -634,18 +563,11 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
{ {
extension = [self updateExtensionVersion:extension withName:extensionName]; extension = [self updateExtensionVersion:extension withName:extensionName];
OWSAssertDebug(![self.extensionNames containsObject:extensionName]);
[self.extensionNames addObject:extensionName]; [self.extensionNames addObject:extensionName];
[self.database asyncRegisterExtension:extension [self.database asyncRegisterExtension:extension
withName:extensionName withName:extensionName
completionBlock:^(BOOL ready) { completionBlock:^(BOOL ready) {
if (!ready) {
OWSFailDebug(@"asyncRegisterExtension failed: %@", extensionName);
} else {
OWSLogVerbose(@"asyncRegisterExtension succeeded: %@", extensionName);
}
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if (completion) { if (completion) {
completion(); completion();
@ -710,22 +632,16 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (NSString *)databaseFilePath - (NSString *)databaseFilePath
{ {
OWSAbstractMethod();
return @""; return @"";
} }
- (NSString *)databaseFilePath_SHM - (NSString *)databaseFilePath_SHM
{ {
OWSAbstractMethod();
return @""; return @"";
} }
- (NSString *)databaseFilePath_WAL - (NSString *)databaseFilePath_WAL
{ {
OWSAbstractMethod();
return @""; return @"";
} }
@ -740,10 +656,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
return YES; return YES;
} }
if (error) {
OWSLogWarn(@"Database key couldn't be accessed: %@", error.localizedDescription);
}
return NO; return NO;
} }
@ -755,29 +667,21 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
+ (nullable NSData *)tryToLoadDatabaseCipherKeySpec:(NSError **)errorHandle + (nullable NSData *)tryToLoadDatabaseCipherKeySpec:(NSError **)errorHandle
{ {
NSData *_Nullable data = [self tryToLoadKeyChainValue:keychainDBCipherKeySpec errorHandle:errorHandle]; NSData *_Nullable data = [self tryToLoadKeyChainValue:keychainDBCipherKeySpec errorHandle:errorHandle];
OWSAssertDebug(!data || data.length == kSQLCipherKeySpecLength);
return data; return data;
} }
+ (void)storeDatabaseCipherKeySpec:(NSData *)cipherKeySpecData + (void)storeDatabaseCipherKeySpec:(NSData *)cipherKeySpecData
{ {
OWSAssertDebug(cipherKeySpecData.length == kSQLCipherKeySpecLength);
[self storeKeyChainValue:cipherKeySpecData keychainKey:keychainDBCipherKeySpec]; [self storeKeyChainValue:cipherKeySpecData keychainKey:keychainDBCipherKeySpec];
} }
+ (void)removeLegacyPassphrase + (void)removeLegacyPassphrase
{ {
OWSLogInfo(@"removing legacy passphrase");
NSError *_Nullable error; NSError *_Nullable error;
BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService
key:keychainDBLegacyPassphrase key:keychainDBLegacyPassphrase
error:&error]; error:&error];
if (error || !result) {
OWSFailDebug(@"could not remove legacy passphrase.");
}
} }
- (void)ensureDatabaseKeySpecExists - (void)ensureDatabaseKeySpecExists
@ -800,8 +704,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
errorDescription = [errorDescription errorDescription = [errorDescription
stringByAppendingFormat:@", ApplicationState: %@", NSStringForUIApplicationState(applicationState)]; stringByAppendingFormat:@", ApplicationState: %@", NSStringForUIApplicationState(applicationState)];
} }
OWSLogError(@"%@", errorDescription);
[DDLog flushLog];
if (CurrentAppContext().isMainApp) { if (CurrentAppContext().isMainApp) {
if (CurrentAppContext().isInBackground) { if (CurrentAppContext().isInBackground) {
@ -818,9 +720,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
// or the keychain has become corrupt. Either way, we want to get back to a // or the keychain has become corrupt. Either way, we want to get back to a
// "known good state" and behave like a new install. // "known good state" and behave like a new install.
BOOL doesDBExist = [NSFileManager.defaultManager fileExistsAtPath:[self databaseFilePath]]; BOOL doesDBExist = [NSFileManager.defaultManager fileExistsAtPath:[self databaseFilePath]];
if (doesDBExist) {
OWSFailDebug(@"Could not load database metadata");
}
if (!CurrentAppContext().isRunningTests) { if (!CurrentAppContext().isRunningTests) {
// Try to reset app by deleting database. // Try to reset app by deleting database.
@ -838,12 +737,10 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
NSData *_Nullable keySpec = [[self class] tryToLoadDatabaseCipherKeySpec:&error]; NSData *_Nullable keySpec = [[self class] tryToLoadDatabaseCipherKeySpec:&error];
if (error) { if (error) {
OWSLogError(@"failed to fetch databaseKeySpec with error: %@", error);
[self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec inaccessible"]; [self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec inaccessible"];
} }
if (keySpec.length != kSQLCipherKeySpecLength) { if (keySpec.length != kSQLCipherKeySpecLength) {
OWSLogError(@"keyspec had length: %lu", (unsigned long)keySpec.length);
[self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec invalid"]; [self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec invalid"];
} }
@ -852,15 +749,12 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
- (void)raiseKeySpecInaccessibleExceptionWithErrorDescription:(NSString *)errorDescription - (void)raiseKeySpecInaccessibleExceptionWithErrorDescription:(NSString *)errorDescription
{ {
OWSAssertDebug(CurrentAppContext().isMainApp && CurrentAppContext().isInBackground);
// Sleep to give analytics events time to be delivered. // Sleep to give analytics events time to be delivered.
[NSThread sleepForTimeInterval:5.0f]; [NSThread sleepForTimeInterval:5.0f];
// Presumably this happened in response to a push notification. It's possible that the keychain is corrupted // Presumably this happened in response to a push notification. It's possible that the keychain is corrupted
// but it could also just be that the user hasn't yet unlocked their device since our password is // but it could also just be that the user hasn't yet unlocked their device since our password is
// kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly // kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
OWSFail(@"%@", errorDescription);
} }
+ (void)deleteDBKeys + (void)deleteDBKeys
@ -869,15 +763,9 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService
key:keychainDBLegacyPassphrase key:keychainDBLegacyPassphrase
error:&error]; error:&error];
if (error || !result) {
OWSFailDebug(@"could not remove legacy passphrase.");
}
result = [CurrentAppContext().keychainStorage removeWithService:keychainService result = [CurrentAppContext().keychainStorage removeWithService:keychainService
key:keychainDBCipherKeySpec key:keychainDBCipherKeySpec
error:&error]; error:&error];
if (error || !result) {
OWSFailDebug(@"could not remove cipher key spec.");
}
} }
- (unsigned long long)databaseFileSize - (unsigned long long)databaseFileSize
@ -897,42 +785,27 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
+ (nullable NSData *)tryToLoadKeyChainValue:(NSString *)keychainKey errorHandle:(NSError **)errorHandle + (nullable NSData *)tryToLoadKeyChainValue:(NSString *)keychainKey errorHandle:(NSError **)errorHandle
{ {
OWSAssertDebug(keychainKey.length > 0);
OWSAssertDebug(errorHandle);
NSData *_Nullable data = NSData *_Nullable data =
[CurrentAppContext().keychainStorage dataForService:keychainService key:keychainKey error:errorHandle]; [CurrentAppContext().keychainStorage dataForService:keychainService key:keychainKey error:errorHandle];
if (*errorHandle || !data) {
OWSLogWarn(@"could not load keychain value.");
}
return data; return data;
} }
+ (void)storeKeyChainValue:(NSData *)data keychainKey:(NSString *)keychainKey + (void)storeKeyChainValue:(NSData *)data keychainKey:(NSString *)keychainKey
{ {
OWSAssertDebug(keychainKey.length > 0);
OWSAssertDebug(data.length > 0);
NSError *error; NSError *error;
BOOL success = BOOL success =
[CurrentAppContext().keychainStorage setWithData:data service:keychainService key:keychainKey error:&error]; [CurrentAppContext().keychainStorage setWithData:data service:keychainService key:keychainKey error:&error];
if (!success || error) { if (!success || error) {
OWSFailDebug(@"Could not store database metadata");
// Sleep to give analytics events time to be delivered. // Sleep to give analytics events time to be delivered.
[NSThread sleepForTimeInterval:15.0f]; [NSThread sleepForTimeInterval:15.0f];
OWSFail(@"Setting keychain value failed with error: %@", error);
} else {
OWSLogWarn(@"Successfully set new keychain value.");
} }
} }
- (void)logFileSizes - (void)logFileSizes
{ {
OWSLogInfo(@"Database file size: %@", [OWSFileSystem fileSizeOfPath:self.databaseFilePath]);
OWSLogInfo(@"\t SHM file size: %@", [OWSFileSystem fileSizeOfPath:self.databaseFilePath_SHM]);
OWSLogInfo(@"\t WAL file size: %@", [OWSFileSystem fileSizeOfPath:self.databaseFilePath_WAL]);
} }
@end @end

View File

@ -1,3 +1,4 @@
import SessionProtocolKit
extension Storage { extension Storage {

View File

@ -2,7 +2,7 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/OWSStorage.h> #import <SessionMessagingKit/OWSStorage.h>
#import <YapDatabase/YapDatabaseViewTransaction.h> #import <YapDatabase/YapDatabaseViewTransaction.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -60,8 +60,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
+ (void)registerCrossProcessNotifier:(OWSStorage *)storage + (void)registerCrossProcessNotifier:(OWSStorage *)storage
{ {
OWSAssertDebug(storage);
// I don't think the identifier and name of this extension matter for our purposes, // I don't think the identifier and name of this extension matter for our purposes,
// so long as they don't conflict with any other extension names. // so long as they don't conflict with any other extension names.
YapDatabaseExtension *extension = YapDatabaseExtension *extension =
@ -74,14 +72,8 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
version:(NSString *)version version:(NSString *)version
storage:(OWSStorage *)storage storage:(OWSStorage *)storage
{ {
OWSAssertIsOnMainThread();
OWSAssertDebug(viewName.length > 0);
OWSAssertDebug((viewGrouping));
OWSAssertDebug(storage);
YapDatabaseView *existingView = [storage registeredExtension:viewName]; YapDatabaseView *existingView = [storage registeredExtension:viewName];
if (existingView) { if (existingView) {
OWSFailDebug(@"Registered database view twice: %@", viewName);
return; return;
} }
@ -142,7 +134,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
if (![object isKindOfClass:[TSInteraction class]]) { if (![object isKindOfClass:[TSInteraction class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object class], collection);
return nil; return nil;
} }
TSInteraction *interaction = (TSInteraction *)object; TSInteraction *interaction = (TSInteraction *)object;
@ -167,19 +158,14 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
+ (void)asyncRegisterLegacyThreadInteractionsDatabaseView:(OWSStorage *)storage + (void)asyncRegisterLegacyThreadInteractionsDatabaseView:(OWSStorage *)storage
{ {
OWSAssertIsOnMainThread();
OWSAssert(storage);
YapDatabaseView *existingView = [storage registeredExtension:TSMessageDatabaseViewExtensionName_Legacy]; YapDatabaseView *existingView = [storage registeredExtension:TSMessageDatabaseViewExtensionName_Legacy];
if (existingView) { if (existingView) {
OWSFailDebug(@"Registered database view twice: %@", TSMessageDatabaseViewExtensionName_Legacy);
return; return;
} }
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
if (![object isKindOfClass:[TSInteraction class]]) { if (![object isKindOfClass:[TSInteraction class]]) {
OWSFailDebug(@"%@ Unexpected entity %@ in collection: %@", self.logTag, [object class], collection);
return nil; return nil;
} }
TSInteraction *interaction = (TSInteraction *)object; TSInteraction *interaction = (TSInteraction *)object;
@ -197,11 +183,9 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
NSString *key2, NSString *key2,
id object2) { id object2) {
if (![object1 isKindOfClass:[TSInteraction class]]) { if (![object1 isKindOfClass:[TSInteraction class]]) {
OWSFailDebug(@"%@ Unexpected entity %@ in collection: %@", self.logTag, [object1 class], collection1);
return NSOrderedSame; return NSOrderedSame;
} }
if (![object2 isKindOfClass:[TSInteraction class]]) { if (![object2 isKindOfClass:[TSInteraction class]]) {
OWSFailDebug(@"%@ Unexpected entity %@ in collection: %@", self.logTag, [object2 class], collection2);
return NSOrderedSame; return NSOrderedSame;
} }
TSInteraction *interaction1 = (TSInteraction *)object1; TSInteraction *interaction1 = (TSInteraction *)object1;
@ -237,7 +221,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
if (![object isKindOfClass:[TSInteraction class]]) { if (![object isKindOfClass:[TSInteraction class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object class], collection);
return nil; return nil;
} }
TSInteraction *interaction = (TSInteraction *)object; TSInteraction *interaction = (TSInteraction *)object;
@ -271,14 +254,12 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
{ {
YapDatabaseView *threadView = [storage registeredExtension:TSThreadDatabaseViewExtensionName]; YapDatabaseView *threadView = [storage registeredExtension:TSThreadDatabaseViewExtensionName];
if (threadView) { if (threadView) {
OWSFailDebug(@"Registered database view twice: %@", TSThreadDatabaseViewExtensionName);
return; return;
} }
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
if (![object isKindOfClass:[TSThread class]]) { if (![object isKindOfClass:[TSThread class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object class], collection);
return nil; return nil;
} }
TSThread *thread = (TSThread *)object; TSThread *thread = (TSThread *)object;
@ -287,7 +268,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
// Do nothing; we never hide threads that have ever had a message. // Do nothing; we never hide threads that have ever had a message.
} else { } else {
YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName]; YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName];
OWSAssertDebug(viewTransaction);
NSUInteger threadMessageCount = [viewTransaction numberOfItemsInGroup:thread.uniqueId]; NSUInteger threadMessageCount = [viewTransaction numberOfItemsInGroup:thread.uniqueId];
if (threadMessageCount < 1) { if (threadMessageCount < 1) {
return nil; return nil;
@ -320,11 +300,9 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
NSString *key2, NSString *key2,
id object2) { id object2) {
if (![object1 isKindOfClass:[TSThread class]]) { if (![object1 isKindOfClass:[TSThread class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object1 class], collection1);
return NSOrderedSame; return NSOrderedSame;
} }
if (![object2 isKindOfClass:[TSThread class]]) { if (![object2 isKindOfClass:[TSThread class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object2 class], collection2);
return NSOrderedSame; return NSOrderedSame;
} }
TSThread *thread1 = (TSThread *)object1; TSThread *thread1 = (TSThread *)object1;
@ -356,11 +334,9 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
NSString *key2, NSString *key2,
id object2) { id object2) {
if (![object1 isKindOfClass:[TSInteraction class]]) { if (![object1 isKindOfClass:[TSInteraction class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object1 class], collection1);
return NSOrderedSame; return NSOrderedSame;
} }
if (![object2 isKindOfClass:[TSInteraction class]]) { if (![object2 isKindOfClass:[TSInteraction class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object2 class], collection2);
return NSOrderedSame; return NSOrderedSame;
} }
TSInteraction *message1 = (TSInteraction *)object1; TSInteraction *message1 = (TSInteraction *)object1;
@ -375,7 +351,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable( YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) { YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
if (![object isKindOfClass:[TSAttachment class]]) { if (![object isKindOfClass:[TSAttachment class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object class], collection);
return nil; return nil;
} }
if (![object isKindOfClass:[TSAttachmentPointer class]]) { if (![object isKindOfClass:[TSAttachmentPointer class]]) {
@ -399,11 +374,9 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
NSString *key2, NSString *key2,
id object2) { id object2) {
if (![object1 isKindOfClass:[TSAttachmentPointer class]]) { if (![object1 isKindOfClass:[TSAttachmentPointer class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object1 class], collection1);
return NSOrderedSame; return NSOrderedSame;
} }
if (![object2 isKindOfClass:[TSAttachmentPointer class]]) { if (![object2 isKindOfClass:[TSAttachmentPointer class]]) {
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object2 class], collection2);
return NSOrderedSame; return NSOrderedSame;
} }
@ -424,15 +397,11 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
+ (id)unseenDatabaseViewExtension:(YapDatabaseReadTransaction *)transaction + (id)unseenDatabaseViewExtension:(YapDatabaseReadTransaction *)transaction
{ {
OWSAssertDebug(transaction);
id _Nullable result = [transaction ext:TSUnseenDatabaseViewExtensionName]; id _Nullable result = [transaction ext:TSUnseenDatabaseViewExtensionName];
OWSAssertDebug(result);
// TODO: I believe we can now safely remove this? // TODO: I believe we can now safely remove this?
if (!result) { if (!result) {
result = [transaction ext:TSUnreadDatabaseViewExtensionName]; result = [transaction ext:TSUnreadDatabaseViewExtensionName];
OWSAssertDebug(result);
} }
return result; return result;
@ -441,20 +410,14 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
// MJK TODO - dynamic interactions // MJK TODO - dynamic interactions
+ (id)threadOutgoingMessageDatabaseView:(YapDatabaseReadTransaction *)transaction + (id)threadOutgoingMessageDatabaseView:(YapDatabaseReadTransaction *)transaction
{ {
OWSAssertDebug(transaction);
id result = [transaction ext:TSThreadOutgoingMessageDatabaseViewExtensionName]; id result = [transaction ext:TSThreadOutgoingMessageDatabaseViewExtensionName];
OWSAssertDebug(result);
return result; return result;
} }
+ (id)threadSpecialMessagesDatabaseView:(YapDatabaseReadTransaction *)transaction + (id)threadSpecialMessagesDatabaseView:(YapDatabaseReadTransaction *)transaction
{ {
OWSAssertDebug(transaction);
id result = [transaction ext:TSThreadSpecialMessagesDatabaseViewExtensionName]; id result = [transaction ext:TSThreadSpecialMessagesDatabaseViewExtensionName];
OWSAssertDebug(result);
return result; return result;
} }

View File

@ -34,13 +34,13 @@ public final class NotifyPNServerJob : NSObject, Job, NSCoding { // NSObject/NSC
// MARK: Running // MARK: Running
public func execute() { public func execute() {
let server = Configuration.shared.pnServerURL let server = PushNotificationAPI.server
let parameters = [ "data" : message.data.description, "send_to" : message.recipient ] let parameters = [ "data" : message.data.description, "send_to" : message.recipient ]
let url = URL(string: "\(server)/notify")! let url = URL(string: "\(server)/notify")!
let request = TSRequest(url: url, method: "POST", parameters: parameters) let request = TSRequest(url: url, method: "POST", parameters: parameters)
request.allHTTPHeaderFields = [ "Content-Type" : "application/json" ] request.allHTTPHeaderFields = [ "Content-Type" : "application/json" ]
attempt(maxRetryCount: 4, recoveringOn: DispatchQueue.global()) { attempt(maxRetryCount: 4, recoveringOn: DispatchQueue.global()) {
OnionRequestAPI.sendOnionRequest(request, to: server, target: "/loki/v2/lsrpc", using: Configuration.shared.pnServerPublicKey).map { _ in } OnionRequestAPI.sendOnionRequest(request, to: server, target: "/loki/v2/lsrpc", using: PushNotificationAPI.serverPublicKey).map { _ in }
}.done(on: DispatchQueue.global()) { // Intentionally capture self }.done(on: DispatchQueue.global()) { // Intentionally capture self
self.handleSuccess() self.handleSuccess()
}.catch(on: DispatchQueue.global()) { error in }.catch(on: DispatchQueue.global()) { error in

View File

@ -5,5 +5,20 @@ public extension Message {
case contact(publicKey: String) case contact(publicKey: String)
case closedGroup(groupPublicKey: String) case closedGroup(groupPublicKey: String)
case openGroup(channel: UInt64, server: String) case openGroup(channel: UInt64, server: String)
static func from(_ thread: TSThread) -> Message.Destination {
if let thread = thread as? TSContactThread {
return .contact(publicKey: thread.contactIdentifier())
} else if let thread = thread as? TSGroupThread, thread.usesSharedSenderKeys {
let groupID = thread.groupModel.groupId
let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
return .closedGroup(groupPublicKey: groupPublicKey)
} else if let thread = thread as? TSGroupThread, thread.isOpenGroup {
let openGroup = Storage.shared.getOpenGroup(for: thread.uniqueId!)!
return .openGroup(channel: openGroup.channel, server: openGroup.server)
} else {
preconditionFailure("TODO: Handle legacy closed groups.")
}
}
} }
} }

View File

@ -2,8 +2,8 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/OWSReadTracking.h> #import <SessionMessagingKit/OWSReadTracking.h>
#import <SignalUtilitiesKit/TSMessage.h> #import <SessionMessagingKit/TSMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -7,8 +7,8 @@
#import "TSContactThread.h" #import "TSContactThread.h"
#import "TSErrorMessage_privateConstructor.h" #import "TSErrorMessage_privateConstructor.h"
#import <SignalCoreKit/NSDate+OWS.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <YapDatabase/YapDatabaseConnection.h> #import <YapDatabase/YapDatabaseConnection.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -205,13 +205,10 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
sendReadReceipt:(BOOL)sendReadReceipt sendReadReceipt:(BOOL)sendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
if (_read) { if (_read) {
return; return;
} }
OWSLogDebug(@"marking as read uniqueId: %@ which has timestamp: %llu", self.uniqueId, self.timestamp);
_read = YES; _read = YES;
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];

View File

@ -2,7 +2,7 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/TSErrorMessage.h> #import <SessionMessagingKit/TSErrorMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -2,8 +2,8 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/OWSReadTracking.h> #import <SessionMessagingKit/OWSReadTracking.h>
#import <SignalUtilitiesKit/TSMessage.h> #import <SessionMessagingKit/TSMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -13,6 +13,7 @@
#import "TSGroupThread.h" #import "TSGroupThread.h"
#import <SessionProtocolKit/SessionProtocolKit.h> #import <SessionProtocolKit/SessionProtocolKit.h>
#import <YapDatabase/YapDatabaseConnection.h> #import <YapDatabase/YapDatabaseConnection.h>
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -36,7 +37,6 @@ NS_ASSUME_NONNULL_BEGIN
} }
if (_authorId == nil) { if (_authorId == nil) {
OWSAssertDebug([self.uniqueThreadId hasPrefix:TSContactThreadPrefix]);
_authorId = [TSContactThread contactIdFromThreadId:self.uniqueThreadId]; _authorId = [TSContactThread contactIdFromThreadId:self.uniqueThreadId];
} }
@ -81,8 +81,6 @@ NS_ASSUME_NONNULL_BEGIN
timestamp:(uint64_t)timestamp timestamp:(uint64_t)timestamp
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
__block TSIncomingMessage *foundMessage; __block TSIncomingMessage *foundMessage;
// In theory we could build a new secondaryIndex for (authorId,timestamp), but in practice there should // In theory we could build a new secondaryIndex for (authorId,timestamp), but in practice there should
// be *very* few (millisecond) timestamps with multiple authors. // be *very* few (millisecond) timestamps with multiple authors.
@ -93,9 +91,6 @@ NS_ASSUME_NONNULL_BEGIN
[TSInteraction fetchObjectWithUniqueID:key transaction:transaction]; [TSInteraction fetchObjectWithUniqueID:key transaction:transaction];
if ([interaction isKindOfClass:[TSIncomingMessage class]]) { if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *message = (TSIncomingMessage *)interaction; TSIncomingMessage *message = (TSIncomingMessage *)interaction;
OWSAssertDebug(message.authorId > 0);
if ([message.authorId isEqualToString:authorId]) { if ([message.authorId isEqualToString:authorId]) {
foundMessage = message; foundMessage = message;
} }
@ -133,7 +128,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)markAsReadNowWithSendReadReceipt:(BOOL)sendReadReceipt - (void)markAsReadNowWithSendReadReceipt:(BOOL)sendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
{ {
[self markAsReadAtTimestamp:[NSDate ows_millisecondTimeStamp] [self markAsReadAtTimestamp:[NSDate millisecondTimestamp]
sendReadReceipt:sendReadReceipt sendReadReceipt:sendReadReceipt
transaction:transaction]; transaction:transaction];
} }
@ -142,17 +137,11 @@ NS_ASSUME_NONNULL_BEGIN
sendReadReceipt:(BOOL)sendReadReceipt sendReadReceipt:(BOOL)sendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
{ {
OWSAssertDebug(transaction);
if (_read && readTimestamp >= self.expireStartedAt) { if (_read && readTimestamp >= self.expireStartedAt) {
return; return;
} }
NSTimeInterval secondsAgoRead = ((NSTimeInterval)[NSDate ows_millisecondTimeStamp] - (NSTimeInterval)readTimestamp) / 1000; NSTimeInterval secondsAgoRead = ((NSTimeInterval)[NSDate millisecondTimestamp] - (NSTimeInterval)readTimestamp) / 1000;
OWSLogDebug(@"marking uniqueId: %@ which has timestamp: %llu as read: %f seconds ago",
self.uniqueId,
self.timestamp,
secondsAgoRead);
_read = YES; _read = YES;
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];

View File

@ -2,8 +2,8 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/OWSReadTracking.h> #import <SessionMessagingKit/OWSReadTracking.h>
#import <SignalUtilitiesKit/TSMessage.h> #import <SessionMessagingKit/TSMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -6,6 +6,7 @@
#import "SSKEnvironment.h" #import "SSKEnvironment.h"
#import <SessionProtocolKit/SessionProtocolKit.h> #import <SessionProtocolKit/SessionProtocolKit.h>
#import <YapDatabase/YapDatabaseConnection.h> #import <YapDatabase/YapDatabaseConnection.h>
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -97,11 +98,8 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
+ (instancetype)userNotRegisteredMessageInThread:(TSThread *)thread recipientId:(NSString *)recipientId + (instancetype)userNotRegisteredMessageInThread:(TSThread *)thread recipientId:(NSString *)recipientId
{ {
OWSAssertDebug(thread);
OWSAssertDebug(recipientId);
// MJK TODO - remove senderTimestamp // MJK TODO - remove senderTimestamp
return [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] return [[self alloc] initWithTimestamp:[NSDate millisecondTimestamp]
inThread:thread inThread:thread
messageType:TSInfoMessageUserNotRegistered messageType:TSInfoMessageUserNotRegistered
unregisteredRecipientId:recipientId]; unregisteredRecipientId:recipientId];
@ -169,13 +167,10 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
sendReadReceipt:(BOOL)sendReadReceipt sendReadReceipt:(BOOL)sendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
if (_read) { if (_read) {
return; return;
} }
OWSLogDebug(@"marking as read uniqueId: %@ which has timestamp: %llu", self.uniqueId, self.timestamp);
_read = YES; _read = YES;
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];

View File

@ -7,7 +7,7 @@
#import "TSThread.h" #import "TSThread.h"
#import "TSGroupThread.h" #import "TSGroupThread.h"
#import <SignalCoreKit/NSDate+OWS.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SessionMessagingKit/SessionMessagingKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -47,8 +47,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
ofClass:(Class)clazz ofClass:(Class)clazz
withTransaction:(YapDatabaseReadTransaction *)transaction withTransaction:(YapDatabaseReadTransaction *)transaction
{ {
OWSAssertDebug(timestamp > 0);
// Accept any interaction. // Accept any interaction.
return [self interactionsWithTimestamp:timestamp return [self interactionsWithTimestamp:timestamp
filter:^(TSInteraction *interaction) { filter:^(TSInteraction *interaction) {
@ -61,8 +59,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
filter:(BOOL (^_Nonnull)(TSInteraction *))filter filter:(BOOL (^_Nonnull)(TSInteraction *))filter
withTransaction:(YapDatabaseReadTransaction *)transaction withTransaction:(YapDatabaseReadTransaction *)transaction
{ {
OWSAssertDebug(timestamp > 0);
NSMutableArray<TSInteraction *> *interactions = [NSMutableArray new]; NSMutableArray<TSInteraction *> *interactions = [NSMutableArray new];
[TSDatabaseSecondaryIndexes [TSDatabaseSecondaryIndexes
@ -88,8 +84,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
timestamp:(uint64_t)timestamp timestamp:(uint64_t)timestamp
inThread:(TSThread *)thread inThread:(TSThread *)thread
{ {
OWSAssertDebug(timestamp > 0);
self = [super initWithUniqueId:uniqueId]; self = [super initWithUniqueId:uniqueId];
if (!self) { if (!self) {
@ -104,8 +98,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread - (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread
{ {
OWSAssertDebug(timestamp > 0);
self = [super initWithUniqueId:[[NSUUID UUID] UUIDString]]; self = [super initWithUniqueId:[[NSUUID UUID] UUIDString]];
if (!self) { if (!self) {
@ -169,8 +161,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction - (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction
changeBlock:(void (^)(id))changeBlock changeBlock:(void (^)(id))changeBlock
{ {
OWSAssertDebug(transaction);
[super applyChangeToSelfAndLatestCopy:transaction changeBlock:changeBlock]; [super applyChangeToSelfAndLatestCopy:transaction changeBlock:changeBlock];
[self touchThreadWithTransaction:transaction]; [self touchThreadWithTransaction:transaction];
} }
@ -203,8 +193,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
- (NSComparisonResult)compareForSorting:(TSInteraction *)other - (NSComparisonResult)compareForSorting:(TSInteraction *)other
{ {
OWSAssertDebug(other);
uint64_t sortId1; uint64_t sortId1;
uint64_t sortId2; uint64_t sortId2;
@ -230,8 +218,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
- (OWSInteractionType)interactionType - (OWSInteractionType)interactionType
{ {
OWSFailDebug(@"unknown interaction type.");
return OWSInteractionType_Unknown; return OWSInteractionType_Unknown;
} }
@ -246,7 +232,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
if (!self.uniqueId) { if (!self.uniqueId) {
OWSFailDebug(@"Missing uniqueId.");
self.uniqueId = [NSUUID new].UUIDString; self.uniqueId = [NSUUID new].UUIDString;
} }
if (self.sortId == 0) { if (self.sortId == 0) {

View File

@ -2,12 +2,10 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/TSErrorMessage.h> #import <SessionMessagingKit/TSErrorMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class OWSFingerprint;
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage @interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
- (void)throws_acceptNewIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions"); - (void)throws_acceptNewIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");

View File

@ -11,18 +11,16 @@ NS_ASSUME_NONNULL_BEGIN
- (void)throws_acceptNewIdentityKey - (void)throws_acceptNewIdentityKey
{ {
OWSAbstractMethod();
} }
- (nullable NSData *)throws_newIdentityKey - (nullable NSData *)throws_newIdentityKey
{ {
OWSAbstractMethod();
return nil; return nil;
} }
- (NSString *)theirSignalId - (NSString *)theirSignalId
{ {
OWSAbstractMethod();
return nil; return nil;
} }

View File

@ -2,7 +2,7 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/TSInvalidIdentityKeyErrorMessage.h> #import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -12,8 +12,8 @@
#import "TSErrorMessage_privateConstructor.h" #import "TSErrorMessage_privateConstructor.h"
#import <SessionProtocolKit/NSData+keyVersionByte.h> #import <SessionProtocolKit/NSData+keyVersionByte.h>
#import <SessionProtocolKit/PreKeyWhisperMessage.h> #import <SessionProtocolKit/PreKeyWhisperMessage.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <YapDatabase/YapDatabaseTransaction.h> #import <YapDatabase/YapDatabaseTransaction.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -59,7 +59,6 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage
NSError *error; NSError *error;
_envelopeData = [envelope serializedDataAndReturnError:&error]; _envelopeData = [envelope serializedDataAndReturnError:&error];
if (!_envelopeData || error != nil) { if (!_envelopeData || error != nil) {
OWSFailDebug(@"failure: envelope data failed with error: %@", error);
return nil; return nil;
} }
@ -75,7 +74,7 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage
NSError *error; NSError *error;
SNProtoEnvelope *_Nullable envelope = [SNProtoEnvelope parseData:self.envelopeData error:&error]; SNProtoEnvelope *_Nullable envelope = [SNProtoEnvelope parseData:self.envelopeData error:&error];
if (error || envelope == nil) { if (error || envelope == nil) {
OWSFailDebug(@"Could not parse proto: %@", error);
} else { } else {
_envelope = envelope; _envelope = envelope;
} }
@ -85,16 +84,12 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage
- (void)throws_acceptNewIdentityKey - (void)throws_acceptNewIdentityKey
{ {
OWSAssertIsOnMainThread();
if (self.errorType != TSErrorMessageWrongTrustedIdentityKey) { if (self.errorType != TSErrorMessageWrongTrustedIdentityKey) {
OWSLogError(@"Refusing to accept identity key for anything but a Key error.");
return; return;
} }
NSData *_Nullable newKey = [self throws_newIdentityKey]; NSData *_Nullable newKey = [self throws_newIdentityKey];
if (!newKey) { if (!newKey) {
OWSFailDebug(@"Couldn't extract identity key to accept");
return; return;
} }
@ -116,18 +111,15 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage
- (nullable NSData *)throws_newIdentityKey - (nullable NSData *)throws_newIdentityKey
{ {
if (!self.envelope) { if (!self.envelope) {
OWSLogError(@"Error message had no envelope data to extract key from");
return nil; return nil;
} }
if (self.envelope.type != SNProtoEnvelopeTypePrekeyBundle) { if (self.envelope.type != SNProtoEnvelopeTypePrekeyBundle) {
OWSLogError(@"Refusing to attempt key extraction from an envelope which isn't a prekey bundle");
return nil; return nil;
} }
NSData *pkwmData = self.envelope.content; NSData *pkwmData = self.envelope.content;
if (!pkwmData) { if (!pkwmData) {
OWSLogError(@"Ignoring acceptNewIdentityKey for empty message");
return nil; return nil;
} }

View File

@ -2,7 +2,7 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/TSInteraction.h> #import <SessionMessagingKit/TSInteraction.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -17,6 +17,8 @@ NS_ASSUME_NONNULL_BEGIN
@class TSQuotedMessage; @class TSQuotedMessage;
@class YapDatabaseReadWriteTransaction; @class YapDatabaseReadWriteTransaction;
extern const NSUInteger kOversizeTextMessageSizeThreshold;
@interface TSMessage : TSInteraction <OWSPreviewText> @interface TSMessage : TSInteraction <OWSPreviewText>
@property (nonatomic, readonly) NSMutableArray<NSString *> *attachmentIds; @property (nonatomic, readonly) NSMutableArray<NSString *> *attachmentIds;

View File

@ -2,7 +2,7 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/TSMessage.h> #import <SessionMessagingKit/TSMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -5,7 +5,6 @@
@import Foundation; @import Foundation;
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
#import "NSString+SSK.h"
#import "TSDatabaseSecondaryIndexes.h" #import "TSDatabaseSecondaryIndexes.h"
#import "OWSPrimaryStorage.h" #import "OWSPrimaryStorage.h"
#import "ProfileManagerProtocol.h" #import "ProfileManagerProtocol.h"
@ -18,9 +17,9 @@
#import "TSGroupThread.h" #import "TSGroupThread.h"
#import "TSQuotedMessage.h" #import "TSQuotedMessage.h"
#import <SignalCoreKit/NSDate+OWS.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseTransaction.h> #import <YapDatabase/YapDatabaseTransaction.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -109,7 +108,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
if (!self.recipientStateMap) { if (!self.recipientStateMap) {
[self migrateRecipientStateMapWithCoder:coder]; [self migrateRecipientStateMapWithCoder:coder];
OWSAssertDebug(self.recipientStateMap);
} }
} }
@ -118,9 +116,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)migrateRecipientStateMapWithCoder:(NSCoder *)coder - (void)migrateRecipientStateMapWithCoder:(NSCoder *)coder
{ {
OWSAssertDebug(!self.recipientStateMap);
OWSAssertDebug(coder);
// Determine the "overall message state." // Determine the "overall message state."
TSOutgoingMessageState oldMessageState = TSOutgoingMessageStateFailed; TSOutgoingMessageState oldMessageState = TSOutgoingMessageStateFailed;
NSNumber *_Nullable messageStateValue = [coder decodeObjectForKey:@"messageState"]; NSNumber *_Nullable messageStateValue = [coder decodeObjectForKey:@"messageState"];
@ -184,7 +179,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
NSString *_Nullable singleGroupRecipient = [coder decodeObjectForKey:@"singleGroupRecipient"]; NSString *_Nullable singleGroupRecipient = [coder decodeObjectForKey:@"singleGroupRecipient"];
if (singleGroupRecipient) { if (singleGroupRecipient) {
OWSFailDebug(@"unexpected single group recipient message.");
// If this is a "single group recipient message", treat it as such. // If this is a "single group recipient message", treat it as such.
recipientIds = @[ recipientIds = @[
singleGroupRecipient, singleGroupRecipient,
@ -207,7 +201,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
recipientState.state = OWSOutgoingMessageRecipientStateSent; recipientState.state = OWSOutgoingMessageRecipientStateSent;
recipientState.deliveryTimestamp = deliveryTimestamp; recipientState.deliveryTimestamp = deliveryTimestamp;
} else if (wasDeliveredToContact) { } else if (wasDeliveredToContact) {
OWSAssertDebug(!isGroupThread);
recipientState.state = OWSOutgoingMessageRecipientStateSent; recipientState.state = OWSOutgoingMessageRecipientStateSent;
// Use message time as an estimate of delivery time. // Use message time as an estimate of delivery time.
recipientState.deliveryTimestamp = @(self.timestamp); recipientState.deliveryTimestamp = @(self.timestamp);
@ -329,7 +322,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
_groupMetaMessage = groupMetaMessage; _groupMetaMessage = groupMetaMessage;
} }
} else { } else {
OWSAssertDebug(groupMetaMessage == TSGroupMetaMessageUnspecified);
// Specifying a group meta message only makes sense for Group threads // Specifying a group meta message only makes sense for Group threads
_groupMetaMessage = TSGroupMetaMessageUnspecified; _groupMetaMessage = TSGroupMetaMessageUnspecified;
} }
@ -377,7 +369,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
TSAttachment *_Nullable attachment = TSAttachment *_Nullable attachment =
[TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction];
if (!attachment) { if (!attachment) {
OWSLogError(@"Couldn't load interaction's attachment for deletion.");
continue; continue;
} }
[attachment removeWithTransaction:transaction]; [attachment removeWithTransaction:transaction];
@ -417,8 +408,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
+ (TSOutgoingMessageState)messageStateForRecipientStates:(NSArray<TSOutgoingMessageRecipientState *> *)recipientStates + (TSOutgoingMessageState)messageStateForRecipientStates:(NSArray<TSOutgoingMessageRecipientState *> *)recipientStates
{ {
OWSAssertDebug(recipientStates);
// If there are any "sending" recipients, consider this message "sending". // If there are any "sending" recipients, consider this message "sending".
BOOL hasFailed = NO; BOOL hasFailed = NO;
for (TSOutgoingMessageRecipientState *recipientState in recipientStates) { for (TSOutgoingMessageRecipientState *recipientState in recipientStates) {
@ -455,8 +444,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
// There's no need to save this message, since it's not displayed to the user. // There's no need to save this message, since it's not displayed to the user.
// //
// Should we find a need to save this in the future, we need to exclude any non-serializable properties. // Should we find a need to save this in the future, we need to exclude any non-serializable properties.
OWSLogDebug(@"Skipping save for transient outgoing message.");
return; return;
} }
@ -483,8 +470,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
// no longer be considered sent. // no longer be considered sent.
// So here we take extra care not to stop any expiration that had previously started. // So here we take extra care not to stop any expiration that had previously started.
// This can also happen under normal cirumstances with an outgoing group message. // This can also happen under normal cirumstances with an outgoing group message.
OWSLogWarn(@"expiration previously started");
return YES; return YES;
} }
@ -587,10 +572,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (nullable TSOutgoingMessageRecipientState *)recipientStateForRecipientId:(NSString *)recipientId - (nullable TSOutgoingMessageRecipientState *)recipientStateForRecipientId:(NSString *)recipientId
{ {
OWSAssertDebug(recipientId.length > 0);
TSOutgoingMessageRecipientState *_Nullable result = self.recipientStateMap[recipientId]; TSOutgoingMessageRecipientState *_Nullable result = self.recipientStateMap[recipientId];
OWSAssertDebug(result);
return [result copy]; return [result copy];
} }
@ -598,7 +580,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)updateWithSendingError:(NSError *)error transaction:(YapDatabaseReadWriteTransaction *)transaction - (void)updateWithSendingError:(NSError *)error transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(error);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
// Mark any "sending" recipients as "failed." // Mark any "sending" recipients as "failed."
@ -613,8 +594,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)updateWithAllSendingRecipientsMarkedAsFailedWithTansaction:(YapDatabaseReadWriteTransaction *)transaction - (void)updateWithAllSendingRecipientsMarkedAsFailedWithTansaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
// Mark any "sending" recipients as "failed." // Mark any "sending" recipients as "failed."
@ -629,8 +608,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)updateWithMarkingAllUnsentRecipientsAsSendingWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)updateWithMarkingAllUnsentRecipientsAsSendingWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
// Mark any "sending" recipients as "failed." // Mark any "sending" recipients as "failed."
@ -654,9 +631,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)updateWithCustomMessage:(NSString *)customMessage transaction:(YapDatabaseReadWriteTransaction *)transaction - (void)updateWithCustomMessage:(NSString *)customMessage transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(customMessage);
OWSAssertDebug(transaction);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
[message setCustomMessage:customMessage]; [message setCustomMessage:customMessage];
@ -673,9 +647,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)updateWithSentRecipient:(NSString *)recipientId - (void)updateWithSentRecipient:(NSString *)recipientId
wasSentByUD:(BOOL)wasSentByUD wasSentByUD:(BOOL)wasSentByUD
transaction:(YapDatabaseReadWriteTransaction *)transaction { transaction:(YapDatabaseReadWriteTransaction *)transaction {
OWSAssertDebug(recipientId.length > 0);
OWSAssertDebug(transaction);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
TSOutgoingMessageRecipientState *_Nullable recipientState TSOutgoingMessageRecipientState *_Nullable recipientState
@ -688,9 +659,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)updateWithSkippedRecipient:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction - (void)updateWithSkippedRecipient:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(recipientId.length > 0);
OWSAssertDebug(transaction);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
TSOutgoingMessageRecipientState *_Nullable recipientState TSOutgoingMessageRecipientState *_Nullable recipientState
@ -704,9 +672,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
deliveryTimestamp:(NSNumber *_Nullable)deliveryTimestamp deliveryTimestamp:(NSNumber *_Nullable)deliveryTimestamp
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(recipientId.length > 0);
OWSAssertDebug(transaction);
// If delivery notification doesn't include timestamp, use "now" as an estimate. // If delivery notification doesn't include timestamp, use "now" as an estimate.
if (!deliveryTimestamp) { if (!deliveryTimestamp) {
deliveryTimestamp = @([NSDate ows_millisecondTimeStamp]); deliveryTimestamp = @([NSDate ows_millisecondTimeStamp]);
@ -716,13 +681,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
TSOutgoingMessageRecipientState *_Nullable recipientState TSOutgoingMessageRecipientState *_Nullable recipientState
= message.recipientStateMap[recipientId]; = message.recipientStateMap[recipientId];
if (!recipientState) { if (!recipientState) { return; }
// OWSFailDebug(@"Missing recipient state for delivered recipient: %@", recipientId);
return;
}
if (recipientState.state != OWSOutgoingMessageRecipientStateSent) {
OWSLogWarn(@"marking unsent message as delivered.");
}
recipientState.state = OWSOutgoingMessageRecipientStateSent; recipientState.state = OWSOutgoingMessageRecipientStateSent;
recipientState.deliveryTimestamp = deliveryTimestamp; recipientState.deliveryTimestamp = deliveryTimestamp;
}]; }];
@ -732,16 +691,10 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
readTimestamp:(uint64_t)readTimestamp readTimestamp:(uint64_t)readTimestamp
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(recipientId.length > 0);
OWSAssertDebug(transaction);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
TSOutgoingMessageRecipientState *_Nullable recipientState = message.recipientStateMap[recipientId]; TSOutgoingMessageRecipientState *_Nullable recipientState = message.recipientStateMap[recipientId];
if (!recipientState) { return; } if (!recipientState) { return; }
if (recipientState.state != OWSOutgoingMessageRecipientStateSent) {
OWSLogWarn(@"Marking unsent message as delivered.");
}
recipientState.state = OWSOutgoingMessageRecipientStateSent; recipientState.state = OWSOutgoingMessageRecipientStateSent;
recipientState.readTimestamp = @(readTimestamp); recipientState.readTimestamp = @(readTimestamp);
}]; }];
@ -752,8 +705,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
isSentUpdate:(BOOL)isSentUpdate isSentUpdate:(BOOL)isSentUpdate
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
[self [self
applyChangeToSelfAndLatestCopy:transaction applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
@ -764,8 +715,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
= [NSMutableDictionary new]; = [NSMutableDictionary new];
for (NSString *recipientId in udRecipientIds) { for (NSString *recipientId in udRecipientIds) {
if (recipientStateMap[recipientId]) { if (recipientStateMap[recipientId]) {
OWSFailDebug(
@"recipient appears more than once in recipient lists: %@", recipientId);
continue; continue;
} }
TSOutgoingMessageRecipientState *recipientState = TSOutgoingMessageRecipientState *recipientState =
@ -776,8 +725,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
} }
for (NSString *recipientId in nonUdRecipientIds) { for (NSString *recipientId in nonUdRecipientIds) {
if (recipientStateMap[recipientId]) { if (recipientStateMap[recipientId]) {
OWSFailDebug(
@"recipient appears more than once in recipient lists: %@", recipientId);
continue; continue;
} }
TSOutgoingMessageRecipientState *recipientState = TSOutgoingMessageRecipientState *recipientState =
@ -822,9 +769,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)updateWithSendingToSingleGroupRecipient:(NSString *)singleGroupRecipient - (void)updateWithSendingToSingleGroupRecipient:(NSString *)singleGroupRecipient
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
OWSAssertDebug(singleGroupRecipient.length > 0);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
TSOutgoingMessageRecipientState *recipientState = TSOutgoingMessageRecipientState *recipientState =
@ -853,8 +797,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (void)updateWithFakeMessageState:(TSOutgoingMessageState)messageState - (void)updateWithFakeMessageState:(TSOutgoingMessageState)messageState
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
[self applyChangeToSelfAndLatestCopy:transaction [self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSOutgoingMessage *message) { changeBlock:^(TSOutgoingMessage *message) {
for (TSOutgoingMessageRecipientState *recipientState in message.recipientStateMap for (TSOutgoingMessageRecipientState *recipientState in message.recipientStateMap
@ -870,7 +812,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
recipientState.state = OWSOutgoingMessageRecipientStateSent; recipientState.state = OWSOutgoingMessageRecipientStateSent;
break; break;
default: default:
OWSFailDebug(@"unexpected message state.");
break; break;
} }
} }
@ -882,7 +823,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
- (nullable id)dataMessageBuilder - (nullable id)dataMessageBuilder
{ {
TSThread *thread = self.thread; TSThread *thread = self.thread;
OWSAssertDebug(thread);
SNProtoDataMessageBuilder *builder = [SNProtoDataMessage builder]; SNProtoDataMessageBuilder *builder = [SNProtoDataMessage builder];
[builder setTimestamp:self.timestamp]; [builder setTimestamp:self.timestamp];
@ -890,11 +830,8 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
if ([self.body lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) { if ([self.body lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) {
[builder setBody:self.body]; [builder setBody:self.body];
} else { } else {
OWSFailDebug(@"message body length too long.");
NSString *truncatedBody = [self.body copy]; NSString *truncatedBody = [self.body copy];
while ([truncatedBody lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > kOversizeTextMessageSizeThreshold) { while ([truncatedBody lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > kOversizeTextMessageSizeThreshold) {
OWSLogError(@"truncating body which is too long: %lu",
(unsigned long)[truncatedBody lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
truncatedBody = [truncatedBody substringToIndex:truncatedBody.length / 2]; truncatedBody = [truncatedBody substringToIndex:truncatedBody.length / 2];
} }
[builder setBody:truncatedBody]; [builder setBody:truncatedBody];
@ -926,7 +863,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
SNProtoAttachmentPointer *_Nullable attachmentProto = SNProtoAttachmentPointer *_Nullable attachmentProto =
[TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject]; [TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject];
if (!attachmentProto) { if (!attachmentProto) {
OWSFailDebug(@"could not build protobuf.");
return nil; return nil;
} }
[groupBuilder setAvatar:attachmentProto]; [groupBuilder setAvatar:attachmentProto];
@ -939,7 +875,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
NSError *error; NSError *error;
SNProtoGroupContext *_Nullable groupContextProto = [groupBuilder buildAndReturnError:&error]; SNProtoGroupContext *_Nullable groupContextProto = [groupBuilder buildAndReturnError:&error];
if (error || !groupContextProto) { if (error || !groupContextProto) {
OWSFailDebug(@"could not build protobuf: %@.", error);
return nil; return nil;
} }
[builder setGroup:groupContextProto]; [builder setGroup:groupContextProto];
@ -952,7 +887,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
SNProtoAttachmentPointer *_Nullable attachmentProto = SNProtoAttachmentPointer *_Nullable attachmentProto =
[TSAttachmentStream buildProtoForAttachmentId:attachmentId]; [TSAttachmentStream buildProtoForAttachmentId:attachmentId];
if (!attachmentProto) { if (!attachmentProto) {
OWSFailDebug(@"could not build protobuf.");
return nil; return nil;
} }
[attachments addObject:attachmentProto]; [attachments addObject:attachmentProto];
@ -966,7 +900,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
NSError *error; NSError *error;
SNProtoDataMessageQuote *_Nullable quoteProto = [quotedMessageBuilder buildAndReturnError:&error]; SNProtoDataMessageQuote *_Nullable quoteProto = [quotedMessageBuilder buildAndReturnError:&error];
if (error || !quoteProto) { if (error || !quoteProto) {
OWSFailDebug(@"could not build protobuf: %@.", error);
return nil; return nil;
} }
[builder setQuote:quoteProto]; [builder setQuote:quoteProto];
@ -983,7 +916,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
SNProtoAttachmentPointer *_Nullable attachmentProto = SNProtoAttachmentPointer *_Nullable attachmentProto =
[TSAttachmentStream buildProtoForAttachmentId:self.linkPreview.imageAttachmentId]; [TSAttachmentStream buildProtoForAttachmentId:self.linkPreview.imageAttachmentId];
if (!attachmentProto) { if (!attachmentProto) {
OWSFailDebug(@"Could not build link preview image protobuf.");
} else { } else {
[previewBuilder setImage:attachmentProto]; [previewBuilder setImage:attachmentProto];
} }
@ -992,7 +925,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
NSError *error; NSError *error;
SNProtoDataMessagePreview *_Nullable previewProto = [previewBuilder buildAndReturnError:&error]; SNProtoDataMessagePreview *_Nullable previewProto = [previewBuilder buildAndReturnError:&error];
if (error || !previewProto) { if (error || !previewProto) {
OWSFailDebug(@"Could not build link preview protobuf: %@.", error);
} else { } else {
[builder addPreview:previewProto]; [builder addPreview:previewProto];
} }
@ -1036,7 +969,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
SNProtoDataMessageQuoteQuotedAttachment *_Nullable quotedAttachmentMessage = SNProtoDataMessageQuoteQuotedAttachment *_Nullable quotedAttachmentMessage =
[quotedAttachmentBuilder buildAndReturnError:&error]; [quotedAttachmentBuilder buildAndReturnError:&error];
if (error || !quotedAttachmentMessage) { if (error || !quotedAttachmentMessage) {
OWSFailDebug(@"could not build protobuf: %@", error);
return nil; return nil;
} }
@ -1047,7 +979,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
if (hasQuotedText || hasQuotedAttachment) { if (hasQuotedText || hasQuotedAttachment) {
return quoteBuilder; return quoteBuilder;
} else { } else {
OWSFailDebug(@"Invalid quoted message data.");
return nil; return nil;
} }
} }
@ -1055,10 +986,8 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
// recipientId is nil when building "sent" sync messages for messages sent to groups. // recipientId is nil when building "sent" sync messages for messages sent to groups.
- (nullable SNProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId - (nullable SNProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId
{ {
OWSAssertDebug(self.thread);
SNProtoDataMessageBuilder *_Nullable builder = [self dataMessageBuilder]; SNProtoDataMessageBuilder *_Nullable builder = [self dataMessageBuilder];
if (builder == nil) { if (builder == nil) {
OWSFailDebug(@"Couldn't build protobuf.");
return nil; return nil;
} }
@ -1082,7 +1011,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
NSError *error; NSError *error;
SNProtoDataMessage *_Nullable dataProto = [builder buildAndReturnError:&error]; SNProtoDataMessage *_Nullable dataProto = [builder buildAndReturnError:&error];
if (error != nil || dataProto == nil) { if (error != nil || dataProto == nil) {
OWSFailDebug(@"Couldn't build protobuf due to error: %@.", error);
return nil; return nil;
} }
return dataProto; return dataProto;
@ -1092,7 +1020,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
SNProtoDataMessage *_Nullable dataMessage = [self buildDataMessage:recipient.recipientId]; SNProtoDataMessage *_Nullable dataMessage = [self buildDataMessage:recipient.recipientId];
if (dataMessage == nil) { if (dataMessage == nil) {
OWSFailDebug(@"Couldn't build protobuf.");
return nil; return nil;
} }
@ -1109,7 +1036,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
NSError *error; NSError *error;
NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error]; NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error];
if (error != nil || contentData == nil) { if (error != nil || contentData == nil) {
OWSFailDebug(@"Couldn't serialize protobuf due to error: %@.", error);
return nil; return nil;
} }

View File

@ -3,6 +3,47 @@
FOUNDATION_EXPORT double SessionMessagingKitVersionNumber; FOUNDATION_EXPORT double SessionMessagingKitVersionNumber;
FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[]; FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[];
#import <SessionMessagingKit/AppReadiness.h>
#import <SessionMessagingKit/NotificationsProtocol.h>
#import <SessionMessagingKit/OWSBackgroundTask.h>
#import <SessionMessagingKit/OWSBlockingManager.h>
#import <SessionMessagingKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
#import <SessionMessagingKit/OWSDisappearingMessagesConfiguration.h>
#import <SessionMessagingKit/OWSDisappearingMessagesFinder.h>
#import <SessionMessagingKit/OWSDisappearingMessagesJob.h>
#import <SessionMessagingKit/OWSIdentityManager.h>
#import <SessionMessagingKit/OWSIncomingMessageFinder.h>
#import <SessionMessagingKit/OWSMediaGalleryFinder.h>
#import <SessionMessagingKit/OWSOutgoingReceiptManager.h>
#import <SessionMessagingKit/OWSPrimaryStorage.h>
#import <SessionMessagingKit/OWSQuotedReplyModel.h>
#import <SessionMessagingKit/OWSReadReceiptManager.h>
#import <SessionMessagingKit/OWSReadTracking.h>
#import <SessionMessagingKit/OWSRecipientIdentity.h>
#import <SessionMessagingKit/OWSStorage.h>
#import <SessionMessagingKit/ProfileManagerProtocol.h>
#import <SessionMessagingKit/ProtoUtils.h>
#import <SessionMessagingKit/SSKEnvironment.h>
#import <SessionMessagingKit/SSKJobRecord.h>
#import <SessionMessagingKit/TSAccountManager.h>
#import <SessionMessagingKit/TSAttachment.h> #import <SessionMessagingKit/TSAttachment.h>
#import <SessionMessagingKit/TSAttachmentPointer.h> #import <SessionMessagingKit/TSAttachmentPointer.h>
#import <SessionMessagingKit/TSAttachmentStream.h> #import <SessionMessagingKit/TSAttachmentStream.h>
#import <SessionMessagingKit/TSContactThread.h>
#import <SessionMessagingKit/TSDatabaseSecondaryIndexes.h>
#import <SessionMessagingKit/TSDatabaseView.h>
#import <SessionMessagingKit/TSErrorMessage.h>
#import <SessionMessagingKit/TSErrorMessage_privateConstructor.h>
#import <SessionMessagingKit/TSGroupModel.h>
#import <SessionMessagingKit/TSGroupThread.h>
#import <SessionMessagingKit/TSIncomingMessage.h>
#import <SessionMessagingKit/TSInfoMessage.h>
#import <SessionMessagingKit/TSInteraction.h>
#import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
#import <SessionMessagingKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
#import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SessionMessagingKit/TSQuotedMessage.h>
#import <SessionMessagingKit/TSThread.h>
#import <SessionMessagingKit/TSUnreadIndicatorInteraction.h>
#import <SessionMessagingKit/YapDatabaseConnection+OWS.h>
#import <SessionMessagingKit/YapDatabaseTransaction+OWS.h>

View File

@ -350,7 +350,7 @@ public final class OpenGroupAPI : DotNetAPI {
storage.setUserCount(to: memberCount, forOpenGroupWithID: "\(server).\(channel)", using: transaction) storage.setUserCount(to: memberCount, forOpenGroupWithID: "\(server).\(channel)", using: transaction)
} }
let openGroupInfo = OpenGroupInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount) let openGroupInfo = OpenGroupInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount)
Configuration.shared.openGroupAPIDelegate.updateProfileIfNeeded(for: channel, on: server, from: openGroupInfo) OpenGroupAPI.updateProfileIfNeeded(for: channel, on: server, from: openGroupInfo)
return openGroupInfo return openGroupInfo
} }
} }
@ -358,6 +358,39 @@ public final class OpenGroupAPI : DotNetAPI {
} }
} }
public static func updateProfileIfNeeded(for channel: UInt64, on server: String, from info: OpenGroupInfo) {
let openGroupID = "\(server).\(channel)"
Storage.write { transaction in
// Update user count
Storage.shared.setUserCount(to: info.memberCount, forOpenGroupWithID: openGroupID, using: transaction)
let thread = TSGroupThread.getOrCreateThread(withGroupId: openGroupID.data(using: .utf8)!, groupType: .openGroup, transaction: transaction)
// Update display name if needed
let model = thread.groupModel
if model.groupName != info.displayName {
let newGroupModel = TSGroupModel(title: info.displayName, memberIds: model.groupMemberIds, image: model.groupImage, groupId: model.groupId, groupType: model.groupType, adminIds: model.groupAdminIds)
thread.groupModel = newGroupModel
thread.save(with: transaction)
}
// Download and update profile picture if needed
let oldProfilePictureURL = Storage.shared.getProfilePictureURL(forOpenGroupWithID: openGroupID)
if oldProfilePictureURL != info.profilePictureURL || model.groupImage == nil {
Storage.shared.setProfilePictureURL(to: info.profilePictureURL, forOpenGroupWithID: openGroupID, using: transaction)
if let profilePictureURL = info.profilePictureURL {
var sanitizedServerURL = server
while sanitizedServerURL.hasSuffix("/") { sanitizedServerURL.removeLast() }
var sanitizedProfilePictureURL = profilePictureURL
while sanitizedProfilePictureURL.hasPrefix("/") { sanitizedProfilePictureURL.removeFirst() }
let url = "\(sanitizedServerURL)/\(sanitizedProfilePictureURL)"
FileServerAPI.downloadAttachment(from: url).map2 { data in
let attachmentStream = TSAttachmentStream(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(data.count), sourceFilename: nil, caption: nil, albumMessageId: nil)
try attachmentStream.write(data)
thread.updateAvatar(with: attachmentStream)
}
}
}
}
}
public static func join(_ channel: UInt64, on server: String) -> Promise<Void> { public static func join(_ channel: UInt64, on server: String) -> Promise<Void> {
return attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global(qos: .default)) { return attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global(qos: .default)) {
getOpenGroupServerPublicKey(for: server).then(on: DispatchQueue.global(qos: .default)) { serverPublicKey in getOpenGroupServerPublicKey(for: server).then(on: DispatchQueue.global(qos: .default)) { serverPublicKey in

View File

@ -1,5 +0,0 @@
public protocol OpenGroupAPIDelegate {
func updateProfileIfNeeded(for channel: UInt64, on server: String, from info: OpenGroupInfo)
}

View File

@ -8,7 +8,7 @@ import MobileCoreServices
import PromiseKit import PromiseKit
import AVFoundation import AVFoundation
enum SignalAttachmentError: Error { public enum SignalAttachmentError: Error {
case missingData case missingData
case fileSizeTooLarge case fileSizeTooLarge
case invalidData case invalidData
@ -21,17 +21,16 @@ enum SignalAttachmentError: Error {
} }
extension String { extension String {
var filenameWithoutExtension: String { public var filenameWithoutExtension: String {
return (self as NSString).deletingPathExtension return (self as NSString).deletingPathExtension
} }
var fileExtension: String? { public var fileExtension: String? {
return (self as NSString).pathExtension return (self as NSString).pathExtension
} }
func appendingFileExtension(_ fileExtension: String) -> String { public func appendingFileExtension(_ fileExtension: String) -> String {
guard let result = (self as NSString).appendingPathExtension(fileExtension) else { guard let result = (self as NSString).appendingPathExtension(fileExtension) else {
owsFailDebug("Failed to append file extension: \(fileExtension) to string: \(self)")
return self return self
} }
return result return result
@ -160,12 +159,9 @@ public class SignalAttachment: NSObject {
@objc @objc
public let dataUTI: String public let dataUTI: String
var error: SignalAttachmentError? { public var error: SignalAttachmentError? {
didSet { didSet {
AssertIsOnMainThread()
assert(oldValue == nil) assert(oldValue == nil)
Logger.verbose("Attachment has error: \(String(describing: error))")
} }
} }
@ -213,7 +209,6 @@ public class SignalAttachment: NSObject {
public var errorName: String? { public var errorName: String? {
guard let error = error else { guard let error = error else {
// This method should only be called if there is an error. // This method should only be called if there is an error.
owsFailDebug("Missing error")
return nil return nil
} }
@ -224,11 +219,9 @@ public class SignalAttachment: NSObject {
public var localizedErrorDescription: String? { public var localizedErrorDescription: String? {
guard let error = self.error else { guard let error = self.error else {
// This method should only be called if there is an error. // This method should only be called if there is an error.
owsFailDebug("Missing error")
return nil return nil
} }
guard let errorDescription = error.errorDescription else { guard let errorDescription = error.errorDescription else {
owsFailDebug("Missing error description")
return nil return nil
} }
@ -238,7 +231,6 @@ public class SignalAttachment: NSObject {
@objc @objc
public class var missingDataErrorMessage: String { public class var missingDataErrorMessage: String {
guard let errorDescription = SignalAttachmentError.missingData.errorDescription else { guard let errorDescription = SignalAttachmentError.missingData.errorDescription else {
owsFailDebug("Missing error description")
return "" return ""
} }
return errorDescription return errorDescription
@ -284,7 +276,6 @@ public class SignalAttachment: NSObject {
do { do {
let filePath = mediaUrl.path let filePath = mediaUrl.path
guard FileManager.default.fileExists(atPath: filePath) else { guard FileManager.default.fileExists(atPath: filePath) else {
owsFailDebug("asset at \(filePath) doesn't exist")
return nil return nil
} }
@ -298,7 +289,6 @@ public class SignalAttachment: NSObject {
return image return image
} catch let error { } catch let error {
Logger.verbose("Could not generate video thumbnail: \(error.localizedDescription)")
return nil return nil
} }
} }
@ -536,7 +526,6 @@ public class SignalAttachment: NSObject {
for dataUTI in inputImageUTISet { for dataUTI in inputImageUTISet {
if pasteboardUTISet.contains(dataUTI) { if pasteboardUTISet.contains(dataUTI) {
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else { guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
return nil return nil
} }
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI) let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
@ -547,7 +536,6 @@ public class SignalAttachment: NSObject {
for dataUTI in videoUTISet { for dataUTI in videoUTISet {
if pasteboardUTISet.contains(dataUTI) { if pasteboardUTISet.contains(dataUTI) {
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else { guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
return nil return nil
} }
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI) let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
@ -557,7 +545,6 @@ public class SignalAttachment: NSObject {
for dataUTI in audioUTISet { for dataUTI in audioUTISet {
if pasteboardUTISet.contains(dataUTI) { if pasteboardUTISet.contains(dataUTI) {
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else { guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
return nil return nil
} }
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI) let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
@ -567,7 +554,6 @@ public class SignalAttachment: NSObject {
let dataUTI = pasteboardUTISet[pasteboardUTISet.startIndex] let dataUTI = pasteboardUTISet[pasteboardUTISet.startIndex]
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else { guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
return nil return nil
} }
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI) let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
@ -579,11 +565,9 @@ public class SignalAttachment: NSObject {
private class func dataForFirstPasteboardItem(dataUTI: String) -> Data? { private class func dataForFirstPasteboardItem(dataUTI: String) -> Data? {
let itemSet = IndexSet(integer: 0) let itemSet = IndexSet(integer: 0)
guard let datas = UIPasteboard.general.data(forPasteboardType: dataUTI, inItemSet: itemSet) else { guard let datas = UIPasteboard.general.data(forPasteboardType: dataUTI, inItemSet: itemSet) else {
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
return nil return nil
} }
guard datas.count > 0 else { guard datas.count > 0 else {
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
return nil return nil
} }
return datas[0] return datas[0]
@ -613,7 +597,6 @@ public class SignalAttachment: NSObject {
} }
guard dataSource.dataLength() > 0 else { guard dataSource.dataLength() > 0 else {
owsFailDebug("imageData was empty")
attachment.error = .invalidData attachment.error = .invalidData
return attachment return attachment
} }
@ -625,7 +608,6 @@ public class SignalAttachment: NSObject {
} }
// Never re-encode animated images (i.e. GIFs) as JPEGs. // Never re-encode animated images (i.e. GIFs) as JPEGs.
Logger.verbose("Sending raw \(attachment.mimeType) to retain any animation")
return attachment return attachment
} else { } else {
guard let image = UIImage(data: dataSource.data()) else { guard let image = UIImage(data: dataSource.data()) else {
@ -649,17 +631,14 @@ public class SignalAttachment: NSObject {
// However the problem comes in when you edit an HEIC image in Photos.app - the image is saved // However the problem comes in when you edit an HEIC image in Photos.app - the image is saved
// in the Photos.app as a JPEG, but retains the (now incongruous) HEIC extension in the filename. // in the Photos.app as a JPEG, but retains the (now incongruous) HEIC extension in the filename.
assert(dataUTI == kUTTypeJPEG as String || !isValidOutput) assert(dataUTI == kUTTypeJPEG as String || !isValidOutput)
Logger.verbose("changing extension: \(sourceFileExtension) to match jpg uti type")
let baseFilename = sourceFilename.filenameWithoutExtension let baseFilename = sourceFilename.filenameWithoutExtension
dataSource.sourceFilename = baseFilename.appendingFileExtension("jpg") dataSource.sourceFilename = baseFilename.appendingFileExtension("jpg")
} }
if isValidOutput { if isValidOutput {
Logger.verbose("Rewriting attachment with metadata removed \(attachment.mimeType)")
return removeImageMetadata(attachment: attachment) return removeImageMetadata(attachment: attachment)
} else { } else {
Logger.verbose("Compressing attachment as image/jpeg, \(dataSource.dataLength()) bytes")
return compressImageAsJPEG(image: image, attachment: attachment, filename: dataSource.sourceFilename, imageQuality: imageQuality) return compressImageAsJPEG(image: image, attachment: attachment, filename: dataSource.sourceFilename, imageQuality: imageQuality)
} }
} }
@ -706,7 +685,6 @@ public class SignalAttachment: NSObject {
let attachment = SignalAttachment(dataSource: dataSource, dataUTI: dataUTI) let attachment = SignalAttachment(dataSource: dataSource, dataUTI: dataUTI)
attachment.cachedImage = image attachment.cachedImage = image
Logger.verbose("Writing \(attachment.mimeType) as image/jpeg")
return compressImageAsJPEG(image: image, attachment: attachment, filename: filename, imageQuality: imageQuality) return compressImageAsJPEG(image: image, attachment: attachment, filename: filename, imageQuality: imageQuality)
} }
@ -751,7 +729,6 @@ public class SignalAttachment: NSObject {
dataSource.dataLength() <= kMaxFileSizeImage { dataSource.dataLength() <= kMaxFileSizeImage {
let recompressedAttachment = SignalAttachment(dataSource: dataSource, dataUTI: kUTTypeJPEG as String) let recompressedAttachment = SignalAttachment(dataSource: dataSource, dataUTI: kUTTypeJPEG as String)
recompressedAttachment.cachedImage = dstImage recompressedAttachment.cachedImage = dstImage
Logger.verbose("Converted \(attachment.mimeType) to image/jpeg, \(jpgImageData.count) bytes")
return recompressedAttachment return recompressedAttachment
} }
@ -781,7 +758,6 @@ public class SignalAttachment: NSObject {
// Resizing using a CGContext seems to work fine. // Resizing using a CGContext seems to work fine.
private class func imageScaled(_ uiImage: UIImage, toMaxSize maxSize: CGFloat) -> UIImage? { private class func imageScaled(_ uiImage: UIImage, toMaxSize maxSize: CGFloat) -> UIImage? {
guard let cgImage = uiImage.cgImage else { guard let cgImage = uiImage.cgImage else {
owsFailDebug("UIImage missing cgImage.")
return nil return nil
} }
@ -804,7 +780,6 @@ public class SignalAttachment: NSObject {
bytesPerRow: 0, bytesPerRow: 0,
space: colorSpace, space: colorSpace,
bitmapInfo: bitmapInfo.rawValue) else { bitmapInfo: bitmapInfo.rawValue) else {
owsFailDebug("could not create CGContext.")
return nil return nil
} }
context.interpolationQuality = .high context.interpolationQuality = .high
@ -814,7 +789,6 @@ public class SignalAttachment: NSObject {
context.draw(cgImage, in: drawRect) context.draw(cgImage, in: drawRect)
guard let newCGImage = context.makeImage() else { guard let newCGImage = context.makeImage() else {
owsFailDebug("could not create new CGImage.")
return nil return nil
} }
return UIImage(cgImage: newCGImage, return UIImage(cgImage: newCGImage,
@ -914,7 +888,6 @@ public class SignalAttachment: NSObject {
return strippedAttachment return strippedAttachment
} else { } else {
Logger.verbose("CGImageDestinationFinalize failed")
attachment.error = .couldNotRemoveMetadata attachment.error = .couldNotRemoveMetadata
return attachment return attachment
} }
@ -934,10 +907,6 @@ public class SignalAttachment: NSObject {
return attachment return attachment
} }
if !isValidOutputVideo(dataSource: dataSource, dataUTI: dataUTI) {
owsFailDebug("building video with invalid output, migrate to async API using compressVideoAsMp4")
}
return newAttachment(dataSource: dataSource, return newAttachment(dataSource: dataSource,
dataUTI: dataUTI, dataUTI: dataUTI,
validUTISet: videoUTISet, validUTISet: videoUTISet,
@ -949,7 +918,6 @@ public class SignalAttachment: NSObject {
OWSFileSystem.ensureDirectoryExists(baseDir.path) OWSFileSystem.ensureDirectoryExists(baseDir.path)
let toUrl = baseDir.appendingPathComponent(fromUrl.lastPathComponent) let toUrl = baseDir.appendingPathComponent(fromUrl.lastPathComponent)
Logger.debug("moving \(fromUrl) -> \(toUrl)")
try FileManager.default.copyItem(at: fromUrl, to: toUrl) try FileManager.default.copyItem(at: fromUrl, to: toUrl)
return toUrl return toUrl
@ -962,8 +930,6 @@ public class SignalAttachment: NSObject {
} }
public class func compressVideoAsMp4(dataSource: DataSource, dataUTI: String) -> (Promise<SignalAttachment>, AVAssetExportSession?) { public class func compressVideoAsMp4(dataSource: DataSource, dataUTI: String) -> (Promise<SignalAttachment>, AVAssetExportSession?) {
Logger.debug("")
guard let url = dataSource.dataUrl() else { guard let url = dataSource.dataUrl() else {
let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI) let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI)
attachment.error = .missingData attachment.error = .missingData
@ -987,15 +953,12 @@ public class SignalAttachment: NSObject {
let (promise, resolver) = Promise<SignalAttachment>.pending() let (promise, resolver) = Promise<SignalAttachment>.pending()
Logger.debug("starting video export")
exportSession.exportAsynchronously { exportSession.exportAsynchronously {
Logger.debug("Completed video export")
let baseFilename = dataSource.sourceFilename let baseFilename = dataSource.sourceFilename
let mp4Filename = baseFilename?.filenameWithoutExtension.appendingFileExtension("mp4") let mp4Filename = baseFilename?.filenameWithoutExtension.appendingFileExtension("mp4")
guard let dataSource = DataSourcePath.dataSource(with: exportURL, guard let dataSource = DataSourcePath.dataSource(with: exportURL,
shouldDeleteOnDeallocation: true) else { shouldDeleteOnDeallocation: true) else {
owsFailDebug("Failed to build data source for exported video URL")
let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI) let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI)
attachment.error = .couldNotConvertToMpeg4 attachment.error = .couldNotConvertToMpeg4
resolver.fulfill(attachment) resolver.fulfill(attachment)
@ -1120,9 +1083,6 @@ public class SignalAttachment: NSObject {
// Check the attachment's error property. // Check the attachment's error property.
@objc @objc
public class func attachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment { public class func attachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment {
if inputImageUTISet.contains(dataUTI) {
owsFailDebug("must specify image quality type")
}
return attachment(dataSource: dataSource, dataUTI: dataUTI, imageQuality: .original) return attachment(dataSource: dataSource, dataUTI: dataUTI, imageQuality: .original)
} }
@ -1175,7 +1135,6 @@ public class SignalAttachment: NSObject {
} }
guard dataSource.dataLength() > 0 else { guard dataSource.dataLength() > 0 else {
owsFailDebug("Empty attachment")
assert(dataSource.dataLength() > 0) assert(dataSource.dataLength() > 0)
attachment.error = .invalidData attachment.error = .invalidData
return attachment return attachment

View File

@ -1,4 +1,5 @@
#import <SessionUtilitiesKit/TSYapDatabaseObject.h> #import <SessionUtilitiesKit/TSYapDatabaseObject.h>
#import <SessionMessagingKit/TSMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -87,6 +88,16 @@ typedef NS_ENUM(NSUInteger, TSAttachmentType) {
+ (NSString *)emojiForMimeType:(NSString *)contentType; + (NSString *)emojiForMimeType:(NSString *)contentType;
#pragma mark - Media Album
- (nullable TSMessage *)fetchAlbumMessageWithTransaction:(YapDatabaseReadTransaction *)transaction;
// `migrateAlbumMessageId` is only used in the migration to the new multi-attachment message scheme,
// and shouldn't be used as a general purpose setter. Instead, `albumMessageId` should be passed as
// an initializer param.
- (void)migrateAlbumMessageId:(NSString *)albumMesssageId;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -244,6 +244,21 @@ NSUInteger const TSAttachmentSchemaVersion = 4;
return _contentType.filterFilename; return _contentType.filterFilename;
} }
#pragma mark - Media Album
- (nullable TSMessage *)fetchAlbumMessageWithTransaction:(YapDatabaseReadTransaction *)transaction
{
if (self.albumMessageId == nil) {
return nil;
}
return [TSMessage fetchObjectWithUniqueID:self.albumMessageId transaction:transaction];
}
- (void)migrateAlbumMessageId:(NSString *)albumMesssageId
{
self.albumMessageId = albumMesssageId;
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View File

@ -11,7 +11,7 @@
#import "TSContactThread.h" #import "TSContactThread.h"
#import "TSGroupThread.h" #import "TSGroupThread.h"
#import "YapDatabaseConnection+OWS.h" #import "YapDatabaseConnection+OWS.h"
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SessionMessagingKit/SessionMessagingKit-Swift.h>
#import "SSKAsserts.h" #import "SSKAsserts.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -2,7 +2,7 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/TSInfoMessage.h> #import <SessionMessagingKit/TSInfoMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -5,7 +5,7 @@
#import "OWSDisappearingConfigurationUpdateInfoMessage.h" #import "OWSDisappearingConfigurationUpdateInfoMessage.h"
#import "NSString+SSK.h" #import "NSString+SSK.h"
#import "OWSDisappearingMessagesConfiguration.h" #import "OWSDisappearingMessagesConfiguration.h"
#import <SessionProtocolKit/SessionProtocolKit.h> #import <SignalCoreKit/NSString+OWS.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -34,8 +34,6 @@ NS_ASSUME_NONNULL_BEGIN
_configurationDurationSeconds = configuration.durationSeconds; _configurationDurationSeconds = configuration.durationSeconds;
// At most one should be set // At most one should be set
OWSAssertDebug(!remoteName || !createdInExistingGroup);
_createdByRemoteName = remoteName; _createdByRemoteName = remoteName;
_createdInExistingGroup = createdInExistingGroup; _createdInExistingGroup = createdInExistingGroup;
@ -52,7 +50,6 @@ NS_ASSUME_NONNULL_BEGIN
-(NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction -(NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction
{ {
if (self.createdInExistingGroup) { if (self.createdInExistingGroup) {
OWSAssertDebug(self.configurationIsEnabled && self.configurationDurationSeconds > 0);
NSString *infoFormat = NSLocalizedString(@"DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT", NSString *infoFormat = NSLocalizedString(@"DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT",
@"Info Message when added to a group which has enabled disappearing messages. Embeds {{time amount}} " @"Info Message when added to a group which has enabled disappearing messages. Embeds {{time amount}} "
@"before messages disappear, see the *_TIME_AMOUNT strings for context."); @"before messages disappear, see the *_TIME_AMOUNT strings for context.");

View File

@ -3,6 +3,7 @@
// //
#import <SessionUtilitiesKit/TSYapDatabaseObject.h> #import <SessionUtilitiesKit/TSYapDatabaseObject.h>
#import <SignalCoreKit/SignalCoreKit.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -4,7 +4,8 @@
#import "OWSDisappearingMessagesConfiguration.h" #import "OWSDisappearingMessagesConfiguration.h"
#import "NSString+SSK.h" #import "NSString+SSK.h"
#import <SessionProtocolKit/SessionProtocolKit.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalCoreKit/NSString+OWS.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -85,9 +86,6 @@ NS_ASSUME_NONNULL_BEGIN
static dispatch_once_t onceToken; static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{ dispatch_once(&onceToken, ^{
max = [[self.validDurationsSeconds valueForKeyPath:@"@max.intValue"] unsignedIntValue]; max = [[self.validDurationsSeconds valueForKeyPath:@"@max.intValue"] unsignedIntValue];
// It's safe to update this assert if we add a larger duration
OWSAssertDebug(max == 1 * kWeekInterval);
}); });
return max; return max;

View File

@ -15,7 +15,7 @@
#import "TSMessage.h" #import "TSMessage.h"
#import "TSThread.h" #import "TSThread.h"
#import <SignalCoreKit/NSDate+OWS.h> #import <SignalCoreKit/NSDate+OWS.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SessionMessagingKit/SessionMessagingKit-Swift.h>
#import <SessionProtocolKit/SessionProtocolKit.h> #import <SessionProtocolKit/SessionProtocolKit.h>
#import "SSKAsserts.h" #import "SSKAsserts.h"

View File

@ -2,6 +2,7 @@
// Copyright (c) 2019 Open Whisper Systems. All rights reserved. // Copyright (c) 2019 Open Whisper Systems. All rights reserved.
// //
import AFNetworking
import Foundation import Foundation
import PromiseKit import PromiseKit
@ -138,29 +139,23 @@ public class OWSLinkPreview: MTLModel {
throw LinkPreviewError.noPreview throw LinkPreviewError.noPreview
} }
guard dataMessage.attachments.count < 1 else { guard dataMessage.attachments.count < 1 else {
Logger.error("Discarding link preview; message has attachments.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
let urlString = previewProto.url let urlString = previewProto.url
guard URL(string: urlString) != nil else { guard URL(string: urlString) != nil else {
Logger.error("Could not parse preview URL.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
guard let body = body else { guard let body = body else {
Logger.error("Preview for message without body.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
let previewUrls = allPreviewUrls(forMessageBodyText: body) let previewUrls = allPreviewUrls(forMessageBodyText: body)
guard previewUrls.contains(urlString) else { guard previewUrls.contains(urlString) else {
Logger.error("URL not present in body.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
guard isValidLinkUrl(urlString) else { guard isValidLinkUrl(urlString) else {
Logger.verbose("Invalid link URL \(urlString).")
Logger.error("Invalid link URL.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
@ -178,7 +173,6 @@ public class OWSLinkPreview: MTLModel {
imageAttachmentPointer.save(with: transaction) imageAttachmentPointer.save(with: transaction)
imageAttachmentId = imageAttachmentPointer.uniqueId imageAttachmentId = imageAttachmentPointer.uniqueId
} else { } else {
Logger.error("Could not parse image proto.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
} }
@ -186,7 +180,6 @@ public class OWSLinkPreview: MTLModel {
let linkPreview = OWSLinkPreview(urlString: urlString, title: title, imageAttachmentId: imageAttachmentId) let linkPreview = OWSLinkPreview(urlString: urlString, title: title, imageAttachmentId: imageAttachmentId)
guard linkPreview.isValid() else { guard linkPreview.isValid() else {
Logger.error("Preview has neither title nor image.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
@ -208,7 +201,6 @@ public class OWSLinkPreview: MTLModel {
let linkPreview = OWSLinkPreview(urlString: info.urlString, title: info.title, imageAttachmentId: imageAttachmentId) let linkPreview = OWSLinkPreview(urlString: info.urlString, title: info.title, imageAttachmentId: imageAttachmentId)
guard linkPreview.isValid() else { guard linkPreview.isValid() else {
owsFailDebug("Preview has neither title nor image.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
@ -225,7 +217,6 @@ public class OWSLinkPreview: MTLModel {
let fileSize = imageData.count let fileSize = imageData.count
guard fileSize > 0 else { guard fileSize > 0 else {
owsFailDebug("Invalid file size for image data.")
return nil return nil
} }
@ -234,17 +225,14 @@ public class OWSLinkPreview: MTLModel {
do { do {
try imageData.write(to: NSURL.fileURL(withPath: filePath), options: .atomicWrite) try imageData.write(to: NSURL.fileURL(withPath: filePath), options: .atomicWrite)
} catch let error as NSError { } catch let error as NSError {
owsFailDebug("file write failed: \(filePath), \(error)")
return nil return nil
} }
guard let dataSource = DataSourcePath.dataSource(withFilePath: filePath, shouldDeleteOnDeallocation: true) else { guard let dataSource = DataSourcePath.dataSource(withFilePath: filePath, shouldDeleteOnDeallocation: true) else {
owsFailDebug("Could not create data source for path: \(filePath)")
return nil return nil
} }
let attachment = TSAttachmentStream(contentType: mimeType, byteCount: UInt32(fileSize), sourceFilename: nil, caption: nil, albumMessageId: nil) let attachment = TSAttachmentStream(contentType: mimeType, byteCount: UInt32(fileSize), sourceFilename: nil, caption: nil, albumMessageId: nil)
guard attachment.write(dataSource) else { guard attachment.write(dataSource) else {
owsFailDebug("Could not write data source for path: \(filePath)")
return nil return nil
} }
attachment.save(with: transaction) attachment.save(with: transaction)
@ -264,11 +252,9 @@ public class OWSLinkPreview: MTLModel {
@objc @objc
public func removeAttachment(transaction: YapDatabaseReadWriteTransaction) { public func removeAttachment(transaction: YapDatabaseReadWriteTransaction) {
guard let imageAttachmentId = imageAttachmentId else { guard let imageAttachmentId = imageAttachmentId else {
owsFailDebug("No attachment id.")
return return
} }
guard let attachment = TSAttachment.fetch(uniqueId: imageAttachmentId, transaction: transaction) else { guard let attachment = TSAttachment.fetch(uniqueId: imageAttachmentId, transaction: transaction) else {
owsFailDebug("Could not load attachment.")
return return
} }
attachment.remove(with: transaction) attachment.remove(with: transaction)
@ -376,18 +362,15 @@ public class OWSLinkPreview: MTLModel {
@objc @objc
public class func displayDomain(forUrl urlString: String?) -> String? { public class func displayDomain(forUrl urlString: String?) -> String? {
guard let urlString = urlString else { guard let urlString = urlString else {
owsFailDebug("Missing url.")
return nil return nil
} }
guard let url = URL(string: urlString) else { guard let url = URL(string: urlString) else {
owsFailDebug("Invalid url.")
return nil return nil
} }
guard let result = whitelistedDomain(forUrl: url, guard let result = whitelistedDomain(forUrl: url,
domainWhitelist: OWSLinkPreview.linkDomainWhitelist, domainWhitelist: OWSLinkPreview.linkDomainWhitelist,
allowSubdomains: false) else { allowSubdomains: false) else {
Logger.error("Missing domain.") return nil
return nil
} }
return result return result
} }
@ -443,12 +426,6 @@ public class OWSLinkPreview: MTLModel {
private static let serialQueue = DispatchQueue(label: "org.signal.linkPreview") private static let serialQueue = DispatchQueue(label: "org.signal.linkPreview")
private class func assertIsOnSerialQueue() {
if _isDebugAssertConfiguration(), #available(iOS 10.0, *) {
assertOnQueue(serialQueue)
}
}
// MARK: - Text Parsing // MARK: - Text Parsing
// This cache should only be accessed on main thread. // This cache should only be accessed on main thread.
@ -465,7 +442,6 @@ public class OWSLinkPreview: MTLModel {
} }
public class func previewUrl(forMessageBodyText body: String?, selectedRange: NSRange?) -> String? { public class func previewUrl(forMessageBodyText body: String?, selectedRange: NSRange?) -> String? {
AssertIsOnMainThread()
// Exit early if link previews are not enabled in order to avoid // Exit early if link previews are not enabled in order to avoid
// tainting the cache. // tainting the cache.
@ -482,7 +458,6 @@ public class OWSLinkPreview: MTLModel {
} }
if let cachedUrl = previewUrlCache.object(forKey: body as NSString) as String? { if let cachedUrl = previewUrlCache.object(forKey: body as NSString) as String? {
Logger.verbose("URL parsing cache hit.")
guard cachedUrl.count > 0 else { guard cachedUrl.count > 0 else {
return nil return nil
} }
@ -496,16 +471,13 @@ public class OWSLinkPreview: MTLModel {
} }
if let selectedRange = selectedRange { if let selectedRange = selectedRange {
Logger.verbose("match: urlString: \(urlMatch.urlString) range: \(urlMatch.matchRange) selectedRange: \(selectedRange)")
let cursorAtEndOfMatch = urlMatch.matchRange.location + urlMatch.matchRange.length == selectedRange.location let cursorAtEndOfMatch = urlMatch.matchRange.location + urlMatch.matchRange.length == selectedRange.location
if selectedRange.location != body.count, if selectedRange.location != body.count,
(urlMatch.matchRange.intersection(selectedRange) != nil || cursorAtEndOfMatch) { (urlMatch.matchRange.intersection(selectedRange) != nil || cursorAtEndOfMatch) {
Logger.debug("ignoring URL, since the user is currently editing it.")
// we don't want to cache the result here, as we want to fetch the link preview // we don't want to cache the result here, as we want to fetch the link preview
// if the user moves the cursor. // if the user moves the cursor.
return nil return nil
} }
Logger.debug("considering URL, since the user is not currently editing it.")
} }
previewUrlCache.setObject(urlMatch.urlString as NSString, forKey: body as NSString) previewUrlCache.setObject(urlMatch.urlString as NSString, forKey: body as NSString)
@ -533,7 +505,6 @@ public class OWSLinkPreview: MTLModel {
do { do {
detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
} catch { } catch {
owsFailDebug("Could not create NSDataDetector: \(error).")
return [] return []
} }
@ -541,7 +512,6 @@ public class OWSLinkPreview: MTLModel {
let matches = detector.matches(in: body, options: [], range: NSRange(location: 0, length: body.count)) let matches = detector.matches(in: body, options: [], range: NSRange(location: 0, length: body.count))
for match in matches { for match in matches {
guard let matchURL = match.url else { guard let matchURL = match.url else {
owsFailDebug("Match missing url")
continue continue
} }
let urlString = matchURL.absoluteString let urlString = matchURL.absoluteString
@ -564,10 +534,8 @@ public class OWSLinkPreview: MTLModel {
return serialQueue.sync { return serialQueue.sync {
guard let linkPreviewDraft = linkPreviewDraftCache, guard let linkPreviewDraft = linkPreviewDraftCache,
linkPreviewDraft.urlString == previewUrl else { linkPreviewDraft.urlString == previewUrl else {
Logger.verbose("----- Cache miss.")
return nil return nil
} }
Logger.verbose("----- Cache hit.")
return linkPreviewDraft return linkPreviewDraft
} }
} }
@ -606,7 +574,6 @@ public class OWSLinkPreview: MTLModel {
return Promise(error: LinkPreviewError.invalidInput) return Promise(error: LinkPreviewError.invalidInput)
} }
if let cachedInfo = cachedLinkPreview(forPreviewUrl: previewUrl) { if let cachedInfo = cachedLinkPreview(forPreviewUrl: previewUrl) {
Logger.verbose("Link preview info cache hit.")
return Promise.value(cachedInfo) return Promise.value(cachedInfo)
} }
return downloadLink(url: previewUrl) return downloadLink(url: previewUrl)
@ -624,9 +591,6 @@ public class OWSLinkPreview: MTLModel {
class func downloadLink(url urlString: String, class func downloadLink(url urlString: String,
remainingRetries: UInt = 3) -> Promise<Data> { remainingRetries: UInt = 3) -> Promise<Data> {
Logger.verbose("url: \(urlString)")
// let sessionConfiguration = ContentProxy.sessionConfiguration() // Loki: Signal's proxy appears to have been banned by YouTube // let sessionConfiguration = ContentProxy.sessionConfiguration() // Loki: Signal's proxy appears to have been banned by YouTube
let sessionConfiguration = URLSessionConfiguration.ephemeral let sessionConfiguration = URLSessionConfiguration.ephemeral
@ -640,7 +604,6 @@ public class OWSLinkPreview: MTLModel {
sessionManager.responseSerializer = AFHTTPResponseSerializer() sessionManager.responseSerializer = AFHTTPResponseSerializer()
guard ContentProxy.configureSessionManager(sessionManager: sessionManager, forUrl: urlString) else { guard ContentProxy.configureSessionManager(sessionManager: sessionManager, forUrl: urlString) else {
owsFailDebug("Could not configure url: \(urlString).")
return Promise(error: LinkPreviewError.assertionFailure) return Promise(error: LinkPreviewError.assertionFailure)
} }
@ -652,40 +615,32 @@ public class OWSLinkPreview: MTLModel {
success: { task, value in success: { task, value in
guard let response = task.response as? HTTPURLResponse else { guard let response = task.response as? HTTPURLResponse else {
Logger.warn("Invalid response: \(type(of: task.response)).")
resolver.reject(LinkPreviewError.assertionFailure) resolver.reject(LinkPreviewError.assertionFailure)
return return
} }
if let contentType = response.allHeaderFields["Content-Type"] as? String { if let contentType = response.allHeaderFields["Content-Type"] as? String {
guard contentType.lowercased().hasPrefix("text/") else { guard contentType.lowercased().hasPrefix("text/") else {
Logger.warn("Invalid content type: \(contentType).")
resolver.reject(LinkPreviewError.invalidContent) resolver.reject(LinkPreviewError.invalidContent)
return return
} }
} }
guard let data = value as? Data else { guard let data = value as? Data else {
Logger.warn("Result is not data: \(type(of: value)).")
resolver.reject(LinkPreviewError.assertionFailure) resolver.reject(LinkPreviewError.assertionFailure)
return return
} }
guard data.count > 0 else { guard data.count > 0 else {
Logger.warn("Empty data: \(type(of: value)).")
resolver.reject(LinkPreviewError.invalidContent) resolver.reject(LinkPreviewError.invalidContent)
return return
} }
resolver.fulfill(data) resolver.fulfill(data)
}, },
failure: { _, error in failure: { _, error in
Logger.verbose("Error: \(error)")
guard isRetryable(error: error) else { guard isRetryable(error: error) else {
Logger.warn("Error is not retryable.")
resolver.reject(LinkPreviewError.couldNotDownload) resolver.reject(LinkPreviewError.couldNotDownload)
return return
} }
guard remainingRetries > 0 else { guard remainingRetries > 0 else {
Logger.warn("No more retries.")
resolver.reject(LinkPreviewError.couldNotDownload) resolver.reject(LinkPreviewError.couldNotDownload)
return return
} }
@ -700,16 +655,11 @@ public class OWSLinkPreview: MTLModel {
} }
private class func downloadImage(url urlString: String, imageMimeType: String) -> Promise<Data> { private class func downloadImage(url urlString: String, imageMimeType: String) -> Promise<Data> {
Logger.verbose("url: \(urlString)")
guard let url = URL(string: urlString) else { guard let url = URL(string: urlString) else {
Logger.error("Could not parse URL.")
return Promise(error: LinkPreviewError.invalidInput) return Promise(error: LinkPreviewError.invalidInput)
} }
guard let assetDescription = ProxiedContentAssetDescription(url: url as NSURL) else { guard let assetDescription = ProxiedContentAssetDescription(url: url as NSURL) else {
Logger.error("Could not create asset description.")
return Promise(error: LinkPreviewError.invalidInput) return Promise(error: LinkPreviewError.invalidInput)
} }
let (promise, resolver) = Promise<ProxiedContentAsset>.pending() let (promise, resolver) = Promise<ProxiedContentAsset>.pending()
@ -719,7 +669,6 @@ public class OWSLinkPreview: MTLModel {
success: { (_, asset) in success: { (_, asset) in
resolver.fulfill(asset) resolver.fulfill(asset)
}, failure: { (_) in }, failure: { (_) in
Logger.warn("Error downloading asset")
resolver.reject(LinkPreviewError.couldNotDownload) resolver.reject(LinkPreviewError.couldNotDownload)
}) })
} }
@ -727,13 +676,11 @@ public class OWSLinkPreview: MTLModel {
do { do {
let imageSize = NSData.imageSize(forFilePath: asset.filePath, mimeType: imageMimeType) let imageSize = NSData.imageSize(forFilePath: asset.filePath, mimeType: imageMimeType)
guard imageSize.width > 0, imageSize.height > 0 else { guard imageSize.width > 0, imageSize.height > 0 else {
Logger.error("Link preview is invalid or has invalid size.")
return Promise(error: LinkPreviewError.invalidContent) return Promise(error: LinkPreviewError.invalidContent)
} }
let data = try Data(contentsOf: URL(fileURLWithPath: asset.filePath)) let data = try Data(contentsOf: URL(fileURLWithPath: asset.filePath))
guard let srcImage = UIImage(data: data) else { guard let srcImage = UIImage(data: data) else {
Logger.error("Could not parse image.")
return Promise(error: LinkPreviewError.invalidContent) return Promise(error: LinkPreviewError.invalidContent)
} }
@ -744,23 +691,19 @@ public class OWSLinkPreview: MTLModel {
let shouldResize = imageSize.width > maxImageSize || imageSize.height > maxImageSize let shouldResize = imageSize.width > maxImageSize || imageSize.height > maxImageSize
guard shouldResize else { guard shouldResize else {
guard let dstData = srcImage.jpegData(compressionQuality: 0.8) else { guard let dstData = srcImage.jpegData(compressionQuality: 0.8) else {
Logger.error("Could not write resized image.")
return Promise(error: LinkPreviewError.invalidContent) return Promise(error: LinkPreviewError.invalidContent)
} }
return Promise.value(dstData) return Promise.value(dstData)
} }
guard let dstImage = srcImage.resized(withMaxDimensionPoints: maxImageSize) else { guard let dstImage = srcImage.resized(withMaxDimensionPoints: maxImageSize) else {
Logger.error("Could not resize image.")
return Promise(error: LinkPreviewError.invalidContent) return Promise(error: LinkPreviewError.invalidContent)
} }
guard let dstData = dstImage.jpegData(compressionQuality: 0.8) else { guard let dstData = dstImage.jpegData(compressionQuality: 0.8) else {
Logger.error("Could not write resized image.")
return Promise(error: LinkPreviewError.invalidContent) return Promise(error: LinkPreviewError.invalidContent)
} }
return Promise.value(dstData) return Promise.value(dstData)
} catch { } catch {
owsFailDebug("Could not load asset data: \(type(of: asset.filePath)).")
return Promise(error: LinkPreviewError.assertionFailure) return Promise(error: LinkPreviewError.assertionFailure)
} }
} }
@ -786,15 +729,12 @@ public class OWSLinkPreview: MTLModel {
} }
guard isValidMediaUrl(imageUrl) else { guard isValidMediaUrl(imageUrl) else {
Logger.error("Invalid image URL.")
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title)) return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
} }
guard let imageFileExtension = fileExtension(forImageUrl: imageUrl) else { guard let imageFileExtension = fileExtension(forImageUrl: imageUrl) else {
Logger.error("Image URL has unknown or invalid file extension: \(imageUrl).")
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title)) return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
} }
guard let imageMimeType = mimetype(forImageFileExtension: imageFileExtension) else { guard let imageMimeType = mimetype(forImageFileExtension: imageFileExtension) else {
Logger.error("Image URL has unknown or invalid content type: \(imageUrl).")
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title)) return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
} }
@ -808,7 +748,6 @@ public class OWSLinkPreview: MTLModel {
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title)) return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
} }
} catch { } catch {
owsFailDebug("Could not parse link data: \(error).")
return Promise(error: error) return Promise(error: error)
} }
} }
@ -819,7 +758,6 @@ public class OWSLinkPreview: MTLModel {
// <meta property="og:image" content="https://i.ytimg.com/vi/tP-Ipsat90c/maxresdefault.jpg"> // <meta property="og:image" content="https://i.ytimg.com/vi/tP-Ipsat90c/maxresdefault.jpg">
class func parse(linkData: Data) throws -> OWSLinkPreviewContents { class func parse(linkData: Data) throws -> OWSLinkPreviewContents {
guard let linkText = String(bytes: linkData, encoding: .utf8) else { guard let linkText = String(bytes: linkData, encoding: .utf8) else {
owsFailDebug("Could not parse link text.")
throw LinkPreviewError.invalidInput throw LinkPreviewError.invalidInput
} }
@ -835,8 +773,6 @@ public class OWSLinkPreview: MTLModel {
} }
} }
Logger.verbose("title: \(String(describing: title))")
guard let rawImageUrlString = NSRegularExpression.parseFirstMatch(pattern: "<meta\\s+property\\s*=\\s*\"og:image\"\\s+[^>]*content\\s*=\\s*\"(.*?)\"[^>]*/?>", text: linkText) else { guard let rawImageUrlString = NSRegularExpression.parseFirstMatch(pattern: "<meta\\s+property\\s*=\\s*\"og:image\"\\s+[^>]*content\\s*=\\s*\"(.*?)\"[^>]*/?>", text: linkText) else {
return OWSLinkPreviewContents(title: title) return OWSLinkPreviewContents(title: title)
} }
@ -849,7 +785,6 @@ public class OWSLinkPreview: MTLModel {
class func fileExtension(forImageUrl urlString: String) -> String? { class func fileExtension(forImageUrl urlString: String) -> String? {
guard let imageUrl = URL(string: urlString) else { guard let imageUrl = URL(string: urlString) else {
Logger.error("Could not parse image URL.")
return nil return nil
} }
let imageFilename = imageUrl.lastPathComponent let imageFilename = imageUrl.lastPathComponent
@ -874,7 +809,6 @@ public class OWSLinkPreview: MTLModel {
return nil return nil
} }
guard let imageMimeType = MIMETypeUtil.mimeType(forFileExtension: imageFileExtension) else { guard let imageMimeType = MIMETypeUtil.mimeType(forFileExtension: imageFileExtension) else {
Logger.error("Image URL has unknown content type: \(imageFileExtension).")
return nil return nil
} }
let kValidMimeTypes = [ let kValidMimeTypes = [
@ -883,7 +817,6 @@ public class OWSLinkPreview: MTLModel {
OWSMimeTypeImageGif, OWSMimeTypeImageGif,
] ]
guard kValidMimeTypes.contains(imageMimeType) else { guard kValidMimeTypes.contains(imageMimeType) else {
Logger.error("Image URL has invalid content type: \(imageMimeType).")
return nil return nil
} }
return imageMimeType return imageMimeType

View File

@ -1,37 +1,35 @@
import SessionMessagingKit import SessionProtocolKit
import SignalCoreKit
public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiverDelegate { extension MessageReceiver {
public static let shared = MessageReceiverDelegate() internal static func isBlocked(_ publicKey: String) -> Bool {
// MARK: - Blocking
public func isBlocked(_ publicKey: String) -> Bool {
return SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(publicKey) return SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(publicKey)
} }
internal static func handle(_ message: Message, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
switch message {
// MARK: - Profiles case let message as ReadReceipt: handleReadReceipt(message, using: transaction)
case let message as TypingIndicator: handleTypingIndicator(message, using: transaction)
public func updateProfile(for publicKey: String, from profile: VisibleMessage.Profile, using transaction: Any) { case let message as ClosedGroupUpdate: handleClosedGroupUpdate(message, using: transaction)
let transaction = transaction as! YapDatabaseReadWriteTransaction case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction)
let profileManager = SSKEnvironment.shared.profileManager case let message as VisibleMessage: try handleVisibleMessage(message, associatedWithProto: proto, using: transaction)
if let displayName = profile.displayName { default: fatalError()
profileManager.updateProfileForContact(withID: publicKey, displayName: displayName, with: transaction)
}
if let profileKey = profile.profileKey, let profilePictureURL = profile.profilePictureURL, profileKey.count == kAES256_KeyByteLength {
profileManager.setProfileKeyData(profileKey, forRecipientId: publicKey, avatarURL: profilePictureURL)
} }
} }
private static func handleReadReceipt(_ message: ReadReceipt, using transaction: Any) {
SSKEnvironment.shared.readReceiptManager.processReadReceipts(fromRecipientId: message.sender!, sentTimestamps: message.timestamps!.map { NSNumber(value: $0) }, readTimestamp: message.receivedTimestamp!)
}
private static func handleTypingIndicator(_ message: TypingIndicator, using transaction: Any) {
switch message.kind! {
case .started: showTypingIndicatorIfNeeded(for: message.sender!)
case .stopped: hideTypingIndicatorIfNeeded(for: message.sender!)
}
}
// MARK: - Typing Indicators public static func showTypingIndicatorIfNeeded(for senderPublicKey: String) {
public func showTypingIndicatorIfNeeded(for senderPublicKey: String) {
var threadOrNil: TSContactThread? var threadOrNil: TSContactThread?
Storage.read { transaction in Storage.read { transaction in
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction) threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
@ -49,7 +47,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
} }
} }
public func hideTypingIndicatorIfNeeded(for senderPublicKey: String) { public static func hideTypingIndicatorIfNeeded(for senderPublicKey: String) {
var threadOrNil: TSContactThread? var threadOrNil: TSContactThread?
Storage.read { transaction in Storage.read { transaction in
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction) threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
@ -67,7 +65,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
} }
} }
public func cancelTypingIndicatorsIfNeeded(for senderPublicKey: String) { public static func cancelTypingIndicatorsIfNeeded(for senderPublicKey: String) {
var threadOrNil: TSContactThread? var threadOrNil: TSContactThread?
Storage.read { transaction in Storage.read { transaction in
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction) threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
@ -85,30 +83,15 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
} }
} }
private static func handleExpirationTimerUpdate(_ message: ExpirationTimerUpdate, using transaction: Any) {
if message.duration! > 0 {
// MARK: - Notifications setExpirationTimer(to: message.duration!, for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction)
} else {
public func notifyUserIfNeeded(forMessageWithID messageID: String, threadID: String) { disableExpirationTimer(for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction)
guard let message = TSIncomingMessage.fetch(uniqueId: messageID), let thread = TSThread.fetch(uniqueId: threadID) else { return }
Storage.read { transaction in
SSKEnvironment.shared.notificationsManager!.notifyUser(for: message, in: thread, transaction: transaction)
} }
} }
public static func setExpirationTimer(to duration: UInt32, for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) {
// MARK: - Read Receipts
public func markMessagesAsRead(_ timestamps: [UInt64], from senderPublicKey: String, at timestamp: UInt64) {
SSKEnvironment.shared.readReceiptManager.processReadReceipts(fromRecipientId: senderPublicKey, sentTimestamps: timestamps.map { NSNumber(value: $0) }, readTimestamp: timestamp)
}
// MARK: - Expiration
public func setExpirationTimer(to duration: UInt32, for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) {
let transaction = transaction as! YapDatabaseReadWriteTransaction let transaction = transaction as! YapDatabaseReadWriteTransaction
var threadOrNil: TSThread? var threadOrNil: TSThread?
Storage.read { transaction in Storage.read { transaction in
@ -130,7 +113,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary() SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary()
} }
public func disableExpirationTimer(for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) { public static func disableExpirationTimer(for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) {
let transaction = transaction as! YapDatabaseReadWriteTransaction let transaction = transaction as! YapDatabaseReadWriteTransaction
var threadOrNil: TSThread? var threadOrNil: TSThread?
Storage.read { transaction in Storage.read { transaction in
@ -152,11 +135,59 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary() SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary()
} }
private static func handleVisibleMessage(_ message: VisibleMessage, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
let storage = Configuration.shared.storage
let transaction = transaction as! YapDatabaseReadWriteTransaction
// Parse & persist attachments
let attachments: [VisibleMessage.Attachment] = proto.dataMessage!.attachments.compactMap { proto in
guard let attachment = VisibleMessage.Attachment.fromProto(proto) else { return nil }
return attachment.isValid ? attachment : nil
}
let attachmentIDs = storage.persist(attachments, using: transaction)
message.attachmentIDs = attachmentIDs
// Update profile if needed
if let profile = message.profile {
let profileManager = SSKEnvironment.shared.profileManager
if let displayName = profile.displayName {
profileManager.updateProfileForContact(withID: message.sender!, displayName: displayName, with: transaction)
}
if let profileKey = profile.profileKey, let profilePictureURL = profile.profilePictureURL, profileKey.count == kAES256_KeyByteLength {
profileManager.setProfileKeyData(profileKey, forRecipientId: message.sender!, avatarURL: profilePictureURL)
}
}
// Persist the message
guard let (threadID, tsIncomingMessageID) = storage.persist(message, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread }
message.threadID = threadID
// Start attachment downloads if needed
storage.withAsync({ transaction in
attachmentIDs.forEach { attachmentID in
let downloadJob = AttachmentDownloadJob(attachmentID: attachmentID, tsIncomingMessageID: tsIncomingMessageID)
if CurrentAppContext().isMainAppAndActive {
JobQueue.shared.add(downloadJob, using: transaction)
} else {
JobQueue.shared.addWithoutExecuting(downloadJob, using: transaction)
}
}
}, completion: { })
// Cancel any typing indicators
cancelTypingIndicatorsIfNeeded(for: message.sender!)
// Notify the user if needed
guard let tsIncomingMessage = TSIncomingMessage.fetch(uniqueId: tsIncomingMessageID), let thread = TSThread.fetch(uniqueId: threadID) else { return }
Storage.read { transaction in
SSKEnvironment.shared.notificationsManager!.notifyUser(for: tsIncomingMessage, in: thread, transaction: transaction)
}
}
private static func handleClosedGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) {
switch message.kind! {
case .new: handleNewGroup(message, using: transaction)
case .info: handleGroupUpdate(message, using: transaction)
case .senderKeyRequest: handleSenderKeyRequest(message, using: transaction)
case .senderKey: handleSenderKey(message, using: transaction)
}
}
// MARK: - Closed Groups private static func handleNewGroup(_ message: ClosedGroupUpdate, using transaction: Any) {
public func handleNewGroup(_ message: ClosedGroupUpdate, using transaction: Any) {
guard case let .new(groupPublicKeyAsData, name, groupPrivateKey, senderKeys, membersAsData, adminsAsData) = message.kind else { return } guard case let .new(groupPublicKeyAsData, name, groupPrivateKey, senderKeys, membersAsData, adminsAsData) = message.kind else { return }
let transaction = transaction as! YapDatabaseReadWriteTransaction let transaction = transaction as! YapDatabaseReadWriteTransaction
let groupPublicKey = groupPublicKeyAsData.toHexString() let groupPublicKey = groupPublicKeyAsData.toHexString()
@ -185,7 +216,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
} }
} }
missingSenderKeys.subtracting([ userPublicKey ]).forEach { publicKey in missingSenderKeys.subtracting([ userPublicKey ]).forEach { publicKey in
MessageSenderDelegate.shared.requestSenderKey(for: groupPublicKey, senderPublicKey: publicKey, using: transaction) MessageSender.shared.requestSenderKey(for: groupPublicKey, senderPublicKey: publicKey, using: transaction)
} }
// Create the group // Create the group
let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey) let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey)
@ -208,7 +239,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
infoMessage.save(with: transaction) infoMessage.save(with: transaction)
} }
public func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) { private static func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) {
guard case let .info(groupPublicKeyAsData, name, senderKeys, membersAsData, adminsAsData) = message.kind else { return } guard case let .info(groupPublicKeyAsData, name, senderKeys, membersAsData, adminsAsData) = message.kind else { return }
let transaction = transaction as! YapDatabaseReadWriteTransaction let transaction = transaction as! YapDatabaseReadWriteTransaction
let groupPublicKey = groupPublicKeyAsData.toHexString() let groupPublicKey = groupPublicKeyAsData.toHexString()
@ -272,7 +303,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
} }
} }
public func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any) { private static func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any) {
guard case let .senderKeyRequest(groupPublicKeyAsData) = message.kind else { return } guard case let .senderKeyRequest(groupPublicKeyAsData) = message.kind else { return }
let transaction = transaction as! YapDatabaseReadWriteTransaction let transaction = transaction as! YapDatabaseReadWriteTransaction
let userPublicKey = getUserHexEncodedPublicKey() let userPublicKey = getUserHexEncodedPublicKey()
@ -300,7 +331,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
MessageSender.send(closedGroupUpdate, in: thread, using: transaction) MessageSender.send(closedGroupUpdate, in: thread, using: transaction)
} }
public func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any) { private static func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any) {
guard case let .senderKey(groupPublicKeyAsData, senderKey) = message.kind else { return } guard case let .senderKey(groupPublicKeyAsData, senderKey) = message.kind else { return }
let groupPublicKey = groupPublicKeyAsData.toHexString() let groupPublicKey = groupPublicKeyAsData.toHexString()
guard senderKey.publicKey.toHexString() == message.sender! else { guard senderKey.publicKey.toHexString() == message.sender! else {

View File

@ -2,7 +2,6 @@ import SessionUtilitiesKit
internal enum MessageReceiver { internal enum MessageReceiver {
// MARK: Error
internal enum Error : LocalizedError { internal enum Error : LocalizedError {
case invalidMessage case invalidMessage
case unknownMessage case unknownMessage
@ -42,7 +41,6 @@ internal enum MessageReceiver {
} }
} }
// MARK: Parsing
internal static func parse(_ data: Data, messageServerID: UInt64?, using transaction: Any) throws -> (Message, SNProtoContent) { internal static func parse(_ data: Data, messageServerID: UInt64?, using transaction: Any) throws -> (Message, SNProtoContent) {
let userPublicKey = Configuration.shared.storage.getUserPublicKey() let userPublicKey = Configuration.shared.storage.getUserPublicKey()
// Parse the envelope // Parse the envelope
@ -59,7 +57,7 @@ internal enum MessageReceiver {
default: throw Error.unknownEnvelopeType default: throw Error.unknownEnvelopeType
} }
// Don't process the envelope any further if the sender is blocked // Don't process the envelope any further if the sender is blocked
guard !Configuration.shared.messageReceiverDelegate.isBlocked(sender) else { throw Error.senderBlocked } guard !isBlocked(sender) else { throw Error.senderBlocked }
// Ignore self sends // Ignore self sends
guard sender != userPublicKey else { throw Error.selfSend } guard sender != userPublicKey else { throw Error.selfSend }
// Parse the proto // Parse the proto
@ -92,81 +90,4 @@ internal enum MessageReceiver {
throw Error.unknownMessage throw Error.unknownMessage
} }
} }
// MARK: Handling
internal static func handle(_ message: Message, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
switch message {
case let message as ReadReceipt: handleReadReceipt(message, using: transaction)
case let message as TypingIndicator: handleTypingIndicator(message, using: transaction)
case let message as ClosedGroupUpdate: handleClosedGroupUpdate(message, using: transaction)
case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction)
case let message as VisibleMessage: try handleVisibleMessage(message, associatedWithProto: proto, using: transaction)
default: fatalError()
}
}
private static func handleReadReceipt(_ message: ReadReceipt, using transaction: Any) {
Configuration.shared.messageReceiverDelegate.markMessagesAsRead(message.timestamps!, from: message.sender!, at: message.receivedTimestamp!)
}
private static func handleTypingIndicator(_ message: TypingIndicator, using transaction: Any) {
let delegate = Configuration.shared.messageReceiverDelegate
switch message.kind! {
case .started: delegate.showTypingIndicatorIfNeeded(for: message.sender!)
case .stopped: delegate.hideTypingIndicatorIfNeeded(for: message.sender!)
}
}
private static func handleClosedGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) {
let delegate = Configuration.shared.messageReceiverDelegate
switch message.kind! {
case .new: delegate.handleNewGroup(message, using: transaction)
case .info: delegate.handleGroupUpdate(message, using: transaction)
case .senderKeyRequest: delegate.handleSenderKeyRequest(message, using: transaction)
case .senderKey: delegate.handleSenderKey(message, using: transaction)
}
}
private static func handleExpirationTimerUpdate(_ message: ExpirationTimerUpdate, using transaction: Any) {
let delegate = Configuration.shared.messageReceiverDelegate
if message.duration! > 0 {
delegate.setExpirationTimer(to: message.duration!, for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction)
} else {
delegate.disableExpirationTimer(for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction)
}
}
private static func handleVisibleMessage(_ message: VisibleMessage, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
let delegate = Configuration.shared.messageReceiverDelegate
let storage = Configuration.shared.storage
// Parse & persist attachments
let attachments: [VisibleMessage.Attachment] = proto.dataMessage!.attachments.compactMap { proto in
guard let attachment = VisibleMessage.Attachment.fromProto(proto) else { return nil }
return attachment.isValid ? attachment : nil
}
let attachmentIDs = storage.persist(attachments, using: transaction)
message.attachmentIDs = attachmentIDs
// Update profile if needed
if let profile = message.profile {
delegate.updateProfile(for: message.sender!, from: profile, using: transaction)
}
// Persist the message
guard let (threadID, tsIncomingMessageID) = storage.persist(message, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread }
message.threadID = threadID
// Start attachment downloads if needed
storage.withAsync({ transaction in
attachmentIDs.forEach { attachmentID in
let downloadJob = AttachmentDownloadJob(attachmentID: attachmentID, tsIncomingMessageID: tsIncomingMessageID)
if CurrentAppContext().isMainAppAndActive {
JobQueue.shared.add(downloadJob, using: transaction)
} else {
JobQueue.shared.addWithoutExecuting(downloadJob, using: transaction)
}
}
}, completion: { })
// Cancel any typing indicators
delegate.cancelTypingIndicatorsIfNeeded(for: message.sender!)
// Notify the user if needed
delegate.notifyUserIfNeeded(forMessageWithID: tsIncomingMessageID, threadID: threadID)
}
} }

View File

@ -1,17 +0,0 @@
public protocol MessageReceiverDelegate {
func isBlocked(_ publicKey: String) -> Bool
func updateProfile(for publicKey: String, from profile: VisibleMessage.Profile, using transaction: Any)
func showTypingIndicatorIfNeeded(for senderPublicKey: String)
func hideTypingIndicatorIfNeeded(for senderPublicKey: String)
func cancelTypingIndicatorsIfNeeded(for senderPublicKey: String)
func notifyUserIfNeeded(forMessageWithID messageID: String, threadID: String)
func markMessagesAsRead(_ timestamps: [UInt64], from senderPublicKey: String, at timestamp: UInt64)
func setExpirationTimer(to duration: UInt32, for senderPublicKey: String, groupPublicKey: String?, using transaction: Any)
func disableExpirationTimer(for senderPublicKey: String, groupPublicKey: String?, using transaction: Any)
func handleNewGroup(_ message: ClosedGroupUpdate, using transaction: Any)
func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any)
func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any)
func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any)
}

View File

@ -11,10 +11,14 @@ public final class MessageSender : NSObject {
case protoConversionFailed case protoConversionFailed
case proofOfWorkCalculationFailed case proofOfWorkCalculationFailed
case noUserPublicKey case noUserPublicKey
// Closed groups
case noThread
case noPrivateKey
case invalidClosedGroupUpdate
internal var isRetryable: Bool { internal var isRetryable: Bool {
switch self { switch self {
case .invalidMessage, .protoConversionFailed, .proofOfWorkCalculationFailed: return false case .invalidMessage, .protoConversionFailed, .proofOfWorkCalculationFailed, .invalidClosedGroupUpdate: return false
default: return true default: return true
} }
} }
@ -25,6 +29,10 @@ public final class MessageSender : NSObject {
case .protoConversionFailed: return "Couldn't convert message to proto." case .protoConversionFailed: return "Couldn't convert message to proto."
case .proofOfWorkCalculationFailed: return "Proof of work calculation failed." case .proofOfWorkCalculationFailed: return "Proof of work calculation failed."
case .noUserPublicKey: return "Couldn't find user key pair." case .noUserPublicKey: return "Couldn't find user key pair."
// Closed groups
case .noThread: return "Couldn't find a thread associated with the given group public key."
case .noPrivateKey: return "Couldn't find a private key associated with the given group public key."
case .invalidClosedGroupUpdate: return "Invalid group update."
} }
} }
} }
@ -32,6 +40,8 @@ public final class MessageSender : NSObject {
// MARK: Initialization // MARK: Initialization
private override init() { } private override init() { }
public static let shared = MessageSender() // FIXME: Remove once requestSenderKey is static
// MARK: Convenience // MARK: Convenience
public static func send(_ message: Message, to destination: Message.Destination, using transaction: Any) -> Promise<Void> { public static func send(_ message: Message, to destination: Message.Destination, using transaction: Any) -> Promise<Void> {
switch destination { switch destination {
@ -56,7 +66,7 @@ public final class MessageSender : NSObject {
// Set the failure handler (for precondition failure handling) // Set the failure handler (for precondition failure handling)
let _ = promise.catch(on: DispatchQueue.main) { error in let _ = promise.catch(on: DispatchQueue.main) { error in
storage.withAsync({ transaction in storage.withAsync({ transaction in
Configuration.shared.messageSenderDelegate.handleFailedMessageSend(message, with: error, using: transaction) MessageSender.handleFailedMessageSend(message, with: error, using: transaction)
}, completion: { }) }, completion: { })
if case .contact(_) = destination { if case .contact(_) = destination {
NotificationCenter.default.post(name: .messageSendingFailed, object: NSNumber(value: message.sentTimestamp!)) NotificationCenter.default.post(name: .messageSendingFailed, object: NSNumber(value: message.sentTimestamp!))
@ -157,7 +167,7 @@ public final class MessageSender : NSObject {
// Handle completion // Handle completion
let _ = promise.done(on: DispatchQueue.main) { let _ = promise.done(on: DispatchQueue.main) {
storage.withAsync({ transaction in storage.withAsync({ transaction in
Configuration.shared.messageSenderDelegate.handleSuccessfulMessageSend(message, using: transaction) MessageSender.handleSuccessfulMessageSend(message, using: transaction)
}, completion: { }) }, completion: { })
if case .contact(_) = destination { if case .contact(_) = destination {
NotificationCenter.default.post(name: .messageSent, object: NSNumber(value: message.sentTimestamp!)) NotificationCenter.default.post(name: .messageSent, object: NSNumber(value: message.sentTimestamp!))
@ -186,7 +196,7 @@ public final class MessageSender : NSObject {
// Set the failure handler (for precondition failure handling) // Set the failure handler (for precondition failure handling)
let _ = promise.catch(on: DispatchQueue.global(qos: .userInitiated)) { error in let _ = promise.catch(on: DispatchQueue.global(qos: .userInitiated)) { error in
storage.withAsync({ transaction in storage.withAsync({ transaction in
Configuration.shared.messageSenderDelegate.handleFailedMessageSend(message, with: error, using: transaction) MessageSender.handleFailedMessageSend(message, with: error, using: transaction)
}, completion: { }) }, completion: { })
} }
// Validate the message // Validate the message
@ -210,10 +220,23 @@ public final class MessageSender : NSObject {
// Handle completion // Handle completion
let _ = promise.done(on: DispatchQueue.global(qos: .userInitiated)) { let _ = promise.done(on: DispatchQueue.global(qos: .userInitiated)) {
storage.withAsync({ transaction in storage.withAsync({ transaction in
Configuration.shared.messageSenderDelegate.handleSuccessfulMessageSend(message, using: transaction) MessageSender.handleSuccessfulMessageSend(message, using: transaction)
}, completion: { }) }, completion: { })
} }
// Return // Return
return promise return promise
} }
// MARK: Result Handling
public static func handleSuccessfulMessageSend(_ message: Message, using transaction: Any) {
guard let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) else { return }
tsMessage.openGroupServerMessageID = message.openGroupServerMessageID ?? 0
tsMessage.isOpenGroupMessage = tsMessage.openGroupServerMessageID != 0
tsMessage.update(withSentRecipient: message.recipient!, wasSentByUD: true, transaction: transaction as! YapDatabaseReadWriteTransaction)
}
public static func handleFailedMessageSend(_ message: Message, with error: Swift.Error, using transaction: Any) {
guard let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) else { return }
tsMessage.update(sendingError: error, transaction: transaction as! YapDatabaseReadWriteTransaction)
}
} }

View File

@ -1,6 +0,0 @@
public protocol MessageSenderDelegate {
func handleSuccessfulMessageSend(_ message: Message, using transaction: Any)
func handleFailedMessageSend(_ message: Message, with error: Error, using transaction: Any)
}

View File

@ -1,3 +1,4 @@
import SessionSnodeKit
import PromiseKit import PromiseKit
@objc(LKPushNotificationAPI) @objc(LKPushNotificationAPI)

View File

@ -1,3 +1,4 @@
import SessionSnodeKit
import PromiseKit import PromiseKit
@objc(LKClosedGroupPoller) @objc(LKClosedGroupPoller)
@ -23,7 +24,9 @@ public final class ClosedGroupPoller : NSObject {
// MARK: Public API // MARK: Public API
@objc public func startIfNeeded() { @objc public func startIfNeeded() {
AssertIsOnMainThread() // Timers don't do well on background queues #if DEBUG
assert(Thread.current.isMainThread) // Timers don't do well on background queues
#endif
guard !isPolling else { return } guard !isPolling else { return }
isPolling = true isPolling = true
timer = Timer.scheduledTimer(withTimeInterval: ClosedGroupPoller.pollInterval, repeats: true) { [weak self] _ in timer = Timer.scheduledTimer(withTimeInterval: ClosedGroupPoller.pollInterval, repeats: true) { [weak self] _ in

View File

@ -162,10 +162,10 @@ public final class OpenGroupPoller : NSObject {
private func pollForDeletedMessages() { private func pollForDeletedMessages() {
let openGroup = self.openGroup let openGroup = self.openGroup
let _ = OpenGroupAPI.getDeletedMessageServerIDs(for: openGroup.channel, on: openGroup.server).done(on: DispatchQueue.global(qos: .default)) { deletedMessageServerIDs in let _ = OpenGroupAPI.getDeletedMessageServerIDs(for: openGroup.channel, on: openGroup.server).done(on: DispatchQueue.global(qos: .default)) { deletedMessageServerIDs in
let deletedMessageIDs = deletedMessageServerIDs.compactMap { Storage.shared.getIDForMessage(withServerID: UInt64($0)) }
Storage.writeSync { transaction in Storage.writeSync { transaction in
let deletedMessageIDs = deletedMessageServerIDs.compactMap { OWSPrimaryStorage.shared().getIDForMessage(withServerID: UInt($0), in: transaction) }
deletedMessageIDs.forEach { messageID in deletedMessageIDs.forEach { messageID in
TSMessage.fetch(uniqueId: messageID)?.remove(with: transaction) TSMessage.fetch(uniqueId: String(messageID))?.remove(with: transaction)
} }
} }
} }

View File

@ -1,3 +1,4 @@
import SessionSnodeKit
import PromiseKit import PromiseKit
@objc(LKPoller) @objc(LKPoller)

View File

@ -0,0 +1,13 @@
extension VisibleMessage.Quote {
@objc(from:)
public static func from(_ quote: OWSQuotedReplyModel?) -> VisibleMessage.Quote? {
guard let quote = quote else { return nil }
let result = VisibleMessage.Quote()
result.timestamp = quote.timestamp
result.publicKey = quote.authorId
result.text = quote.body
return result
}
}

View File

@ -2,7 +2,8 @@
// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import <SignalUtilitiesKit/TSQuotedMessage.h> #import <UIKit/UIKit.h>
#import <SessionMessagingKit/TSQuotedMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View File

@ -4,16 +4,15 @@
#import "OWSQuotedReplyModel.h" #import "OWSQuotedReplyModel.h"
#import "ConversationViewItem.h" #import "ConversationViewItem.h"
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <SessionUtilitiesKit/MIMETypeUtil.h> #import <SessionUtilitiesKit/MIMETypeUtil.h>
#import <SignalUtilitiesKit/TSAccountManager.h> #import <SessionMessagingKit/TSAccountManager.h>
#import <SessionMessagingKit/TSAttachmentPointer.h> #import <SessionMessagingKit/TSAttachmentPointer.h>
#import <SessionMessagingKit/TSAttachmentStream.h> #import <SessionMessagingKit/TSAttachmentStream.h>
#import <SignalUtilitiesKit/TSIncomingMessage.h> #import <SessionMessagingKit/TSIncomingMessage.h>
#import <SignalUtilitiesKit/TSMessage.h> #import <SessionMessagingKit/TSMessage.h>
#import <SignalUtilitiesKit/TSOutgoingMessage.h> #import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SignalUtilitiesKit/TSQuotedMessage.h> #import <SessionMessagingKit/TSQuotedMessage.h>
#import <SignalUtilitiesKit/TSThread.h> #import <SessionMessagingKit/TSThread.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -78,7 +77,6 @@ NS_ASSUME_NONNULL_BEGIN
threadId:(NSString *)threadId threadId:(NSString *)threadId
transaction:(YapDatabaseReadTransaction *)transaction transaction:(YapDatabaseReadTransaction *)transaction
{ {
OWSAssertDebug(quotedMessage.quotedAttachments.count <= 1);
OWSAttachmentInfo *attachmentInfo = quotedMessage.quotedAttachments.firstObject; OWSAttachmentInfo *attachmentInfo = quotedMessage.quotedAttachments.firstObject;
BOOL thumbnailDownloadFailed = NO; BOOL thumbnailDownloadFailed = NO;
@ -123,17 +121,12 @@ NS_ASSUME_NONNULL_BEGIN
threadId:(NSString *)threadId threadId:(NSString *)threadId
transaction:(YapDatabaseReadTransaction *)transaction; transaction:(YapDatabaseReadTransaction *)transaction;
{ {
OWSAssertDebug(conversationItem);
OWSAssertDebug(transaction);
TSMessage *message = (TSMessage *)conversationItem.interaction; TSMessage *message = (TSMessage *)conversationItem.interaction;
if (![message isKindOfClass:[TSMessage class]]) { if (![message isKindOfClass:[TSMessage class]]) {
OWSFailDebug(@"unexpected reply message: %@", message);
return nil; return nil;
} }
TSThread *thread = [message threadWithTransaction:transaction]; TSThread *thread = [message threadWithTransaction:transaction];
OWSAssertDebug(thread);
uint64_t timestamp = message.timestamp; uint64_t timestamp = message.timestamp;
@ -143,11 +136,9 @@ NS_ASSUME_NONNULL_BEGIN
} else if ([message isKindOfClass:[TSIncomingMessage class]]) { } else if ([message isKindOfClass:[TSIncomingMessage class]]) {
return [(TSIncomingMessage *)message authorId]; return [(TSIncomingMessage *)message authorId];
} else { } else {
OWSFailDebug(@"Unexpected message type: %@", message.class);
return (NSString * _Nullable) nil; return (NSString * _Nullable) nil;
} }
}(); }();
OWSAssertDebug(authorId.length > 0);
NSString *_Nullable quotedText = message.body; NSString *_Nullable quotedText = message.body;
BOOL hasText = quotedText.length > 0; BOOL hasText = quotedText.length > 0;
@ -192,8 +183,6 @@ NS_ASSUME_NONNULL_BEGIN
} }
if ([truncatedText dataUsingEncoding:NSUTF8StringEncoding].length < kOversizeTextMessageSizeThreshold) { if ([truncatedText dataUsingEncoding:NSUTF8StringEncoding].length < kOversizeTextMessageSizeThreshold) {
quotedText = truncatedText; quotedText = truncatedText;
} else {
OWSFailDebug(@"Missing valid text snippet.");
} }
} }
} else { } else {
@ -209,7 +198,6 @@ NS_ASSUME_NONNULL_BEGIN
BOOL hasAttachment = quotedAttachment != nil; BOOL hasAttachment = quotedAttachment != nil;
if (!hasText && !hasAttachment) { if (!hasText && !hasAttachment) {
OWSFailDebug(@"quoted message has neither text nor attachment");
quotedText = @""; quotedText = @"";
hasText = YES; hasText = YES;
} }

View File

@ -1,17 +1,4 @@
extension VisibleMessage.Quote {
@objc(from:)
public static func from(_ quote: OWSQuotedReplyModel?) -> VisibleMessage.Quote? {
guard let quote = quote else { return nil }
let result = VisibleMessage.Quote()
result.timestamp = quote.timestamp
result.publicKey = quote.authorId
result.text = quote.body
return result
}
}
extension TSQuotedMessage { extension TSQuotedMessage {
@objc(from:) @objc(from:)

View File

@ -11,8 +11,8 @@
#import "TSInteraction.h" #import "TSInteraction.h"
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
#import "TSThread.h" #import "TSThread.h"
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <YapDatabase/YapDatabaseTransaction.h> #import <YapDatabase/YapDatabaseTransaction.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -20,10 +20,6 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithAttachmentStream:(TSAttachmentStream *)attachmentStream; - (instancetype)initWithAttachmentStream:(TSAttachmentStream *)attachmentStream;
{ {
OWSAssertDebug([attachmentStream isKindOfClass:[TSAttachmentStream class]]);
OWSAssertDebug(attachmentStream.uniqueId);
OWSAssertDebug(attachmentStream.contentType);
return [self initWithAttachmentId:attachmentStream.uniqueId return [self initWithAttachmentId:attachmentStream.uniqueId
contentType:attachmentStream.contentType contentType:attachmentStream.contentType
sourceFilename:attachmentStream.sourceFilename]; sourceFilename:attachmentStream.sourceFilename];
@ -62,9 +58,6 @@ NS_ASSUME_NONNULL_BEGIN
bodySource:(TSQuotedMessageContentSource)bodySource bodySource:(TSQuotedMessageContentSource)bodySource
receivedQuotedAttachmentInfos:(NSArray<OWSAttachmentInfo *> *)attachmentInfos receivedQuotedAttachmentInfos:(NSArray<OWSAttachmentInfo *> *)attachmentInfos
{ {
OWSAssertDebug(timestamp > 0);
OWSAssertDebug(authorId.length > 0);
self = [super init]; self = [super init];
if (!self) { if (!self) {
return nil; return nil;
@ -84,9 +77,6 @@ NS_ASSUME_NONNULL_BEGIN
body:(NSString *_Nullable)body body:(NSString *_Nullable)body
quotedAttachmentsForSending:(NSArray<TSAttachmentStream *> *)attachments quotedAttachmentsForSending:(NSArray<TSAttachmentStream *> *)attachments
{ {
OWSAssertDebug(timestamp > 0);
OWSAssertDebug(authorId.length > 0);
self = [super init]; self = [super init];
if (!self) { if (!self) {
return nil; return nil;
@ -110,8 +100,6 @@ NS_ASSUME_NONNULL_BEGIN
thread:(TSThread *)thread thread:(TSThread *)thread
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(dataMessage);
if (!dataMessage.quote) { if (!dataMessage.quote) {
return nil; return nil;
} }
@ -119,13 +107,11 @@ NS_ASSUME_NONNULL_BEGIN
SNProtoDataMessageQuote *quoteProto = [dataMessage quote]; SNProtoDataMessageQuote *quoteProto = [dataMessage quote];
if (quoteProto.id == 0) { if (quoteProto.id == 0) {
OWSFailDebug(@"quoted message missing id");
return nil; return nil;
} }
uint64_t timestamp = [quoteProto id]; uint64_t timestamp = [quoteProto id];
if (quoteProto.author.length == 0) { if (quoteProto.author.length == 0) {
OWSFailDebug(@"quoted message missing author");
return nil; return nil;
} }
// TODO: We could verify that this is a valid e164 value. // TODO: We could verify that this is a valid e164 value.
@ -173,18 +159,10 @@ NS_ASSUME_NONNULL_BEGIN
transaction:transaction]; transaction:transaction];
if (localThumbnail) { if (localThumbnail) {
OWSLogDebug(@"Generated local thumbnail for quoted quoted message: %@:%lu",
thread.uniqueId,
(unsigned long)timestamp);
[localThumbnail saveWithTransaction:transaction]; [localThumbnail saveWithTransaction:transaction];
attachmentInfo.thumbnailAttachmentStreamId = localThumbnail.uniqueId; attachmentInfo.thumbnailAttachmentStreamId = localThumbnail.uniqueId;
} else if (quotedAttachment.thumbnail) { } else if (quotedAttachment.thumbnail) {
OWSLogDebug(@"Saving reference for fetching remote thumbnail for quoted message: %@:%lu",
thread.uniqueId,
(unsigned long)timestamp);
SNProtoAttachmentPointer *thumbnailAttachmentProto = quotedAttachment.thumbnail; SNProtoAttachmentPointer *thumbnailAttachmentProto = quotedAttachment.thumbnail;
TSAttachmentPointer *_Nullable thumbnailPointer = TSAttachmentPointer *_Nullable thumbnailPointer =
[TSAttachmentPointer attachmentPointerFromProto:thumbnailAttachmentProto albumMessage:nil]; [TSAttachmentPointer attachmentPointerFromProto:thumbnailAttachmentProto albumMessage:nil];
@ -192,11 +170,7 @@ NS_ASSUME_NONNULL_BEGIN
[thumbnailPointer saveWithTransaction:transaction]; [thumbnailPointer saveWithTransaction:transaction];
attachmentInfo.thumbnailAttachmentPointerId = thumbnailPointer.uniqueId; attachmentInfo.thumbnailAttachmentPointerId = thumbnailPointer.uniqueId;
} else {
OWSFailDebug(@"Invalid thumbnail attachment.");
} }
} else {
OWSLogDebug(@"No thumbnail for quoted message: %@:%lu", thread.uniqueId, (unsigned long)timestamp);
} }
[attachmentInfos addObject:attachmentInfo]; [attachmentInfos addObject:attachmentInfo];
@ -251,18 +225,13 @@ NS_ASSUME_NONNULL_BEGIN
authorId:(NSString *)authorId authorId:(NSString *)authorId
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
if (timestamp <= 0) { if (timestamp <= 0) {
OWSFailDebug(@"Invalid timestamp: %llu", timestamp);
return nil; return nil;
} }
if (threadId.length <= 0) { if (threadId.length <= 0) {
OWSFailDebug(@"Invalid thread.");
return nil; return nil;
} }
if (authorId.length <= 0) { if (authorId.length <= 0) {
OWSFailDebug(@"Invalid authorId: %@", authorId);
return nil; return nil;
} }
@ -284,7 +253,6 @@ NS_ASSUME_NONNULL_BEGIN
return message; return message;
} }
OWSLogWarn(@"Could not find quoted message: %llu", timestamp);
return nil; return nil;
} }
@ -292,7 +260,6 @@ NS_ASSUME_NONNULL_BEGIN
- (nullable OWSAttachmentInfo *)firstAttachmentInfo - (nullable OWSAttachmentInfo *)firstAttachmentInfo
{ {
OWSAssertDebug(self.quotedAttachments.count <= 1);
return self.quotedAttachments.firstObject; return self.quotedAttachments.firstObject;
} }
@ -326,9 +293,6 @@ NS_ASSUME_NONNULL_BEGIN
- (void)setThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream - (void)setThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream
{ {
OWSAssertDebug([attachmentStream isKindOfClass:[TSAttachmentStream class]]);
OWSAssertDebug(self.quotedAttachments.count == 1);
OWSAttachmentInfo *firstAttachment = self.firstAttachmentInfo; OWSAttachmentInfo *firstAttachment = self.firstAttachmentInfo;
firstAttachment.thumbnailAttachmentStreamId = attachmentStream.uniqueId; firstAttachment.thumbnailAttachmentStreamId = attachmentStream.uniqueId;
} }
@ -352,8 +316,6 @@ NS_ASSUME_NONNULL_BEGIN
NSMutableArray<TSAttachmentStream *> *thumbnailAttachments = [NSMutableArray new]; NSMutableArray<TSAttachmentStream *> *thumbnailAttachments = [NSMutableArray new];
for (OWSAttachmentInfo *info in self.quotedAttachments) { for (OWSAttachmentInfo *info in self.quotedAttachments) {
OWSAssertDebug(info.attachmentId);
TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:info.attachmentId transaction:transaction]; TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:info.attachmentId transaction:transaction];
if (![attachment isKindOfClass:[TSAttachmentStream class]]) { if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
continue; continue;

View File

@ -3,16 +3,16 @@
// //
#import "OWSOutgoingReceiptManager.h" #import "OWSOutgoingReceiptManager.h"
#import "AppReadiness.h" #import <SessionMessagingKit/SessionMessagingKit-Swift.h>
#import "OWSError.h"
#import <PromiseKit/PromiseKit.h>
#import "OWSPrimaryStorage.h"
#import "SSKEnvironment.h" #import "SSKEnvironment.h"
#import "AppReadiness.h"
#import "OWSPrimaryStorage.h"
#import "TSContactThread.h" #import "TSContactThread.h"
#import "TSYapDatabaseObject.h" #import "TSYapDatabaseObject.h"
#import <PromiseKit/PromiseKit.h>
#import <YapDatabase/YapDatabase.h>
#import <Reachability/Reachability.h> #import <Reachability/Reachability.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SessionUtilitiesKit/SessionUtilitiesKit.h>
#import "SSKAsserts.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -41,8 +41,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
+ (instancetype)sharedManager + (instancetype)sharedManager
{ {
OWSAssert(SSKEnvironment.shared.outgoingReceiptManager);
return SSKEnvironment.shared.outgoingReceiptManager; return SSKEnvironment.shared.outgoingReceiptManager;
} }
@ -58,8 +56,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
_dbConnection = primaryStorage.newDatabaseConnection; _dbConnection = primaryStorage.newDatabaseConnection;
OWSSingletonAssert();
[[NSNotificationCenter defaultCenter] addObserver:self [[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(reachabilityChanged) selector:@selector(reachabilityChanged)
name:kReachabilityChangedNotification name:kReachabilityChangedNotification
@ -93,15 +89,11 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
// Schedules a processing pass, unless one is already scheduled. // Schedules a processing pass, unless one is already scheduled.
- (void)process { - (void)process {
OWSAssertDebug(AppReadiness.isAppReady);
dispatch_async(self.serialQueue, ^{ dispatch_async(self.serialQueue, ^{
if (self.isProcessing) { if (self.isProcessing) {
return; return;
} }
OWSLogVerbose(@"Processing outbound receipts.");
self.isProcessing = YES; self.isProcessing = YES;
if (!self.reachability.isReachable) { if (!self.reachability.isReachable) {
@ -159,7 +151,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
for (NSString *recipientId in queuedReceiptMap) { for (NSString *recipientId in queuedReceiptMap) {
NSSet<NSNumber *> *timestamps = queuedReceiptMap[recipientId]; NSSet<NSNumber *> *timestamps = queuedReceiptMap[recipientId];
if (timestamps.count < 1) { if (timestamps.count < 1) {
OWSFailDebug(@"Missing timestamps.");
continue; continue;
} }
@ -236,11 +227,9 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
NSString *collection = [self collectionForReceiptType:receiptType]; NSString *collection = [self collectionForReceiptType:receiptType];
if (recipientId.length < 1) { if (recipientId.length < 1) {
OWSFailDebug(@"Invalid recipient id.");
return; return;
} }
if (timestamp < 1) { if (timestamp < 1) {
OWSFailDebug(@"Invalid timestamp.");
return; return;
} }
dispatch_async(self.serialQueue, ^{ dispatch_async(self.serialQueue, ^{
@ -263,11 +252,9 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
NSString *collection = [self collectionForReceiptType:receiptType]; NSString *collection = [self collectionForReceiptType:receiptType];
if (recipientId.length < 1) { if (recipientId.length < 1) {
OWSFailDebug(@"Invalid recipient id.");
return; return;
} }
if (timestamps.count < 1) { if (timestamps.count < 1) {
OWSFailDebug(@"Invalid timestamps.");
return; return;
} }
dispatch_async(self.serialQueue, ^{ dispatch_async(self.serialQueue, ^{
@ -288,8 +275,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
- (void)reachabilityChanged - (void)reachabilityChanged
{ {
OWSAssertIsOnMainThread();
[self process]; [self process];
} }

View File

@ -51,15 +51,6 @@ extern NSString *const kIncomingMessageMarkedAsReadNotification;
- (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message - (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
#pragma mark - Linked Device Read Receipts
- (void)processReadReceiptsFromLinkedDevice:(NSArray<SNProtoSyncMessageRead *> *)readReceiptProtos
readTimestamp:(uint64_t)readTimestamp
transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)applyEarlyReadReceiptsForIncomingMessage:(TSIncomingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction;
#pragma mark - Locally Read #pragma mark - Locally Read
// This method cues this manager: // This method cues this manager:

View File

@ -10,13 +10,13 @@
#import "SSKEnvironment.h" #import "SSKEnvironment.h"
#import "TSAccountManager.h" #import "TSAccountManager.h"
#import "TSContactThread.h" #import "TSContactThread.h"
#import "TSOutgoingMessage.h"
#import "TSDatabaseView.h" #import "TSDatabaseView.h"
#import "TSIncomingMessage.h" #import "TSIncomingMessage.h"
#import "YapDatabaseConnection+OWS.h" #import "YapDatabaseConnection+OWS.h"
#import <SessionProtocolKit/SessionProtocolKit.h> #import <SessionProtocolKit/SessionProtocolKit.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h> #import <SessionUtilitiesKit/SessionUtilitiesKit.h>
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
#import "SSKAsserts.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -41,8 +41,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
- (instancetype)initWithSentTimestamp:(uint64_t)sentTimestamp - (instancetype)initWithSentTimestamp:(uint64_t)sentTimestamp
{ {
OWSAssertDebug(sentTimestamp > 0);
self = [super initWithUniqueId:[TSRecipientReadReceipt uniqueIdForSentTimestamp:sentTimestamp]]; self = [super initWithUniqueId:[TSRecipientReadReceipt uniqueIdForSentTimestamp:sentTimestamp]];
if (self) { if (self) {
@ -60,9 +58,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
- (void)addRecipientId:(NSString *)recipientId timestamp:(uint64_t)timestamp - (void)addRecipientId:(NSString *)recipientId timestamp:(uint64_t)timestamp
{ {
OWSAssertDebug(recipientId.length > 0);
OWSAssertDebug(timestamp > 0);
NSMutableDictionary<NSString *, NSNumber *> *recipientMapCopy = [self.recipientMap mutableCopy]; NSMutableDictionary<NSString *, NSNumber *> *recipientMapCopy = [self.recipientMap mutableCopy];
recipientMapCopy[recipientId] = @(timestamp); recipientMapCopy[recipientId] = @(timestamp);
_recipientMap = [recipientMapCopy copy]; _recipientMap = [recipientMapCopy copy];
@ -73,8 +68,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
readTimestamp:(uint64_t)readTimestamp readTimestamp:(uint64_t)readTimestamp
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
TSRecipientReadReceipt *_Nullable recipientReadReceipt = TSRecipientReadReceipt *_Nullable recipientReadReceipt =
[transaction objectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]]; [transaction objectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
if (!recipientReadReceipt) { if (!recipientReadReceipt) {
@ -88,8 +81,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
transaction: transaction:
(YapDatabaseReadWriteTransaction *)transaction (YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
TSRecipientReadReceipt *_Nullable recipientReadReceipt = TSRecipientReadReceipt *_Nullable recipientReadReceipt =
[transaction objectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]]; [transaction objectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
return recipientReadReceipt.recipientMap; return recipientReadReceipt.recipientMap;
@ -98,8 +89,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
+ (void)removeRecipientIdsForTimestamp:(uint64_t)sentTimestamp + (void)removeRecipientIdsForTimestamp:(uint64_t)sentTimestamp
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(transaction);
[transaction removeObjectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]]; [transaction removeObjectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
} }
@ -133,8 +122,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
+ (instancetype)sharedManager + (instancetype)sharedManager
{ {
OWSAssert(SSKEnvironment.shared.readReceiptManager);
return SSKEnvironment.shared.readReceiptManager; return SSKEnvironment.shared.readReceiptManager;
} }
@ -148,8 +135,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
_dbConnection = primaryStorage.newDatabaseConnection; _dbConnection = primaryStorage.newDatabaseConnection;
OWSSingletonAssert();
// Start processing. // Start processing.
[AppReadiness runNowOrWhenAppDidBecomeReady:^{ [AppReadiness runNowOrWhenAppDidBecomeReady:^{
[self scheduleProcessing]; [self scheduleProcessing];
@ -167,8 +152,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
- (OWSOutgoingReceiptManager *)outgoingReceiptManager - (OWSOutgoingReceiptManager *)outgoingReceiptManager
{ {
OWSAssertDebug(SSKEnvironment.shared.outgoingReceiptManager);
return SSKEnvironment.shared.outgoingReceiptManager; return SSKEnvironment.shared.outgoingReceiptManager;
} }
@ -177,8 +160,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
// Schedules a processing pass, unless one is already scheduled. // Schedules a processing pass, unless one is already scheduled.
- (void)scheduleProcessing - (void)scheduleProcessing
{ {
OWSAssertDebug(AppReadiness.isAppReady);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
@synchronized(self) @synchronized(self)
{ {
@ -240,13 +221,11 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
- (void)markAsReadLocallyBeforeSortId:(uint64_t)sortId thread:(TSThread *)thread - (void)markAsReadLocallyBeforeSortId:(uint64_t)sortId thread:(TSThread *)thread
{ {
OWSAssertDebug(thread);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self markAsReadBeforeSortId:sortId [self markAsReadBeforeSortId:sortId
thread:thread thread:thread
readTimestamp:[NSDate ows_millisecondTimeStamp] readTimestamp:[NSDate millisecondTimestamp]
wasLocal:YES wasLocal:YES
transaction:transaction]; transaction:transaction];
}]; }];
@ -303,11 +282,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
sentTimestamps:(NSArray<NSNumber *> *)sentTimestamps sentTimestamps:(NSArray<NSNumber *> *)sentTimestamps
readTimestamp:(uint64_t)readTimestamp readTimestamp:(uint64_t)readTimestamp
{ {
OWSAssertDebug(recipientId.length > 0);
OWSAssertDebug(sentTimestamps);
if (![self areReadReceiptsEnabled]) { if (![self areReadReceiptsEnabled]) {
OWSLogInfo(@"Ignoring incoming receipt message as read receipts are disabled.");
return; return;
} }
@ -320,9 +295,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
= (NSArray<TSOutgoingMessage *> *)[TSInteraction interactionsWithTimestamp:sentTimestamp = (NSArray<TSOutgoingMessage *> *)[TSInteraction interactionsWithTimestamp:sentTimestamp
ofClass:[TSOutgoingMessage class] ofClass:[TSOutgoingMessage class]
withTransaction:transaction]; withTransaction:transaction];
if (messages.count > 1) {
OWSLogError(@"More than one matching message with timestamp: %llu.", sentTimestamp);
}
if (messages.count > 0) { if (messages.count > 0) {
// TODO: We might also need to "mark as read by recipient" any older messages // TODO: We might also need to "mark as read by recipient" any older messages
// from us in that thread. Or maybe this state should hang on the thread? // from us in that thread. Or maybe this state should hang on the thread?
@ -344,124 +316,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
}); });
} }
- (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssertDebug(message);
OWSAssertDebug(transaction);
uint64_t sentTimestamp = message.timestamp;
NSDictionary<NSString *, NSNumber *> *recipientMap =
[TSRecipientReadReceipt recipientMapForSentTimestamp:sentTimestamp transaction:transaction];
if (!recipientMap) {
return;
}
OWSAssertDebug(recipientMap.count > 0);
for (NSString *recipientId in recipientMap) {
NSNumber *nsReadTimestamp = recipientMap[recipientId];
OWSAssertDebug(nsReadTimestamp);
uint64_t readTimestamp = [nsReadTimestamp unsignedLongLongValue];
[message updateWithReadRecipientId:recipientId readTimestamp:readTimestamp transaction:transaction];
}
[TSRecipientReadReceipt removeRecipientIdsForTimestamp:message.timestamp transaction:transaction];
}
#pragma mark - Linked Device Read Receipts
- (void)applyEarlyReadReceiptsForIncomingMessage:(TSIncomingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
/*
OWSAssertDebug(message);
OWSAssertDebug(transaction);
NSString *senderId = message.authorId;
uint64_t timestamp = message.timestamp;
if (senderId.length < 1 || timestamp < 1) {
OWSFailDebug(@"Invalid incoming message: %@ %llu", senderId, timestamp);
return;
}
OWSLinkedDeviceReadReceipt *_Nullable readReceipt =
[OWSLinkedDeviceReadReceipt findLinkedDeviceReadReceiptWithSenderId:senderId
messageIdTimestamp:timestamp
transaction:transaction];
if (!readReceipt) {
return;
}
[message markAsReadAtTimestamp:readReceipt.readTimestamp sendReadReceipt:NO transaction:transaction];
[readReceipt removeWithTransaction:transaction];
*/
}
- (void)processReadReceiptsFromLinkedDevice:(NSArray<SNProtoSyncMessageRead *> *)readReceiptProtos
readTimestamp:(uint64_t)readTimestamp
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
// TODO TODO TODO
/*
OWSAssertDebug(readReceiptProtos);
OWSAssertDebug(transaction);
for (SNProtoSyncMessageRead *readReceiptProto in readReceiptProtos) {
NSString *_Nullable senderId = readReceiptProto.sender;
uint64_t messageIdTimestamp = readReceiptProto.timestamp;
if (senderId.length == 0) {
OWSFailDebug(@"senderId was unexpectedly nil");
continue;
}
if (messageIdTimestamp == 0) {
OWSFailDebug(@"messageIdTimestamp was unexpectedly 0");
continue;
}
NSArray<TSIncomingMessage *> *messages
= (NSArray<TSIncomingMessage *> *)[TSInteraction interactionsWithTimestamp:messageIdTimestamp
ofClass:[TSIncomingMessage class]
withTransaction:transaction];
if (messages.count > 0) {
for (TSIncomingMessage *message in messages) {
NSTimeInterval secondsSinceRead = [NSDate new].timeIntervalSince1970 - readTimestamp / 1000;
OWSAssertDebug([message isKindOfClass:[TSIncomingMessage class]]);
OWSLogDebug(@"read on linked device %f seconds ago", secondsSinceRead);
[self markAsReadOnLinkedDevice:message readTimestamp:readTimestamp transaction:transaction];
}
} else {
// Received read receipt for unknown incoming message.
// Persist in case we receive the incoming message later.
OWSLinkedDeviceReadReceipt *readReceipt =
[[OWSLinkedDeviceReadReceipt alloc] initWithSenderId:senderId
messageIdTimestamp:messageIdTimestamp
readTimestamp:readTimestamp];
[readReceipt saveWithTransaction:transaction];
}
}
*/
}
- (void)markAsReadOnLinkedDevice:(TSIncomingMessage *)message
readTimestamp:(uint64_t)readTimestamp
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssertDebug(message);
OWSAssertDebug(transaction);
// Always re-mark the message as read to ensure any earlier read time is applied to disappearing messages.
[message markAsReadAtTimestamp:readTimestamp sendReadReceipt:NO transaction:transaction];
// Also mark any unread messages appearing earlier in the thread as read as well.
[self markAsReadBeforeSortId:message.sortId
thread:[message threadWithTransaction:transaction]
readTimestamp:readTimestamp
wasLocal:NO
transaction:transaction];
}
#pragma mark - Mark As Read #pragma mark - Mark As Read
- (void)markAsReadBeforeSortId:(uint64_t)sortId - (void)markAsReadBeforeSortId:(uint64_t)sortId
@ -470,22 +324,12 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
wasLocal:(BOOL)wasLocal wasLocal:(BOOL)wasLocal
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
OWSAssertDebug(sortId > 0);
OWSAssertDebug(thread);
OWSAssertDebug(transaction);
NSMutableArray<id<OWSReadTracking>> *newlyReadList = [NSMutableArray new]; NSMutableArray<id<OWSReadTracking>> *newlyReadList = [NSMutableArray new];
[[TSDatabaseView unseenDatabaseViewExtension:transaction] [[TSDatabaseView unseenDatabaseViewExtension:transaction]
enumerateKeysAndObjectsInGroup:thread.uniqueId enumerateKeysAndObjectsInGroup:thread.uniqueId
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) { usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
if (![object conformsToProtocol:@protocol(OWSReadTracking)]) { if (![object conformsToProtocol:@protocol(OWSReadTracking)]) {
OWSFailDebug(
@"Expected to conform to OWSReadTracking: object with class: %@ collection: %@ "
@"key: %@",
[object class],
collection,
key);
return; return;
} }
id<OWSReadTracking> possiblyRead = (id<OWSReadTracking>)object; id<OWSReadTracking> possiblyRead = (id<OWSReadTracking>)object;
@ -498,7 +342,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
// there is a bug that can somehow cause it to be false leading to conversations permanently being // there is a bug that can somehow cause it to be false leading to conversations permanently being
// stuck with "unread" messages. // stuck with "unread" messages.
OWSAssertDebug(possiblyRead.expireStartedAt == 0);
if (!possiblyRead.read) { if (!possiblyRead.read) {
[newlyReadList addObject:possiblyRead]; [newlyReadList addObject:possiblyRead];
} }
@ -507,12 +350,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
if (newlyReadList.count < 1) { if (newlyReadList.count < 1) {
return; return;
} }
if (wasLocal) {
OWSLogError(@"Marking %lu messages as read locally.", (unsigned long)newlyReadList.count);
} else {
OWSLogError(@"Marking %lu messages as read by linked device.", (unsigned long)newlyReadList.count);
}
for (id<OWSReadTracking> readItem in newlyReadList) { for (id<OWSReadTracking> readItem in newlyReadList) {
[readItem markAsReadAtTimestamp:readTimestamp sendReadReceipt:wasLocal transaction:transaction]; [readItem markAsReadAtTimestamp:readTimestamp sendReadReceipt:wasLocal transaction:transaction];
} }
@ -539,8 +377,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
- (void)setAreReadReceiptsEnabled:(BOOL)value - (void)setAreReadReceiptsEnabled:(BOOL)value
{ {
OWSLogInfo(@"setAreReadReceiptsEnabled: %d.", value);
[self.dbConnection setBool:value [self.dbConnection setBool:value
forKey:OWSReadReceiptManagerAreReadReceiptsEnabled forKey:OWSReadReceiptManagerAreReadReceiptsEnabled
inCollection:OWSReadReceiptManagerCollection]; inCollection:OWSReadReceiptManagerCollection];

Some files were not shown because too many files have changed in this diff Show More