diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 55b226498..820d90aec 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -104,6 +104,7 @@ 451DE9F81DC18C9500810E42 /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45CD81EE1DC030E7004C9430 /* AccountManager.swift */; }; 451DE9FD1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451DE9FC1DC1A28200810E42 /* SyncPushTokensJob.swift */; }; 451DE9FE1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451DE9FC1DC1A28200810E42 /* SyncPushTokensJob.swift */; }; + 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */ = {isa = PBXBuildFile; fileRef = 452037D01EE84975004E4CDF /* DebugUISessionState.m */; }; 4520D8D51D417D8E00123472 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4520D8D41D417D8E00123472 /* Photos.framework */; }; 452C468F1E427E200087B011 /* OutboundCallInitiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452C468E1E427E200087B011 /* OutboundCallInitiator.swift */; }; 452C46901E427E200087B011 /* OutboundCallInitiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 452C468E1E427E200087B011 /* OutboundCallInitiator.swift */; }; @@ -518,6 +519,8 @@ 451A13B01E13DED2000A50FD /* CallNotificationsAdapter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; name = CallNotificationsAdapter.swift; path = ../UserInterface/Notifications/CallNotificationsAdapter.swift; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.swift; }; 451DE9F11DC1585F00810E42 /* PromiseKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PromiseKit.framework; path = Carthage/Build/iOS/PromiseKit.framework; sourceTree = ""; }; 451DE9FC1DC1A28200810E42 /* SyncPushTokensJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SyncPushTokensJob.swift; path = Models/SyncPushTokensJob.swift; sourceTree = ""; }; + 452037CF1EE84975004E4CDF /* DebugUISessionState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUISessionState.h; sourceTree = ""; }; + 452037D01EE84975004E4CDF /* DebugUISessionState.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUISessionState.m; sourceTree = ""; }; 4520D8D41D417D8E00123472 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; }; 4526BD481CA61C8D00166BC8 /* OWSMessageEditing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageEditing.h; sourceTree = ""; }; 452C468E1E427E200087B011 /* OutboundCallInitiator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OutboundCallInitiator.swift; sourceTree = ""; }; @@ -1026,6 +1029,8 @@ 34D8C0241ED3673300188D7C /* DebugUIMessages.m */, 34D8C0251ED3673300188D7C /* DebugUITableViewController.h */, 34D8C0261ED3673300188D7C /* DebugUITableViewController.m */, + 452037CF1EE84975004E4CDF /* DebugUISessionState.h */, + 452037D01EE84975004E4CDF /* DebugUISessionState.m */, ); path = DebugUI; sourceTree = ""; @@ -2097,6 +2102,7 @@ 450873C71D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m in Sources */, 76EB057A18170B33006006FC /* OWSContactsManager.m in Sources */, 76EB064218170B33006006FC /* StringUtil.m in Sources */, + 452037D11EE84975004E4CDF /* DebugUISessionState.m in Sources */, 45BFFFA81D898AF0004A12A7 /* OWSStaleNotificationObserver.m in Sources */, 45C681B71D305A580050903A /* OWSCall.m in Sources */, 76EB062618170B33006006FC /* Queue.m in Sources */, diff --git a/Signal/src/ViewControllers/DebugUI/DebugUISessionState.h b/Signal/src/ViewControllers/DebugUI/DebugUISessionState.h new file mode 100644 index 000000000..b315d1afd --- /dev/null +++ b/Signal/src/ViewControllers/DebugUI/DebugUISessionState.h @@ -0,0 +1,16 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +NS_ASSUME_NONNULL_BEGIN + +@class TSContactThread; +@class OWSTableSection; + +@interface DebugUISessionState : NSObject + ++ (OWSTableSection *)sectionForContactThread:(TSContactThread *)contactThread; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUI/DebugUISessionState.m b/Signal/src/ViewControllers/DebugUI/DebugUISessionState.m new file mode 100644 index 000000000..ba9b9c685 --- /dev/null +++ b/Signal/src/ViewControllers/DebugUI/DebugUISessionState.m @@ -0,0 +1,67 @@ +// +// Copyright (c) 2017 Open Whisper Systems. All rights reserved. +// + +#import "DebugUISessionState.h" +#import "OWSTableViewController.h" +#import "Signal-Swift.h" +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@implementation DebugUISessionState + ++ (OWSTableSection *)sectionForContactThread:(TSContactThread *)contactThread +{ + return [OWSTableSection + sectionWithTitle:@"Session State" + items:@[ + [OWSTableItem itemWithTitle:@"Log All Recipient Identities" + actionBlock:^{ + [OWSRecipientIdentity printAllIdentities]; + }], + [OWSTableItem itemWithTitle:@"Log All Sessions" + actionBlock:^{ + dispatch_async([OWSDispatch sessionStoreQueue], ^{ + [[TSStorageManager sharedManager] printAllSessions]; + }); + }], + [OWSTableItem itemWithTitle:@"Toggle Key Change (Contact Thread Only)" + actionBlock:^{ + DDLogError(@"Flipping identity Key. Flip again to return."); + + OWSIdentityManager *identityManager = [OWSIdentityManager sharedManager]; + NSString *recipientId = [contactThread contactIdentifier]; + + NSData *currentKey = [identityManager identityKeyForRecipientId:recipientId]; + NSMutableData *flippedKey = [NSMutableData new]; + const char *currentKeyBytes = currentKey.bytes; + for (NSUInteger i = 0; i < currentKey.length; i++) { + const char xorByte = currentKeyBytes[i] ^ 0xff; + [flippedKey appendBytes:&xorByte length:1]; + } + OWSAssert(flippedKey.length == currentKey.length); + [identityManager saveRemoteIdentity:flippedKey recipientId:recipientId]; + }], + [OWSTableItem itemWithTitle:@"Delete session (Contact Thread Only)" + actionBlock:^{ + dispatch_async([OWSDispatch sessionStoreQueue], ^{ + [[TSStorageManager sharedManager] + deleteAllSessionsForContact:contactThread.contactIdentifier]; + }); + }], + [OWSTableItem itemWithTitle:@"Send session reset (Contact Thread Only)" + actionBlock:^{ + [OWSSessionResetJob + runWithContactThread:contactThread + messageSender:[Environment getCurrent].messageSender + storageManager:[TSStorageManager sharedManager]]; + }] + ]]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m index c782078c9..58b3ba264 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m @@ -5,9 +5,9 @@ #import "DebugUITableViewController.h" #import "DebugUIContacts.h" #import "DebugUIMessages.h" +#import "DebugUISessionState.h" #import "Signal-Swift.h" #import -#import #import NS_ASSUME_NONNULL_BEGIN @@ -49,124 +49,97 @@ NS_ASSUME_NONNULL_BEGIN OWSTableContents *contents = [OWSTableContents new]; contents.title = @"Debug: Conversation"; - [contents - addSection:[OWSTableSection - sectionWithTitle:[DebugUIMessages sectionForThread:thread].headerTitle - items:@[ - [OWSTableItem - disclosureItemWithText:[DebugUIMessages sectionForThread:thread].headerTitle - actionBlock:^{ - [weakSelf pushPageWithSection:[DebugUIMessages - sectionForThread:thread]]; - }], - ]]]; - - [contents - addSection:[OWSTableSection - sectionWithTitle:@"Session State" - items:@[ - [OWSTableItem itemWithTitle:@"Log All Recipient Identities" - actionBlock:^{ - [OWSRecipientIdentity printAllIdentities]; - }], - [OWSTableItem itemWithTitle:@"Log All Sessions" - actionBlock:^{ - dispatch_async([OWSDispatch sessionStoreQueue], ^{ - [[TSStorageManager sharedManager] printAllSessions]; - }); - }], - [OWSTableItem - itemWithTitle:@"Delete session (Contact Thread Only)" - actionBlock:^{ - if (![thread isKindOfClass:[TSContactThread class]]) { - DDLogError(@"Refusing to delete session for group thread."); - OWSAssert(NO); - return; - } - TSContactThread *contactThread = (TSContactThread *)thread; - dispatch_async([OWSDispatch sessionStoreQueue], ^{ - [[TSStorageManager sharedManager] - deleteAllSessionsForContact:contactThread.contactIdentifier]; - }); - }], - [OWSTableItem - itemWithTitle:@"Send session reset (Contact Thread Only)" - actionBlock:^{ - if (![thread isKindOfClass:[TSContactThread class]]) { - DDLogError(@"Refusing to reset session for group thread."); - OWSAssert(NO); - return; - } - TSContactThread *contactThread = (TSContactThread *)thread; - [OWSSessionResetJob - runWithContactThread:contactThread - messageSender:[Environment getCurrent].messageSender - storageManager:[TSStorageManager sharedManager]]; - }] - ]]]; + OWSTableSection *messagesSection = [DebugUIMessages sectionForThread:thread]; + [contents addSection:[OWSTableSection + sectionWithTitle:messagesSection.headerTitle + items:@[ + [OWSTableItem disclosureItemWithText:messagesSection.headerTitle + actionBlock:^{ + [weakSelf pushPageWithSection:messagesSection]; + }], + ]]]; + + if ([thread isKindOfClass:[TSContactThread class]]) { + TSContactThread *contactThread = (TSContactThread *)thread; + + OWSTableSection *sessionSection = [DebugUISessionState sectionForContactThread:contactThread]; + [contents addSection:[OWSTableSection + sectionWithTitle:sessionSection.headerTitle + items:@[ + [OWSTableItem disclosureItemWithText:sessionSection.headerTitle + actionBlock:^{ + [weakSelf + pushPageWithSection:sessionSection]; + }], + ]]]; + + // After enqueing the notification you may want to background the app or lock the screen before it triggers, so + // we give a little delay. + uint64_t notificationDelay = 5; + [contents + addSection: + [OWSTableSection + sectionWithTitle:[NSString + stringWithFormat:@"Call Notifications (%llu second delay)", notificationDelay] + items:@[ + [OWSTableItem + itemWithTitle:@"Missed Call" + actionBlock:^{ + SignalCall *call = + [SignalCall incomingCallWithLocalId:[NSUUID new] + remotePhoneNumber:thread.contactIdentifier + signalingId:0]; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, + (int64_t)(notificationDelay * NSEC_PER_SEC)), + dispatch_get_main_queue(), + ^{ + [[Environment getCurrent].callService.notificationsAdapter + presentMissedCall:call + callerName:thread.name]; + }); + }], + [OWSTableItem + itemWithTitle:@"Rejected Call with New Safety Number" + actionBlock:^{ + SignalCall *call = + [SignalCall incomingCallWithLocalId:[NSUUID new] + remotePhoneNumber:thread.contactIdentifier + signalingId:0]; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, + (int64_t)(notificationDelay * NSEC_PER_SEC)), + dispatch_get_main_queue(), + ^{ + [[Environment getCurrent].callService.notificationsAdapter + presentMissedCallBecauseOfNewIdentityWithCall:call + callerName:thread.name]; + }); + }], + [OWSTableItem + itemWithTitle:@"Rejected Call with No Longer Verified Safety Number" + actionBlock:^{ + SignalCall *call = + [SignalCall incomingCallWithLocalId:[NSUUID new] + remotePhoneNumber:thread.contactIdentifier + signalingId:0]; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, + (int64_t)(notificationDelay * NSEC_PER_SEC)), + dispatch_get_main_queue(), + ^{ + [[Environment getCurrent].callService.notificationsAdapter + presentMissedCallBecauseOfNoLongerVerifiedIdentityWithCall:call + callerName: + thread + .name]; + }); + }], + ]]]; + } // end contact thread section [contents addSection:[DebugUIContacts section]]; - // After enqueing the notification you may want to background the app or lock the screen before it triggers, so we - // give a little delay. - uint64_t notificationDelay = 5; - [contents - addSection: - [OWSTableSection - sectionWithTitle:[NSString - stringWithFormat:@"Call Notifications (%llu second delay)", notificationDelay] - items:@[ - [OWSTableItem itemWithTitle:@"Missed Call" - actionBlock:^{ - SignalCall *call = - [SignalCall incomingCallWithLocalId:[NSUUID new] - remotePhoneNumber:thread.contactIdentifier - signalingId:0]; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, - (int64_t)(notificationDelay * NSEC_PER_SEC)), - dispatch_get_main_queue(), - ^{ - [[Environment getCurrent].callService.notificationsAdapter - presentMissedCall:call - callerName:thread.name]; - }); - }], - [OWSTableItem - itemWithTitle:@"Rejected Call with New Safety Number" - actionBlock:^{ - SignalCall *call = [SignalCall incomingCallWithLocalId:[NSUUID new] - remotePhoneNumber:thread.contactIdentifier - signalingId:0]; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, - (int64_t)(notificationDelay * NSEC_PER_SEC)), - dispatch_get_main_queue(), - ^{ - [[Environment getCurrent].callService.notificationsAdapter - presentMissedCallBecauseOfNewIdentityWithCall:call - callerName:thread.name]; - }); - }], - [OWSTableItem - itemWithTitle:@"Rejected Call with No Longer Verified Safety Number" - actionBlock:^{ - SignalCall *call = [SignalCall incomingCallWithLocalId:[NSUUID new] - remotePhoneNumber:thread.contactIdentifier - signalingId:0]; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, - (int64_t)(notificationDelay * NSEC_PER_SEC)), - dispatch_get_main_queue(), - ^{ - [[Environment getCurrent].callService.notificationsAdapter - presentMissedCallBecauseOfNoLongerVerifiedIdentityWithCall:call - callerName: - thread.name]; - }); - }], - ]]]; - viewController.contents = contents; [viewController presentFromViewController:fromViewController]; }