diff --git a/Signal/src/ViewControllers/AppSettings/PrivacySettingsTableViewController.m b/Signal/src/ViewControllers/AppSettings/PrivacySettingsTableViewController.m index c4f68e9ee..0de1d77e4 100644 --- a/Signal/src/ViewControllers/AppSettings/PrivacySettingsTableViewController.m +++ b/Signal/src/ViewControllers/AppSettings/PrivacySettingsTableViewController.m @@ -8,6 +8,7 @@ #import "Signal-Swift.h" #import #import +#import #import #import @@ -186,13 +187,7 @@ NS_ASSUME_NONNULL_BEGIN - (void)deleteThreadsAndMessages { - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - [transaction removeAllObjectsInCollection:[TSThread collection]]; - [transaction removeAllObjectsInCollection:[SignalRecipient collection]]; - [transaction removeAllObjectsInCollection:[TSInteraction collection]]; - [transaction removeAllObjectsInCollection:[TSAttachment collection]]; - }]; - [TSAttachmentStream deleteAttachments]; + [ThreadUtil deleteAllContent]; } - (void)didToggleScreenSecuritySwitch:(UISwitch *)sender diff --git a/Signal/src/ViewControllers/DebugUI/DebugUICalling.swift b/Signal/src/ViewControllers/DebugUI/DebugUICalling.swift index eb78d85a0..33d3bf218 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUICalling.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUICalling.swift @@ -27,26 +27,30 @@ class DebugUICalling: DebugUIPage { } let sectionItems = [ - OWSTableItem(title:"Send 'hangup' for old call") { + OWSTableItem(title: "Send 'hangup' for old call") { [weak self] in + guard let strongSelf = self else { return } + let kFakeCallId = UInt64(12345) let hangupMessage = OWSCallHangupMessage(callId: kFakeCallId) let callMessage = OWSOutgoingCallMessage(thread: thread, hangupMessage: hangupMessage) - self.messageSender.sendPromise(message: callMessage).then { - Logger.debug("\(self.logTag) Successfully sent hangup call message to \(thread.contactIdentifier())") + strongSelf.messageSender.sendPromise(message: callMessage).then { + Logger.debug("\(strongSelf.logTag) Successfully sent hangup call message to \(thread.contactIdentifier())") }.catch { error in - Logger.error("\(self.logTag) failed to send hangup call message to \(thread.contactIdentifier()) with error: \(error)") + Logger.error("\(strongSelf.logTag) failed to send hangup call message to \(thread.contactIdentifier()) with error: \(error)") } }, - OWSTableItem(title:"Send 'busy' for old call") { + OWSTableItem(title: "Send 'busy' for old call") { [weak self] in + guard let strongSelf = self else { return } + let kFakeCallId = UInt64(12345) let busyMessage = OWSCallBusyMessage(callId: kFakeCallId) let callMessage = OWSOutgoingCallMessage(thread: thread, busyMessage: busyMessage) - self.messageSender.sendPromise(message: callMessage).then { - Logger.debug("\(self.logTag) Successfully sent busy call message to \(thread.contactIdentifier())") + strongSelf.messageSender.sendPromise(message: callMessage).then { + Logger.debug("\(strongSelf.logTag) Successfully sent busy call message to \(thread.contactIdentifier())") }.catch { error in - Logger.error("\(self.logTag) failed to send busy call message to \(thread.contactIdentifier()) with error: \(error)") + Logger.error("\(strongSelf.logTag) failed to send busy call message to \(thread.contactIdentifier()) with error: \(error)") } } ] diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m index 4cd9b1511..2ddc7951f 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUIMisc.m @@ -72,7 +72,6 @@ NS_ASSUME_NONNULL_BEGIN [items addObject:[OWSTableItem itemWithTitle:@"Re-register" actionBlock:^{ - [OWSAlerts showConfirmationAlertWithTitle:@"Re-register?" message:@"If you proceed, you will not lose any of your " @@ -80,7 +79,7 @@ NS_ASSUME_NONNULL_BEGIN @"deactivated until you complete re-registration." proceedTitle:@"Proceed" proceedAction:^(UIAlertAction *_Nonnull action) { - [self reregister]; + [DebugUIMisc reregister]; }]; }]]; @@ -124,7 +123,7 @@ NS_ASSUME_NONNULL_BEGIN return [OWSTableSection sectionWithTitle:self.name items:items]; } -- (void)reregister ++ (void)reregister { DDLogInfo(@"%@ re-registering.", self.logTag); [[TSAccountManager sharedInstance] resetForRegistration]; diff --git a/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift b/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift index 768269f7a..e83bf2743 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift +++ b/Signal/src/ViewControllers/DebugUI/DebugUIProfile.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // import Foundation @@ -26,22 +26,25 @@ class DebugUIProfile: DebugUIPage { } override func section(thread aThread: TSThread?) -> OWSTableSection? { + let profileManager = self.profileManager let sectionItems = [ OWSTableItem(title: "Clear Profile Whitelist") { - self.profileManager.clearProfileWhitelist() + profileManager.clearProfileWhitelist() }, OWSTableItem(title: "Log Profile Whitelist") { - self.profileManager.logProfileWhitelist() + profileManager.logProfileWhitelist() }, OWSTableItem(title: "Log User Profiles") { - self.profileManager.logUserProfiles() + profileManager.logUserProfiles() }, OWSTableItem(title: "Regenerate Profile/ProfileKey") { - self.profileManager.regenerateLocalProfile() + profileManager.regenerateLocalProfile() }, - OWSTableItem(title: "Send Profile Key Message") { + OWSTableItem(title: "Send Profile Key Message") { [weak self] in + guard let strongSelf = self else { return } + let message = OWSProfileKeyMessage(timestamp: NSDate.ows_millisecondTimeStamp(), in: aThread) - self.messageSender.sendPromise(message: message).then { + strongSelf.messageSender.sendPromise(message: message).then { Logger.info("Successfully sent profile key message to thread: \(String(describing: aThread))") }.catch { _ in owsFail("Failed to send profile key message to thread: \(String(describing: aThread))") diff --git a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m index 3d5b1bf81..d517f78d1 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m @@ -110,9 +110,9 @@ NS_ASSUME_NONNULL_BEGIN [viewController.navigationController pushViewController:fileBrowser animated:YES]; }]; [subsectionItems addObject:documentsFileBrowserItem]; - [subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:thread]]; [subsectionItems addObject:[self itemForSubsection:[DebugUIBackup new] viewController:viewController thread:thread]]; + [subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:thread]]; [contents addSection:[OWSTableSection sectionWithTitle:@"Sections" items:subsectionItems]]; @@ -137,8 +137,8 @@ NS_ASSUME_NONNULL_BEGIN addObject:[self itemForSubsection:[DebugUISessionState new] viewController:viewController thread:nil]]; [subsectionItems addObject:[self itemForSubsection:[DebugUISyncMessages new] viewController:viewController thread:nil]]; - [subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:nil]]; [subsectionItems addObject:[self itemForSubsection:[DebugUIBackup new] viewController:viewController thread:nil]]; + [subsectionItems addObject:[self itemForSubsection:[DebugUIMisc new] viewController:viewController thread:nil]]; [contents addSection:[OWSTableSection sectionWithTitle:@"Sections" items:subsectionItems]]; viewController.contents = contents; diff --git a/SignalMessaging/utils/ThreadUtil.h b/SignalMessaging/utils/ThreadUtil.h index 0cca7b2b1..f68c08f9c 100644 --- a/SignalMessaging/utils/ThreadUtil.h +++ b/SignalMessaging/utils/ThreadUtil.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // NS_ASSUME_NONNULL_BEGIN @@ -104,6 +104,10 @@ NS_ASSUME_NONNULL_BEGIN // Returns YES IFF the thread was just added to the profile whitelist. + (BOOL)addThreadToProfileWhitelistIfEmptyContactThread:(TSThread *)thread; +#pragma mark - Delete Content + ++ (void)deleteAllContent; + @end NS_ASSUME_NONNULL_END diff --git a/SignalMessaging/utils/ThreadUtil.m b/SignalMessaging/utils/ThreadUtil.m index 26c127ffc..f9e523fae 100644 --- a/SignalMessaging/utils/ThreadUtil.m +++ b/SignalMessaging/utils/ThreadUtil.m @@ -1,5 +1,5 @@ // -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// Copyright (c) 2018 Open Whisper Systems. All rights reserved. // #import "ThreadUtil.h" @@ -605,6 +605,56 @@ NS_ASSUME_NONNULL_BEGIN } } +#pragma mark - Delete Content + ++ (void)deleteAllContent +{ + DDLogInfo(@"%@ %s", self.logTag, __PRETTY_FUNCTION__); + + [OWSPrimaryStorage.sharedManager.newDatabaseConnection + readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + [self removeAllObjectsInCollection:[TSThread collection] class:[TSThread class] transaction:transaction]; + [self removeAllObjectsInCollection:[TSInteraction collection] + class:[TSInteraction class] + transaction:transaction]; + [self removeAllObjectsInCollection:[TSAttachment collection] + class:[TSAttachment class] + transaction:transaction]; + [self removeAllObjectsInCollection:[SignalRecipient collection] + class:[SignalRecipient class] + transaction:transaction]; + }]; + [TSAttachmentStream deleteAttachments]; +} + ++ (void)removeAllObjectsInCollection:(NSString *)collection + class:(Class) class + transaction:(YapDatabaseReadWriteTransaction *)transaction { + OWSAssert(collection.length > 0); + OWSAssert(class); + OWSAssert(transaction); + + NSArray *_Nullable uniqueIds = [transaction allKeysInCollection:collection]; + if (!uniqueIds) { + OWSProdLogAndFail(@"%@ couldn't load uniqueIds for collection: %@.", self.logTag, collection); + return; + } + DDLogInfo(@"%@ Deleting %zd objects from: %@", self.logTag, uniqueIds.count, collection); + NSUInteger count = 0; + for (NSString *uniqueId in uniqueIds) { + // We need to fetch each object, since [TSYapDatabaseObject removeWithTransaction:] sometimes does important + // work. + TSYapDatabaseObject *_Nullable object = [class fetchObjectWithUniqueID:uniqueId transaction:transaction]; + if (!object) { + OWSProdLogAndFail(@"%@ couldn't load object for deletion: %@.", self.logTag, collection); + continue; + } + [object removeWithTransaction:transaction]; + count++; + }; + DDLogInfo(@"%@ Deleted %zd/%zd objects from: %@", self.logTag, count, uniqueIds.count, collection); +} + @end -NS_ASSUME_NONNULL_END + NS_ASSUME_NONNULL_END diff --git a/SignalServiceKit/src/Contacts/TSThread.m b/SignalServiceKit/src/Contacts/TSThread.m index c539b4995..0adb101ce 100644 --- a/SignalServiceKit/src/Contacts/TSThread.m +++ b/SignalServiceKit/src/Contacts/TSThread.m @@ -67,7 +67,14 @@ NS_ASSUME_NONNULL_BEGIN }]; for (NSString *interactionId in interactionIds) { - [transaction removeObjectForKey:interactionId inCollection:[[TSInteraction class] collection]]; + // We need to fetch each interaction, since [TSInteraction removeWithTransaction:] does important work. + TSInteraction *_Nullable interaction = + [TSInteraction fetchObjectWithUniqueID:interactionId transaction:transaction]; + if (!interaction) { + OWSProdLogAndFail(@"%@ couldn't load thread's interaction for deletion.", self.logTag); + continue; + } + [interaction removeWithTransaction:transaction]; } } diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.m b/SignalServiceKit/src/Messages/Interactions/TSMessage.m index af9b0f372..e5cc08293 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.m +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.m @@ -304,7 +304,13 @@ static const NSUInteger OWSMessageSchemaVersion = 4; [super removeWithTransaction:transaction]; for (NSString *attachmentId in self.attachmentIds) { - TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; + // We need to fetch each attachment, since [TSAttachment removeWithTransaction:] does important work. + TSAttachment *_Nullable attachment = + [TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction]; + if (!attachment) { + OWSProdLogAndFail(@"%@ couldn't load interaction's attachment for deletion.", self.logTag); + continue; + } [attachment removeWithTransaction:transaction]; };