From ceb210748e68dff5d2d5306b23727e0e98e74c8d Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 6 Jun 2017 14:12:47 -0400 Subject: [PATCH 01/10] Sketch out OWSIdentityManager. // FREEBIE --- Podfile | 8 +++---- Podfile.lock | 16 ++++--------- Signal/src/ProfileFetcherJob.swift | 4 ++-- Signal/src/Signal-Bridging-Header.h | 6 ++--- .../FingerprintViewController.m | 2 +- .../OWSLinkDeviceViewController.m | 8 ++++--- .../SafetyNumberConfirmationAlert.swift | 23 +++++++++++-------- Signal/src/call/CallService.swift | 2 +- .../OWS104CreateRecipientIdentities.m | 2 +- 9 files changed, 35 insertions(+), 36 deletions(-) diff --git a/Podfile b/Podfile index 55d7dcd08..4de5fa3a0 100644 --- a/Podfile +++ b/Podfile @@ -3,10 +3,10 @@ source 'https://github.com/CocoaPods/Specs.git' target 'Signal' do pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git' - pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git' - #pod 'AxolotlKit', path: '../SignalProtocolKit' - pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git' - #pod 'SignalServiceKit', path: '../SignalServiceKit' + #pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git' + pod 'AxolotlKit', path: '../SignalProtocolKit' + #pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git' + pod 'SignalServiceKit', path: '../SignalServiceKit' pod 'OpenSSL' pod 'JSQMessagesViewController', git: 'https://github.com/WhisperSystems/JSQMessagesViewController.git', branch: 'mkirk/position-edit-menu' #pod 'JSQMessagesViewController' path: '../JSQMessagesViewController' diff --git a/Podfile.lock b/Podfile.lock index 709615233..e4127585b 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -109,35 +109,29 @@ PODS: - YapDatabase/SQLCipher/Core DEPENDENCIES: - - AxolotlKit (from `https://github.com/WhisperSystems/SignalProtocolKit.git`) + - AxolotlKit (from `../SignalProtocolKit`) - JSQMessagesViewController (from `https://github.com/WhisperSystems/JSQMessagesViewController.git`, branch `mkirk/position-edit-menu`) - OpenSSL - PureLayout - Reachability - - SignalServiceKit (from `https://github.com/WhisperSystems/SignalServiceKit.git`) + - SignalServiceKit (from `../SignalServiceKit`) - SocketRocket (from `https://github.com/facebook/SocketRocket.git`) EXTERNAL SOURCES: AxolotlKit: - :git: https://github.com/WhisperSystems/SignalProtocolKit.git + :path: ../SignalProtocolKit JSQMessagesViewController: :branch: mkirk/position-edit-menu :git: https://github.com/WhisperSystems/JSQMessagesViewController.git SignalServiceKit: - :git: https://github.com/WhisperSystems/SignalServiceKit.git + :path: ../SignalServiceKit SocketRocket: :git: https://github.com/facebook/SocketRocket.git CHECKOUT OPTIONS: - AxolotlKit: - :commit: 9179d4e326df58185f35af45831e7a5d7250ab85 - :git: https://github.com/WhisperSystems/SignalProtocolKit.git JSQMessagesViewController: :commit: 7054e4b13ee5bcd6d524adb6dc9a726e8c466308 :git: https://github.com/WhisperSystems/JSQMessagesViewController.git - SignalServiceKit: - :commit: 43d1aa49dc869486cdba8546b56e716beae5c1d0 - :git: https://github.com/WhisperSystems/SignalServiceKit.git SocketRocket: :commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf :git: https://github.com/facebook/SocketRocket.git @@ -164,6 +158,6 @@ SPEC CHECKSUMS: UnionFind: c33be5adb12983981d6e827ea94fc7f9e370f52d YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266 -PODFILE CHECKSUM: 48e80d7f1e049bbf544a689fdfdf33e8196c640a +PODFILE CHECKSUM: dc5ed308ade575a81ccadf5c485990530353c4ee COCOAPODS: 1.2.1 diff --git a/Signal/src/ProfileFetcherJob.swift b/Signal/src/ProfileFetcherJob.swift index ad1c1009e..f80ddb517 100644 --- a/Signal/src/ProfileFetcherJob.swift +++ b/Signal/src/ProfileFetcherJob.swift @@ -62,12 +62,12 @@ class ProfileFetcherJob: NSObject { private func verifyIdentityUpToDateAsync(recipientId: String, latestIdentityKey: Data) { OWSDispatch.sessionStoreQueue().async { - if self.storageManager.identityKey(forRecipientId: recipientId) == nil { + if OWSIdentityManager.shared().identityKey(forRecipientId: recipientId) == nil { // first time use, do nothing, since there's no change. return } - if self.storageManager.saveRemoteIdentity(latestIdentityKey, recipientId: recipientId) { + if OWSIdentityManager.shared().saveRemoteIdentity(latestIdentityKey, recipientId: recipientId) { Logger.info("\(self.TAG) updated identity key in fetched profile for recipient: \(recipientId)") self.storageManager.deleteAllSessions(forContact: recipientId) } else { diff --git a/Signal/src/Signal-Bridging-Header.h b/Signal/src/Signal-Bridging-Header.h index 5a2fad749..6aa08aaa7 100644 --- a/Signal/src/Signal-Bridging-Header.h +++ b/Signal/src/Signal-Bridging-Header.h @@ -52,13 +52,14 @@ #import #import #import +#import +#import #import #import +#import #import #import #import -#import -#import #import #import #import @@ -77,7 +78,6 @@ #import #import #import -#import #import #import #import diff --git a/Signal/src/ViewControllers/FingerprintViewController.m b/Signal/src/ViewControllers/FingerprintViewController.m index 913c2406e..372bf25f1 100644 --- a/Signal/src/ViewControllers/FingerprintViewController.m +++ b/Signal/src/ViewControllers/FingerprintViewController.m @@ -11,8 +11,8 @@ #import #import #import +#import #import -#import #import #import diff --git a/Signal/src/ViewControllers/OWSLinkDeviceViewController.m b/Signal/src/ViewControllers/OWSLinkDeviceViewController.m index 1203f9401..73cd9812a 100644 --- a/Signal/src/ViewControllers/OWSLinkDeviceViewController.m +++ b/Signal/src/ViewControllers/OWSLinkDeviceViewController.m @@ -8,7 +8,7 @@ #import "SettingsTableViewController.h" #import #import -#import +#import #import NS_ASSUME_NONNULL_BEGIN @@ -128,8 +128,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)provisionWithParser:(OWSDeviceProvisioningURLParser *)parser { - NSData *myPublicKey = [[TSStorageManager sharedManager] identityKeyPair].publicKey; - NSData *myPrivateKey = [[TSStorageManager sharedManager] identityKeyPair].ows_privateKey; + ECKeyPair *_Nullable identityKeyPair = [[OWSIdentityManager sharedManager] identityKeyPair]; + OWSAssert(identityKeyPair); + NSData *myPublicKey = identityKeyPair.publicKey; + NSData *myPrivateKey = identityKeyPair.ows_privateKey; NSString *accountIdentifier = [TSStorageManager localNumber]; OWSDeviceProvisioner *provisioner = [[OWSDeviceProvisioner alloc] initWithMyPublicKey:myPublicKey diff --git a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift index 6f5515d4f..7c708452c 100644 --- a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift +++ b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift @@ -4,6 +4,7 @@ import Foundation +// TODO: class SafetyNumberConfirmationAlert: NSObject { let TAG = "[SafetyNumberConfirmationAlert]" @@ -69,10 +70,8 @@ class SafetyNumberConfirmationAlert: NSObject { Logger.info("\(self.TAG) Confirmed identity: \(untrustedIdentity)") OWSDispatch.sessionStoreQueue().async { - self.storageManager.saveRemoteIdentity(untrustedIdentity.identityKey, - recipientId: untrustedIdentity.recipientId, - approvedForBlockingUse: true, - approvedForNonBlockingUse: true) + OWSIdentityManager.shared().saveRemoteIdentity(untrustedIdentity.identityKey, + recipientId: untrustedIdentity.recipientId) MarkIdentityAsSeenJob.run(recipientId: untrustedIdentity.recipientId) DispatchQueue.main.async { completion(true) @@ -111,15 +110,19 @@ class SafetyNumberConfirmationAlert: NSObject { } private func unconfirmedIdentities(recipientIds: [String]) -> [OWSRecipientIdentity] { - return recipientIds.flatMap { - self.storageManager.unconfirmedIdentityThatShouldBlockSending(forRecipientId: $0) - } + // TODO: Return the _unverified_ identities. + return [] +// return recipientIds.flatMap { +// OWSIdentityManager.shared().unconfirmedIdentityThatShouldBlockSending(forRecipientId: $0) +// } } private func unseenIdentities(recipientIds: [String]) -> [OWSRecipientIdentity] { - return recipientIds.flatMap { - self.storageManager.unseenIdentityChange(forRecipientId: $0) - } + // TODO: Return the _unverified_ identities. + return [] +// return recipientIds.flatMap { +// OWSIdentityManager.shared().unseenIdentityChange(forRecipientId: $0) +// } } } diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index 07229e4ad..b5fe03b95 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -470,7 +470,7 @@ protocol CallServiceObserver: class { let newCall = SignalCall.incomingCall(localId: UUID(), remotePhoneNumber: thread.contactIdentifier(), signalingId: callId) - guard self.storageManager.unseenIdentityChange(forRecipientId: thread.contactIdentifier()) == nil else { + guard OWSIdentityManager.shared().isCurrentIdentityTrustedForSending(withRecipientId: thread.contactIdentifier()) else { let callerName = self.contactsManager.displayName(forPhoneIdentifier: thread.contactIdentifier()) self.notificationsAdapter.presentRejectedCallWithUnseenIdentityChange(newCall, callerName: callerName) return diff --git a/Signal/src/environment/Migrations/OWS104CreateRecipientIdentities.m b/Signal/src/environment/Migrations/OWS104CreateRecipientIdentities.m index 7077eaeee..9e51de910 100644 --- a/Signal/src/environment/Migrations/OWS104CreateRecipientIdentities.m +++ b/Signal/src/environment/Migrations/OWS104CreateRecipientIdentities.m @@ -3,8 +3,8 @@ // #import "OWS104CreateRecipientIdentities.h" +#import #import -#import #import #import From b6ddea9eaeeb9b945c44f8ca950580a88d710c12 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 6 Jun 2017 15:01:16 -0400 Subject: [PATCH 02/10] Sketch out OWSIdentityManager. // FREEBIE --- Signal.xcodeproj/project.pbxproj | 4 -- Signal/src/Jobs/MarkIdentityAsSeenJob.swift | 43 ------------------- .../ConversationView/MessagesViewController.m | 1 - .../SafetyNumberConfirmationAlert.swift | 1 - .../OWS104CreateRecipientIdentities.m | 4 +- Signal/src/network/PushManager.m | 3 -- 6 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 Signal/src/Jobs/MarkIdentityAsSeenJob.swift diff --git a/Signal.xcodeproj/project.pbxproj b/Signal.xcodeproj/project.pbxproj index 1720ae466..55b226498 100644 --- a/Signal.xcodeproj/project.pbxproj +++ b/Signal.xcodeproj/project.pbxproj @@ -154,7 +154,6 @@ 458E38371D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38361D668EBF0094BD24 /* OWSDeviceProvisioningURLParser.m */; }; 458E383A1D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 458E38391D6699FA0094BD24 /* OWSDeviceProvisioningURLParserTest.m */; }; 459311FC1D75C948008DD4F0 /* OWSDeviceTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */; }; - 459B1C671ED480BB00506A04 /* MarkIdentityAsSeenJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 459B1C661ED480BB00506A04 /* MarkIdentityAsSeenJob.swift */; }; 45A6DAD61EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; }; 45A6DAD71EBBF85500893231 /* ReminderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45A6DAD51EBBF85500893231 /* ReminderView.swift */; }; 45AE48511E0732D6004D96C2 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */; }; @@ -577,7 +576,6 @@ 459311FB1D75C948008DD4F0 /* OWSDeviceTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDeviceTableViewCell.m; sourceTree = ""; }; 4597E94E1D8313C100040CDE /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = translations/sq.lproj/Localizable.strings; sourceTree = ""; }; 4597E94F1D8313CB00040CDE /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = translations/bg.lproj/Localizable.strings; sourceTree = ""; }; - 459B1C661ED480BB00506A04 /* MarkIdentityAsSeenJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MarkIdentityAsSeenJob.swift; path = Jobs/MarkIdentityAsSeenJob.swift; sourceTree = ""; }; 45A6DAD51EBBF85500893231 /* ReminderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReminderView.swift; sourceTree = ""; }; 45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = ""; }; 45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = ""; }; @@ -1163,7 +1161,6 @@ 451DE9FC1DC1A28200810E42 /* SyncPushTokensJob.swift */, 45D231761DC7E8F10034FA89 /* SessionResetJob.swift */, 452ECA4C1E087E7200E2F016 /* MessageFetcherJob.swift */, - 459B1C661ED480BB00506A04 /* MarkIdentityAsSeenJob.swift */, 4585C4651ED5DF7A00896AEA /* ProfileFetcherJob.swift */, ); name = Jobs; @@ -2126,7 +2123,6 @@ 45C0DC1E1E69011F00E04C47 /* UIStoryboard+OWS.swift in Sources */, 34F3089F1ECA580B00BB7697 /* OWSUnreadIndicatorCell.m in Sources */, 34B3F8861E8DF1700035BE1A /* NotificationSettingsOptionsViewController.m in Sources */, - 459B1C671ED480BB00506A04 /* MarkIdentityAsSeenJob.swift in Sources */, 452ECA4D1E087E7200E2F016 /* MessageFetcherJob.swift in Sources */, 452EA0971EA662330078744B /* AttachmentPointerAdapter.swift in Sources */, 34DFCB851E8E04B500053165 /* AddToBlockListViewController.m in Sources */, diff --git a/Signal/src/Jobs/MarkIdentityAsSeenJob.swift b/Signal/src/Jobs/MarkIdentityAsSeenJob.swift deleted file mode 100644 index 329f0b78b..000000000 --- a/Signal/src/Jobs/MarkIdentityAsSeenJob.swift +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2017 Open Whisper Systems. All rights reserved. -// - -import Foundation - -@objc -class MarkIdentityAsSeenJob: NSObject { - let TAG = "[MarkIdentityAsSeenJob]" - - private let recipientIds: [String] - - public class func run(thread: TSThread) { - let recipientIds = thread.recipientIdentifiers - - MarkIdentityAsSeenJob(recipientIds: recipientIds).run() - } - - public class func run(recipientId: String) { - MarkIdentityAsSeenJob(recipientIds: [recipientId]).run() - } - - init(recipientIds: [String]) { - self.recipientIds = recipientIds - } - - public func run() { - for recipientId in self.recipientIds { - markAsSeenIfNecessary(recipientId: recipientId) - } - } - - private func markAsSeenIfNecessary(recipientId: String) { - guard let identity = OWSRecipientIdentity.fetch(uniqueId: recipientId) else { - Logger.verbose("\(self.TAG) no existing identity for recipient: \(recipientId). No messages with them yet?") - return - } - if !identity.wasSeen { - Logger.info("\(self.TAG) marking identity as seen for recipient: \(recipientId)") - identity.updateAsSeen() - } - } -} diff --git a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m index 68b38148a..a0ca24f9d 100644 --- a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m +++ b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m @@ -834,7 +834,6 @@ typedef enum : NSUInteger { _callOnOpen = NO; } [self updateNavigationBarSubtitleLabel]; - [MarkIdentityAsSeenJob runWithThread:self.thread]; [ProfileFetcherJob runWithThread:self.thread networkManager:self.networkManager]; [self markVisibleMessagesAsRead]; diff --git a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift index 7c708452c..b1bf06dbe 100644 --- a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift +++ b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift @@ -72,7 +72,6 @@ class SafetyNumberConfirmationAlert: NSObject { OWSDispatch.sessionStoreQueue().async { OWSIdentityManager.shared().saveRemoteIdentity(untrustedIdentity.identityKey, recipientId: untrustedIdentity.recipientId) - MarkIdentityAsSeenJob.run(recipientId: untrustedIdentity.recipientId) DispatchQueue.main.async { completion(true) } diff --git a/Signal/src/environment/Migrations/OWS104CreateRecipientIdentities.m b/Signal/src/environment/Migrations/OWS104CreateRecipientIdentities.m index 9e51de910..fc2407aca 100644 --- a/Signal/src/environment/Migrations/OWS104CreateRecipientIdentities.m +++ b/Signal/src/environment/Migrations/OWS104CreateRecipientIdentities.m @@ -54,8 +54,8 @@ static NSString *const OWS104CreateRecipientIdentitiesMigrationId = @"104"; identityKey:identityKey isFirstKnownKey:NO createdAt:[NSDate dateWithTimeIntervalSince1970:0] - approvedForBlockingUse:YES - approvedForNonBlockingUse:NO] saveWithTransaction:transaction]; + verificationState:OWSVerificationStateDefault] + saveWithTransaction:transaction]; }]; [self saveWithTransaction:transaction]; diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index fe242de84..be5ffd931 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -216,9 +216,6 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe return; } - TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:recipientId]; - [MarkIdentityAsSeenJob runWithThread:thread]; - [self.callUIAdapter startAndShowOutgoingCallWithRecipientId:recipientId]; completionHandler(); } else if ([identifier isEqualToString:PushManagerActionsShowThread]) { From c7c243cfedcd5de8635f273af75204c4ead79887 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Tue, 6 Jun 2017 15:32:38 -0400 Subject: [PATCH 03/10] Clean up ahead of PR. // FREEBIE --- .../SafetyNumberConfirmationAlert.swift | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift index b1bf06dbe..73e15cfa5 100644 --- a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift +++ b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift @@ -36,25 +36,12 @@ class SafetyNumberConfirmationAlert: NSObject { */ public func presentIfNecessary(recipientIds: [String], confirmationText: String, verifySeen: Bool, completion: @escaping (Bool) -> Void) -> Bool { - let unconfirmedIdentity = unconfirmedIdentities(recipientIds: recipientIds).first - - var unseenIdentity: OWSRecipientIdentity? - if verifySeen { - unseenIdentity = unseenIdentities(recipientIds: recipientIds).first - } - - guard let untrustedIdentity = [unseenIdentity, unconfirmedIdentity].flatMap({ $0 }).first else { + guard let unverifiedIdentity = unverifiedIdentity(recipientIds: recipientIds) else { // No identities to confirm, no alert to present. return false } - let displayName: String = { - if let signalAccount = contactsManager.signalAccountMap[untrustedIdentity.recipientId] { - return contactsManager.displayName(for: signalAccount) - } else { - return contactsManager.displayName(forPhoneIdentifier: untrustedIdentity.recipientId) - } - }() + let displayName = contactsManager.displayName(forPhoneIdentifier: unverifiedIdentity.recipientId) let titleFormat = NSLocalizedString("CONFIRM_SENDING_TO_CHANGED_IDENTITY_TITLE_FORMAT", comment: "Action sheet title presented when a users's SN have recently changed. Embeds {{contact's name or phone number}}") @@ -67,11 +54,10 @@ class SafetyNumberConfirmationAlert: NSObject { let actionSheetController = UIAlertController(title: title, message:body, preferredStyle: .actionSheet) let confirmAction = UIAlertAction(title: confirmationText, style: .default) { _ in - Logger.info("\(self.TAG) Confirmed identity: \(untrustedIdentity)") + Logger.info("\(self.TAG) Confirmed identity: \(unverifiedIdentity)") OWSDispatch.sessionStoreQueue().async { - OWSIdentityManager.shared().saveRemoteIdentity(untrustedIdentity.identityKey, - recipientId: untrustedIdentity.recipientId) + OWSIdentityManager.shared().setVerificationState(.default, identityKey: unverifiedIdentity.identityKey, recipientId: unverifiedIdentity.recipientId, sendSyncMessage: true) DispatchQueue.main.async { completion(true) } @@ -80,10 +66,10 @@ class SafetyNumberConfirmationAlert: NSObject { actionSheetController.addAction(confirmAction) let showSafetyNumberAction = UIAlertAction(title: NSLocalizedString("VERIFY_PRIVACY", comment: "Action sheet item"), style: .default) { _ in - Logger.info("\(self.TAG) Opted to show Safety Number for identity: \(untrustedIdentity)") + Logger.info("\(self.TAG) Opted to show Safety Number for identity: \(unverifiedIdentity)") - self.presentSafetyNumberViewController(theirIdentityKey: untrustedIdentity.identityKey, - theirRecipientId: untrustedIdentity.recipientId, + self.presentSafetyNumberViewController(theirIdentityKey: unverifiedIdentity.identityKey, + theirRecipientId: unverifiedIdentity.recipientId, theirDisplayName: displayName, completion: { completion(false) }) From 41a34e572bd0c2a58202606985ba1c4a020295cd Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 6 Jun 2017 15:44:20 -0400 Subject: [PATCH 04/10] Update Safety Number alerts to work with verification // FREEBIE --- .../SafetyNumberConfirmationAlert.swift | 33 +++++++------------ Signal/src/call/CallService.swift | 2 +- 2 files changed, 12 insertions(+), 23 deletions(-) diff --git a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift index 73e15cfa5..5fe4ece72 100644 --- a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift +++ b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift @@ -36,12 +36,12 @@ class SafetyNumberConfirmationAlert: NSObject { */ public func presentIfNecessary(recipientIds: [String], confirmationText: String, verifySeen: Bool, completion: @escaping (Bool) -> Void) -> Bool { - guard let unverifiedIdentity = unverifiedIdentity(recipientIds: recipientIds) else { + guard let noLongerVerifiedIdentity = noLongerVerifiedIdentity(recipientIds: recipientIds) else { // No identities to confirm, no alert to present. return false } - let displayName = contactsManager.displayName(forPhoneIdentifier: unverifiedIdentity.recipientId) + let displayName = contactsManager.displayName(forPhoneIdentifier: noLongerVerifiedIdentity.recipientId) let titleFormat = NSLocalizedString("CONFIRM_SENDING_TO_CHANGED_IDENTITY_TITLE_FORMAT", comment: "Action sheet title presented when a users's SN have recently changed. Embeds {{contact's name or phone number}}") @@ -54,10 +54,10 @@ class SafetyNumberConfirmationAlert: NSObject { let actionSheetController = UIAlertController(title: title, message:body, preferredStyle: .actionSheet) let confirmAction = UIAlertAction(title: confirmationText, style: .default) { _ in - Logger.info("\(self.TAG) Confirmed identity: \(unverifiedIdentity)") + Logger.info("\(self.TAG) Confirmed identity: \(noLongerVerifiedIdentity)") OWSDispatch.sessionStoreQueue().async { - OWSIdentityManager.shared().setVerificationState(.default, identityKey: unverifiedIdentity.identityKey, recipientId: unverifiedIdentity.recipientId, sendSyncMessage: true) + OWSIdentityManager.shared().setVerificationState(.default, identityKey: noLongerVerifiedIdentity.identityKey, recipientId: noLongerVerifiedIdentity.recipientId, sendSyncMessage: true) DispatchQueue.main.async { completion(true) } @@ -66,10 +66,10 @@ class SafetyNumberConfirmationAlert: NSObject { actionSheetController.addAction(confirmAction) let showSafetyNumberAction = UIAlertAction(title: NSLocalizedString("VERIFY_PRIVACY", comment: "Action sheet item"), style: .default) { _ in - Logger.info("\(self.TAG) Opted to show Safety Number for identity: \(unverifiedIdentity)") + Logger.info("\(self.TAG) Opted to show Safety Number for identity: \(noLongerVerifiedIdentity)") - self.presentSafetyNumberViewController(theirIdentityKey: unverifiedIdentity.identityKey, - theirRecipientId: unverifiedIdentity.recipientId, + self.presentSafetyNumberViewController(theirIdentityKey: noLongerVerifiedIdentity.identityKey, + theirRecipientId: noLongerVerifiedIdentity.recipientId, theirDisplayName: displayName, completion: { completion(false) }) @@ -94,20 +94,9 @@ class SafetyNumberConfirmationAlert: NSObject { UIApplication.shared.frontmostViewController?.present(fingerprintViewController, animated: true, completion: completion) } - private func unconfirmedIdentities(recipientIds: [String]) -> [OWSRecipientIdentity] { - // TODO: Return the _unverified_ identities. - return [] -// return recipientIds.flatMap { -// OWSIdentityManager.shared().unconfirmedIdentityThatShouldBlockSending(forRecipientId: $0) -// } + private func noLongerVerifiedIdentity(recipientIds: [String]) -> OWSRecipientIdentity? { + return recipientIds.flatMap { + OWSIdentityManager.shared().noLongerVerifiedIdentity(recipientId: $0) + }.first } - - private func unseenIdentities(recipientIds: [String]) -> [OWSRecipientIdentity] { - // TODO: Return the _unverified_ identities. - return [] -// return recipientIds.flatMap { -// OWSIdentityManager.shared().unseenIdentityChange(forRecipientId: $0) -// } - } - } diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index b5fe03b95..3d704da66 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -470,7 +470,7 @@ protocol CallServiceObserver: class { let newCall = SignalCall.incomingCall(localId: UUID(), remotePhoneNumber: thread.contactIdentifier(), signalingId: callId) - guard OWSIdentityManager.shared().isCurrentIdentityTrustedForSending(withRecipientId: thread.contactIdentifier()) else { + guard OWSIdentityManager.shared().isCurrentIdentityTrustedForSending(toRecipientId: thread.contactIdentifier()) else { let callerName = self.contactsManager.displayName(forPhoneIdentifier: thread.contactIdentifier()) self.notificationsAdapter.presentRejectedCallWithUnseenIdentityChange(newCall, callerName: callerName) return From 146031e4d505911cce840f6a2e7a3150e4d7abba Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 6 Jun 2017 15:52:30 -0400 Subject: [PATCH 05/10] update copy / remove some unused "unseen" tracking // FREEBIE --- Signal/src/ViewControllers/AddToGroupViewController.m | 2 -- .../ConversationView/MessagesViewController.m | 1 - Signal/src/ViewControllers/NewGroupViewController.m | 2 -- .../SafetyNumberConfirmationAlert.swift | 10 ++++------ Signal/src/call/OutboundCallInitiator.swift | 3 +-- Signal/translations/en.lproj/Localizable.strings | 8 ++++---- 6 files changed, 9 insertions(+), 17 deletions(-) diff --git a/Signal/src/ViewControllers/AddToGroupViewController.m b/Signal/src/ViewControllers/AddToGroupViewController.m index 217140871..0a2e8e2df 100644 --- a/Signal/src/ViewControllers/AddToGroupViewController.m +++ b/Signal/src/ViewControllers/AddToGroupViewController.m @@ -73,7 +73,6 @@ NS_ASSUME_NONNULL_BEGIN @"button title to confirm adding a recipient to a group when their safety " @"number has recently changed") contactsManager:helper.contactsManager - verifySeen:YES completion:^(BOOL didConfirmIdentity) { if (didConfirmIdentity) { [weakSelf addToGroup:phoneNumber]; @@ -125,7 +124,6 @@ NS_ASSUME_NONNULL_BEGIN @"button title to confirm adding a recipient to a group when their safety " @"number has recently changed") contactsManager:helper.contactsManager - verifySeen:YES completion:^(BOOL didConfirmIdentity) { if (didConfirmIdentity) { [weakSelf addToGroup:signalAccount.recipientId]; diff --git a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m index a0ca24f9d..ce78559e0 100644 --- a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m +++ b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m @@ -1173,7 +1173,6 @@ typedef enum : NSUInteger { return [SafetyNumberConfirmationAlert presentAlertIfNecessaryWithRecipientIds:self.thread.recipientIdentifiers confirmationText:confirmationText contactsManager:self.contactsManager - verifySeen:NO completion:completionHandler]; } diff --git a/Signal/src/ViewControllers/NewGroupViewController.m b/Signal/src/ViewControllers/NewGroupViewController.m index 2deb7ff2f..13481b808 100644 --- a/Signal/src/ViewControllers/NewGroupViewController.m +++ b/Signal/src/ViewControllers/NewGroupViewController.m @@ -261,7 +261,6 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68; @"their safety " @"number has recently changed") contactsManager:contactsViewHelper.contactsManager - verifySeen:YES completion:^(BOOL didConfirmIdentity) { if (didConfirmIdentity) { [weakSelf addRecipientId:recipientId]; @@ -351,7 +350,6 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68; @"their safety " @"number has recently changed") contactsManager:contactsViewHelper.contactsManager - verifySeen:YES completion:^(BOOL didConfirmIdentity) { if (didConfirmIdentity) { [weakSelf addRecipientId:recipientId]; diff --git a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift index 5fe4ece72..bd68df4d8 100644 --- a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift +++ b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift @@ -4,7 +4,6 @@ import Foundation -// TODO: class SafetyNumberConfirmationAlert: NSObject { let TAG = "[SafetyNumberConfirmationAlert]" @@ -17,14 +16,13 @@ class SafetyNumberConfirmationAlert: NSObject { self.storageManager = TSStorageManager.shared() } - public class func presentAlertIfNecessary(recipientId: String, confirmationText: String, contactsManager: OWSContactsManager, verifySeen: Bool, completion: @escaping (Bool) -> Void) -> Bool { - return self.presentAlertIfNecessary(recipientIds: [recipientId], confirmationText: confirmationText, contactsManager: contactsManager, verifySeen: verifySeen, completion: completion) + public class func presentAlertIfNecessary(recipientId: String, confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void) -> Bool { + return self.presentAlertIfNecessary(recipientIds: [recipientId], confirmationText: confirmationText, contactsManager: contactsManager, completion: completion) } - public class func presentAlertIfNecessary(recipientIds: [String], confirmationText: String, contactsManager: OWSContactsManager, verifySeen: Bool, completion: @escaping (Bool) -> Void) -> Bool { + public class func presentAlertIfNecessary(recipientIds: [String], confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void) -> Bool { return SafetyNumberConfirmationAlert(contactsManager: contactsManager).presentIfNecessary(recipientIds: recipientIds, confirmationText: confirmationText, - verifySeen: verifySeen, completion: completion) } @@ -34,7 +32,7 @@ class SafetyNumberConfirmationAlert: NSObject { * @returns true if an alert was shown * false if there were no unconfirmed identities */ - public func presentIfNecessary(recipientIds: [String], confirmationText: String, verifySeen: Bool, completion: @escaping (Bool) -> Void) -> Bool { + public func presentIfNecessary(recipientIds: [String], confirmationText: String, completion: @escaping (Bool) -> Void) -> Bool { guard let noLongerVerifiedIdentity = noLongerVerifiedIdentity(recipientIds: recipientIds) else { // No identities to confirm, no alert to present. diff --git a/Signal/src/call/OutboundCallInitiator.swift b/Signal/src/call/OutboundCallInitiator.swift index 144fbc1af..e898e5c33 100644 --- a/Signal/src/call/OutboundCallInitiator.swift +++ b/Signal/src/call/OutboundCallInitiator.swift @@ -48,8 +48,7 @@ import Foundation let showedAlert = SafetyNumberConfirmationAlert.presentAlertIfNecessary(recipientId: recipientId, confirmationText: CallStrings.confirmAndCallButtonTitle, - contactsManager: self.contactsManager, - verifySeen: true) { didConfirmIdentity in + contactsManager: self.contactsManager) { didConfirmIdentity in if didConfirmIdentity { _ = self.initiateCall(recipientId: recipientId) } diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 9092bcaf1..ae0c3bfb3 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -1073,13 +1073,13 @@ "RETRY_BUTTON_TEXT" = "Retry"; /* button title to confirm adding a recipient to a group when their safety number has recently changed */ -"SAFETY_NUMBER_CHANGED_CONFIRM_ADD_TO_GROUP_ACTION" = "Confirm and Add to Group"; +"SAFETY_NUMBER_CHANGED_CONFIRM_ADD_TO_GROUP_ACTION" = "Add to Group Anyway"; -/* alert button text to confirm placing an outgoing call after the recipients Safety Number has changed. */ -"SAFETY_NUMBER_CHANGED_CONFIRM_CALL_ACTION" = "Confirm and Call"; +/* button title to confirm calling a recipient whose safety number recently changed */ +"SAFETY_NUMBER_CHANGED_CONFIRM_CALL_ACTION" = "Call Anyway"; /* button title to confirm sending to a recipient whose safety number recently changed */ -"SAFETY_NUMBER_CHANGED_CONFIRM_SEND_ACTION" = "Confirm and Send"; +"SAFETY_NUMBER_CHANGED_CONFIRM_SEND_ACTION" = "Send Anyway"; /* Snippet to share {{safety number}} with a friend. sent e.g. via SMS */ "SAFETY_NUMBER_SHARE_FORMAT" = "Our Signal Safety Number:\n%@"; From 11275530414cf78bd2cd0bc0130616a666260dba Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 6 Jun 2017 16:31:09 -0400 Subject: [PATCH 06/10] restore "confirm and callback" functionality // FREEBIE --- .../CallNotificationsAdapter.swift | 4 ++-- .../UserNotificationsAdaptee.swift | 8 +++---- Signal/src/UserInterface/Strings.swift | 21 ++++++++--------- .../DebugUI/DebugUITableViewController.m | 4 ++-- Signal/src/call/CallService.swift | 2 +- .../OWSCallNotificationsAdaptee.h | 7 +++--- Signal/src/environment/NotificationsManager.m | 11 ++++----- Signal/src/network/PushManager.h | 4 ++-- Signal/src/network/PushManager.m | 23 ++++++++++++++----- .../translations/en.lproj/Localizable.strings | 21 +++++------------ 10 files changed, 52 insertions(+), 53 deletions(-) diff --git a/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift b/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift index 8d0d95a40..f6e03dbbf 100644 --- a/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift +++ b/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift @@ -36,8 +36,8 @@ class CallNotificationsAdapter: NSObject { adaptee.presentMissedCall(call, callerName: callerName) } - func presentRejectedCallWithUnseenIdentityChange(_ call: SignalCall, callerName: String) { + func presentRejectedCallWithIdentityChange(_ call: SignalCall, callerName: String) { Logger.debug("\(TAG) in \(#function)") - adaptee.presentRejectedCallWithUnseenIdentityChange(call, callerName: callerName) + adaptee.presentRejectedCallWithIdentityChange(call, callerName: callerName) } } diff --git a/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift b/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift index 676a47179..66c9a1cbd 100644 --- a/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift +++ b/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift @@ -134,7 +134,7 @@ class UserNotificationsAdaptee: NSObject, OWSCallNotificationsAdaptee, UNUserNot center.add(request) } - func presentRejectedCallWithUnseenIdentityChange(_ call: SignalCall, callerName: String) { + func presentRejectedCallWithIdentityChange(_ call: SignalCall, callerName: String) { Logger.debug("\(TAG) \(#function)") let content = UNMutableNotificationContent() @@ -144,11 +144,11 @@ class UserNotificationsAdaptee: NSObject, OWSCallNotificationsAdaptee, UNUserNot let notificationBody = { () -> String in switch previewType { case .noNameNoPreview: - return CallStrings.rejectedCallWithUnseenIdentityChangeNotificationBody + return CallStrings.rejectedCallWithIdentityChangeNotificationBody case .nameNoPreview, .namePreview: return (Environment.getCurrent().preferences.isCallKitPrivacyEnabled() - ? CallStrings.rejectedCallWithUnseenIdentityChangeNotificationBodyWithoutCallerName - : String(format: CallStrings.rejectedCallWithUnseenIdentityChangeNotificationBodyWithCallerName, callerName)) + ? CallStrings.rejectedCallWithIdentityChangeNotificationBodyWithoutCallerName + : String(format: CallStrings.rejectedCallWithIdentityChangeNotificationBodyWithCallerName, callerName)) }}() content.body = notificationBody diff --git a/Signal/src/UserInterface/Strings.swift b/Signal/src/UserInterface/Strings.swift index 60ef70c61..b457b18ba 100644 --- a/Signal/src/UserInterface/Strings.swift +++ b/Signal/src/UserInterface/Strings.swift @@ -13,22 +13,19 @@ import Foundation static let confirmAndCallButtonTitle = NSLocalizedString("SAFETY_NUMBER_CHANGED_CONFIRM_CALL_ACTION", comment: "alert button text to confirm placing an outgoing call after the recipients Safety Number has changed.") + static let callBackAlertTitle = NSLocalizedString("CALL_USER_ALERT_TITLE", comment: "Title for alert offering to call a user.") + static let callBackAlertMessageFormat = NSLocalizedString("CALL_USER_ALERT_MESSAGE_FORMAT", comment: "Message format for alert offering to call a user. Embeds {{the user's display name or phone number}}.") + static let callBackAlertCallButton = NSLocalizedString("CALL_USER_ALERT_CALL_BUTTON", comment: "Label for call button for alert offering to call a user.") + // MARK: Notification actions static let callBackButtonTitle = NSLocalizedString("CALLBACK_BUTTON_TITLE", comment: "notification action") - static let confirmIdentityAndCallBackButtonTitle = NSLocalizedString("CONFIRM_IDENTITY_AND_CALLBACK_BUTTON_TITLE", comment: "notification action, confirming that it's OK to proceed calling after a caller's Safety Number has changed") static let showThreadButtonTitle = NSLocalizedString("SHOW_THREAD_BUTTON_TITLE", comment: "notification action") // MARK: Missed Call Notification - static let missedCallNotificationBody = NSLocalizedString("MISSED_CALL", comment: "notification title") - static let missedCallNotificationBodyWithCallerName = NSLocalizedString("MSGVIEW_MISSED_CALL_WITH_NAME", comment: "notification title. Embeds {{Caller's Name}}") - static let missedCallNotificationBodyWithoutCallerName = NSLocalizedString("MSGVIEW_MISSED_CALL_WITHOUT_NAME", comment: "notification title.") + static let missedCallNotificationBodyWithoutCallerName = NSLocalizedString("MISSED_CALL", comment: "notification title") + static let missedCallNotificationBodyWithCallerName = NSLocalizedString("MSGVIEW_MISSED_CALL_WITH_NAME", comment: "notification title. Embeds {{caller's name or phone number}}") - // MARK: Missed with Unseen identity Notification - static let rejectedCallWithUnseenIdentityChangeNotificationBody = NSLocalizedString("MISSED_CALL_WITH_UNSEEN_IDENTITY_BODY", comment: "notification action") - static let rejectedCallWithUnseenIdentityChangeNotificationBodyWithoutCallerName = NSLocalizedString("MISSED_CALL_WITH_UNSEEN_IDENTITY_BODY_WITHOUT_CALLER_NAME", comment: "notification action") - static let rejectedCallWithUnseenIdentityChangeNotificationBodyWithCallerName = NSLocalizedString("MISSED_CALL_WITH_UNSEEN_IDENTITY_BODY_WITH_CALLER_NAME", comment: "notification action") - - static let callBackAlertTitle = NSLocalizedString("CALL_USER_ALERT_TITLE", comment: "Title for alert offering to call a user.") - static let callBackAlertMessageFormat = NSLocalizedString("CALL_USER_ALERT_MESSAGE_FORMAT", comment: "Message format for alert offering to call a user. Embeds {{the user's display name or phone number}}.") - static let callBackAlertCallButton = NSLocalizedString("CALL_USER_ALERT_CALL_BUTTON", comment: "Label for call button for alert offering to call a user.") + // MARK: Missed with changed identity notification (for not previously verified identity) + static let missedCallWithIdentityChangeNotificationBodyWithoutCallerName = NSLocalizedString("MISSED_CALL_WITH_CHANGED_IDENTITY_BODY_WITHOUT_CALLER_NAME", comment: "notification title") + static let missedCallWithIdentityChangeNotificationBodyWithCallerName = NSLocalizedString("MISSED_CALL_WITH_CHANGED_IDENTITY_BODY_WITH_CALLER_NAME", comment: "notification title. Embeds {{caller's name or phone number}}") } diff --git a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m index 013f09cb6..2983f1d5b 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m @@ -146,8 +146,8 @@ NS_ASSUME_NONNULL_BEGIN dispatch_get_main_queue(), ^{ [[Environment getCurrent].callService.notificationsAdapter - presentRejectedCallWithUnseenIdentityChange:call - callerName:thread.name]; + presentRejectedCallWithIdentityChange:call + callerName:thread.name]; }); }], ]]]; diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index 3d704da66..7d34663ff 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -472,7 +472,7 @@ protocol CallServiceObserver: class { guard OWSIdentityManager.shared().isCurrentIdentityTrustedForSending(toRecipientId: thread.contactIdentifier()) else { let callerName = self.contactsManager.displayName(forPhoneIdentifier: thread.contactIdentifier()) - self.notificationsAdapter.presentRejectedCallWithUnseenIdentityChange(newCall, callerName: callerName) + self.notificationsAdapter.presentRejectedCallWithIdentityChange(newCall, callerName: callerName) return } diff --git a/Signal/src/call/UserInterface/OWSCallNotificationsAdaptee.h b/Signal/src/call/UserInterface/OWSCallNotificationsAdaptee.h index d80a09319..e63f4bb98 100644 --- a/Signal/src/call/UserInterface/OWSCallNotificationsAdaptee.h +++ b/Signal/src/call/UserInterface/OWSCallNotificationsAdaptee.h @@ -12,9 +12,10 @@ NS_ASSUME_NONNULL_BEGIN - (void)presentMissedCall:(SignalCall *)call callerName:(NSString *)callerName; -- (void)presentRejectedCallWithUnseenIdentityChange:(SignalCall *)call - callerName:(NSString *)callerName - NS_SWIFT_NAME(presentRejectedCallWithUnseenIdentityChange(_:callerName:)); +- (void)presentRejectedCallWithIdentityChange:(SignalCall *)call + callerName:(NSString *)callerName + NS_SWIFT_NAME(presentRejectedCallWithIdentityChange(_:callerName +:)); @end diff --git a/Signal/src/environment/NotificationsManager.m b/Signal/src/environment/NotificationsManager.m index 2e72eadbc..040221bb2 100644 --- a/Signal/src/environment/NotificationsManager.m +++ b/Signal/src/environment/NotificationsManager.m @@ -113,13 +113,13 @@ [self presentNotification:notification identifier:localCallId]; } -- (void)presentRejectedCallWithUnseenIdentityChange:(SignalCall *)call callerName:(NSString *)callerName +- (void)presentRejectedCallWithIdentityChange:(SignalCall *)call callerName:(NSString *)callerName { TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:call.remotePhoneNumber]; OWSAssert(thread != nil); UILocalNotification *notification = [UILocalNotification new]; - notification.category = PushManagerCategoriesRejectedCallFromUnseenIdentityChange; + notification.category = PushManagerCategoriesRejectedCallFromIdentityChange; NSString *localCallId = call.localId.UUIDString; notification.userInfo = @{ PushManagerUserInfoKeysLocalCallId : localCallId, @@ -130,17 +130,16 @@ NSString *alertMessage; switch (self.notificationPreviewType) { case NotificationNoNameNoPreview: { - alertMessage = [CallStrings rejectedCallWithUnseenIdentityChangeNotificationBody]; + alertMessage = [CallStrings rejectedCallWithIdentityChangeNotificationBody]; break; } case NotificationNameNoPreview: case NotificationNamePreview: { alertMessage = (([UIDevice currentDevice].supportsCallKit && [[Environment getCurrent].preferences isCallKitPrivacyEnabled]) - ? [CallStrings rejectedCallWithUnseenIdentityChangeNotificationBodyWithoutCallerName] + ? [CallStrings rejectedCallWithIdentityChangeNotificationBodyWithoutCallerName] : [NSString - stringWithFormat:[CallStrings - rejectedCallWithUnseenIdentityChangeNotificationBodyWithCallerName], + stringWithFormat:[CallStrings rejectedCallWithIdentityChangeNotificationBodyWithCallerName], callerName]); break; } diff --git a/Signal/src/network/PushManager.h b/Signal/src/network/PushManager.h index c3a93c33d..bb5fe32ba 100644 --- a/Signal/src/network/PushManager.h +++ b/Signal/src/network/PushManager.h @@ -22,12 +22,12 @@ extern NSString *const Signal_Message_MarkAsRead_Identifier; extern NSString *const PushManagerCategoriesIncomingCall; extern NSString *const PushManagerCategoriesMissedCall; -extern NSString *const PushManagerCategoriesRejectedCallFromUnseenIdentityChange; +extern NSString *const PushManagerCategoriesRejectedCallFromIdentityChange; extern NSString *const PushManagerActionsAcceptCall; extern NSString *const PushManagerActionsDeclineCall; extern NSString *const PushManagerActionsCallBack; -extern NSString *const PushManagerActionsConfirmIdentityAndCallBack; +extern NSString *const PushManagerActionsIgnoreIdentityChangeAndCallBack; extern NSString *const PushManagerActionsShowThread; extern NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId; diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index be5ffd931..390fe79c8 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -209,13 +209,23 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe [self.callUIAdapter startAndShowOutgoingCallWithRecipientId:recipientId]; completionHandler(); - } else if ([identifier isEqualToString:PushManagerActionsConfirmIdentityAndCallBack]) { + } else if ([identifier isEqualToString:PushManagerActionsIgnoreIdentityChangeAndCallBack]) { NSString *recipientId = notification.userInfo[PushManagerUserInfoKeysCallBackSignalRecipientId]; if (!recipientId) { DDLogError(@"%@ missing call back id", self.tag); return; } + NSData *currentIdentityKey = [[OWSIdentityManager sharedManager] identityKeyForRecipientId:recipientId]; + if (currentIdentityKey.length <= 0) { + OWSFail(@"%@ currentIdentityKey unexpectedly empty for recipient: %@", self.tag, recipientId); + completionHandler(); + return; + } + [[OWSIdentityManager sharedManager] setVerificationState:OWSVerificationStateDefault + identityKey:currentIdentityKey + recipientId:recipientId + sendSyncMessage:YES]; [self.callUIAdapter startAndShowOutgoingCallWithRecipientId:recipientId]; completionHandler(); } else if ([identifier isEqualToString:PushManagerActionsShowThread]) { @@ -354,13 +364,14 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe NSString *const PushManagerCategoriesIncomingCall = @"PushManagerCategoriesIncomingCall"; NSString *const PushManagerCategoriesMissedCall = @"PushManagerCategoriesMissedCall"; -NSString *const PushManagerCategoriesRejectedCallFromUnseenIdentityChange = - @"PushManagerCategoriesRejectedCallFromUnseenIdentityChange"; +NSString *const PushManagerCategoriesRejectedCallFromIdentityChange = + @"PushManagerCategoriesRejectedCallFromIdentityChange"; NSString *const PushManagerActionsAcceptCall = @"PushManagerActionsAcceptCall"; NSString *const PushManagerActionsDeclineCall = @"PushManagerActionsDeclineCall"; NSString *const PushManagerActionsCallBack = @"PushManagerActionsCallBack"; -NSString *const PushManagerActionsConfirmIdentityAndCallBack = @"PushManagerActionsConfirmIdentityAndCallBack"; +NSString *const PushManagerActionsIgnoreIdentityChangeAndCallBack = + @"PushManagerActionsIgnoreIdentityChangeAndCallBack"; NSString *const PushManagerActionsShowThread = @"PushManagerActionsShowThread"; NSString *const PushManagerUserInfoKeysLocalCallId = @"PushManagerUserInfoKeysLocalCallId"; @@ -410,7 +421,7 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager - (UIUserNotificationCategory *)signalRejectedCallWithUnseenIdentityChangeCategory { UIMutableUserNotificationAction *confirmAndCallBackAction = [UIMutableUserNotificationAction new]; - confirmAndCallBackAction.identifier = PushManagerActionsConfirmIdentityAndCallBack; + confirmAndCallBackAction.identifier = PushManagerActionsIgnoreIdentityChangeAndCallBack; confirmAndCallBackAction.title = [CallStrings confirmIdentityAndCallBackButtonTitle]; confirmAndCallBackAction.activationMode = UIUserNotificationActivationModeForeground; confirmAndCallBackAction.destructive = NO; @@ -424,7 +435,7 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager showThreadAction.authenticationRequired = YES; UIMutableUserNotificationCategory *rejectedCallCategory = [UIMutableUserNotificationCategory new]; - rejectedCallCategory.identifier = PushManagerCategoriesRejectedCallFromUnseenIdentityChange; + rejectedCallCategory.identifier = PushManagerCategoriesRejectedCallFromIdentityChange; [rejectedCallCategory setActions:@[ confirmAndCallBackAction, showThreadAction ] forContext:UIUserNotificationActionContextMinimal]; [rejectedCallCategory setActions:@[ confirmAndCallBackAction, showThreadAction ] diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index ae0c3bfb3..92b5fdb0c 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -241,9 +241,6 @@ /* No comment provided by engineer. */ "CONFIRM_ACCOUNT_DESTRUCTION_TITLE" = "Are you sure you want to delete your account?"; -/* notification action, confirming that it's OK to proceed calling after a caller's Safety Number has changed */ -"CONFIRM_IDENTITY_AND_CALLBACK_BUTTON_TITLE" = "Confirm and Call Back"; - /* Alert body */ "CONFIRM_LEAVE_GROUP_DESCRIPTION" = "You will no longer be able to send or receive messages in this group."; @@ -745,14 +742,11 @@ /* notification title */ "MISSED_CALL" = "Missed call"; -/* notification action */ -"MISSED_CALL_WITH_UNSEEN_IDENTITY_BODY" = "Missed call because the caller's safety number changed."; - -/* notification action */ -"MISSED_CALL_WITH_UNSEEN_IDENTITY_BODY_WITH_CALLER_NAME" = "Missed call from %@ because their safety number changed."; +/* notification title. Embeds {{caller's name or phone number}} */ +"MISSED_CALL_WITH_CHANGED_IDENTITY_BODY_WITH_CALLER_NAME" = "Missed call because the caller's safety number changed."; -/* notification action */ -"MISSED_CALL_WITH_UNSEEN_IDENTITY_BODY_WITHOUT_CALLER_NAME" = "Missed call because the caller's safety number changed."; +/* notification title */ +"MISSED_CALL_WITH_CHANGED_IDENTITY_BODY_WITHOUT_CALLER_NAME" = "Missed call because the caller's safety number changed."; /* Alert body Alert body when camera is not authorized */ @@ -762,12 +756,9 @@ Alert title when camera is not authorized */ "MISSING_CAMERA_PERMISSION_TITLE" = "Signal needs to access your camera."; -/* notification title. Embeds {{Caller's Name}} */ +/* notification title. Embeds {{caller's name or phone number}} */ "MSGVIEW_MISSED_CALL_WITH_NAME" = "Missed call from %@."; -/* notification title. */ -"MSGVIEW_MISSED_CALL_WITHOUT_NAME" = "Missed call from Signal User."; - /* No comment provided by engineer. */ "MSGVIEW_RECEIVED_CALL" = "You received a call from %@."; @@ -1075,7 +1066,7 @@ /* button title to confirm adding a recipient to a group when their safety number has recently changed */ "SAFETY_NUMBER_CHANGED_CONFIRM_ADD_TO_GROUP_ACTION" = "Add to Group Anyway"; -/* button title to confirm calling a recipient whose safety number recently changed */ +/* alert button text to confirm placing an outgoing call after the recipients Safety Number has changed. */ "SAFETY_NUMBER_CHANGED_CONFIRM_CALL_ACTION" = "Call Anyway"; /* button title to confirm sending to a recipient whose safety number recently changed */ From c8d547a08f5d4a5522d69975491c6f27f0b52aca Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Tue, 6 Jun 2017 18:59:38 -0400 Subject: [PATCH 07/10] Only allow callback for identities that were not previously verified // FREEBIE --- .../CallNotificationsAdapter.swift | 10 +- .../UserNotificationsAdaptee.swift | 48 +++++++--- .../DebugUI/DebugUITableViewController.m | 95 +++++++++++-------- .../SafetyNumberConfirmationAlert.swift | 18 ++-- Signal/src/call/CallService.swift | 16 +++- .../OWSCallNotificationsAdaptee.h | 10 +- Signal/src/environment/NotificationsManager.m | 51 ++++++++-- Signal/src/network/PushManager.h | 3 +- Signal/src/network/PushManager.m | 53 +++-------- .../translations/en.lproj/Localizable.strings | 2 +- 10 files changed, 189 insertions(+), 117 deletions(-) diff --git a/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift b/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift index f6e03dbbf..235592126 100644 --- a/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift +++ b/Signal/src/UserInterface/Notifications/CallNotificationsAdapter.swift @@ -36,8 +36,12 @@ class CallNotificationsAdapter: NSObject { adaptee.presentMissedCall(call, callerName: callerName) } - func presentRejectedCallWithIdentityChange(_ call: SignalCall, callerName: String) { - Logger.debug("\(TAG) in \(#function)") - adaptee.presentRejectedCallWithIdentityChange(call, callerName: callerName) + public func presentMissedCallBecauseOfNoLongerVerifiedIdentity(call: SignalCall, callerName: String) { + adaptee.presentMissedCallBecauseOfNoLongerVerifiedIdentity(call: call, callerName: callerName) + } + + public func presentMissedCallBecauseOfNewIdentity(call: SignalCall, callerName: String) { + adaptee.presentMissedCallBecauseOfNewIdentity(call: call, callerName: callerName) } + } diff --git a/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift b/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift index 66c9a1cbd..0b22c0251 100644 --- a/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift +++ b/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift @@ -14,10 +14,10 @@ import UserNotifications struct AppNotifications { enum Category { case missedCall, - rejectedCallFromUnseenIdentity + missedCallFromNoLongerVerifiedIdentity // Don't forget to update this! We use it to register categories. - static let allValues = [ missedCall, rejectedCallFromUnseenIdentity ] + static let allValues = [ missedCall, missedCallFromNoLongerVerifiedIdentity ] } enum Action { @@ -39,9 +39,9 @@ struct AppNotifications { intentIdentifiers: [], options: []) - case .rejectedCallFromUnseenIdentity: - return UNNotificationCategory(identifier: "org.whispersystems.signal.AppNotifications.Category.rejectedCallFromUnseenIdentity", - actions: [ action(.confirmIdentityAndCallBack), action(.showThread) ], + case .missedCallFromNoLongerVerifiedIdentity: + return UNNotificationCategory(identifier: "org.whispersystems.signal.AppNotifications.Category.missedCallFromNoLongerVerifiedIdentity", + actions: [ action(.showThread) ], intentIdentifiers: [], options: []) } @@ -118,7 +118,7 @@ class UserNotificationsAdaptee: NSObject, OWSCallNotificationsAdaptee, UNUserNot let notificationBody = { () -> String in switch previewType { case .noNameNoPreview: - return CallStrings.missedCallNotificationBody + return CallStrings.missedCallNotificationBodyWithoutCallerName case .nameNoPreview, .namePreview: return (Environment.getCurrent().preferences.isCallKitPrivacyEnabled() ? CallStrings.missedCallNotificationBodyWithoutCallerName @@ -134,7 +134,7 @@ class UserNotificationsAdaptee: NSObject, OWSCallNotificationsAdaptee, UNUserNot center.add(request) } - func presentRejectedCallWithIdentityChange(_ call: SignalCall, callerName: String) { + public func presentMissedCallBecauseOfNoLongerVerifiedIdentity(call: SignalCall, callerName: String) { Logger.debug("\(TAG) \(#function)") let content = UNMutableNotificationContent() @@ -144,16 +144,42 @@ class UserNotificationsAdaptee: NSObject, OWSCallNotificationsAdaptee, UNUserNot let notificationBody = { () -> String in switch previewType { case .noNameNoPreview: - return CallStrings.rejectedCallWithIdentityChangeNotificationBody + return CallStrings.missedCallWithIdentityChangeNotificationBodyWithoutCallerName case .nameNoPreview, .namePreview: return (Environment.getCurrent().preferences.isCallKitPrivacyEnabled() - ? CallStrings.rejectedCallWithIdentityChangeNotificationBodyWithoutCallerName - : String(format: CallStrings.rejectedCallWithIdentityChangeNotificationBodyWithCallerName, callerName)) + ? CallStrings.missedCallWithIdentityChangeNotificationBodyWithoutCallerName + : String(format: CallStrings.missedCallWithIdentityChangeNotificationBodyWithCallerName, callerName)) }}() content.body = notificationBody content.sound = UNNotificationSound.default() - content.categoryIdentifier = AppNotifications.category(.rejectedCallFromUnseenIdentity).identifier + content.categoryIdentifier = AppNotifications.category(.missedCallFromNoLongerVerifiedIdentity).identifier + + let request = UNNotificationRequest.init(identifier: call.localId.uuidString, content: content, trigger: nil) + + center.add(request) + } + + public func presentMissedCallBecauseOfNewIdentity(call: SignalCall, callerName: String) { + Logger.debug("\(TAG) \(#function)") + + let content = UNMutableNotificationContent() + // TODO group by thread identifier + // content.threadIdentifier = threadId + + let notificationBody = { () -> String in + switch previewType { + case .noNameNoPreview: + return CallStrings.missedCallWithIdentityChangeNotificationBodyWithoutCallerName + case .nameNoPreview, .namePreview: + return (Environment.getCurrent().preferences.isCallKitPrivacyEnabled() + ? CallStrings.missedCallWithIdentityChangeNotificationBodyWithoutCallerName + : String(format: CallStrings.missedCallWithIdentityChangeNotificationBodyWithCallerName, callerName)) + }}() + + content.body = notificationBody + content.sound = UNNotificationSound.default() + content.categoryIdentifier = AppNotifications.category(.missedCall).identifier let request = UNNotificationRequest.init(identifier: call.localId.uuidString, content: content, trigger: nil) diff --git a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m index 2983f1d5b..c782078c9 100644 --- a/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m +++ b/Signal/src/ViewControllers/DebugUI/DebugUITableViewController.m @@ -111,46 +111,61 @@ NS_ASSUME_NONNULL_BEGIN // 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 Unseen 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 - presentRejectedCallWithIdentityChange:call - callerName:thread.name]; - }); - }], - ]]]; + 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]; diff --git a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift index bd68df4d8..0836ec4ac 100644 --- a/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift +++ b/Signal/src/ViewControllers/SafetyNumberConfirmationAlert.swift @@ -34,12 +34,12 @@ class SafetyNumberConfirmationAlert: NSObject { */ public func presentIfNecessary(recipientIds: [String], confirmationText: String, completion: @escaping (Bool) -> Void) -> Bool { - guard let noLongerVerifiedIdentity = noLongerVerifiedIdentity(recipientIds: recipientIds) else { + guard let untrustedIdentity = untrustedIdentityForSending(recipientIds: recipientIds) else { // No identities to confirm, no alert to present. return false } - let displayName = contactsManager.displayName(forPhoneIdentifier: noLongerVerifiedIdentity.recipientId) + let displayName = contactsManager.displayName(forPhoneIdentifier: untrustedIdentity.recipientId) let titleFormat = NSLocalizedString("CONFIRM_SENDING_TO_CHANGED_IDENTITY_TITLE_FORMAT", comment: "Action sheet title presented when a users's SN have recently changed. Embeds {{contact's name or phone number}}") @@ -52,10 +52,10 @@ class SafetyNumberConfirmationAlert: NSObject { let actionSheetController = UIAlertController(title: title, message:body, preferredStyle: .actionSheet) let confirmAction = UIAlertAction(title: confirmationText, style: .default) { _ in - Logger.info("\(self.TAG) Confirmed identity: \(noLongerVerifiedIdentity)") + Logger.info("\(self.TAG) Confirmed identity: \(untrustedIdentity)") OWSDispatch.sessionStoreQueue().async { - OWSIdentityManager.shared().setVerificationState(.default, identityKey: noLongerVerifiedIdentity.identityKey, recipientId: noLongerVerifiedIdentity.recipientId, sendSyncMessage: true) + OWSIdentityManager.shared().setVerificationState(.default, identityKey: untrustedIdentity.identityKey, recipientId: untrustedIdentity.recipientId, sendSyncMessage: true) DispatchQueue.main.async { completion(true) } @@ -64,10 +64,10 @@ class SafetyNumberConfirmationAlert: NSObject { actionSheetController.addAction(confirmAction) let showSafetyNumberAction = UIAlertAction(title: NSLocalizedString("VERIFY_PRIVACY", comment: "Action sheet item"), style: .default) { _ in - Logger.info("\(self.TAG) Opted to show Safety Number for identity: \(noLongerVerifiedIdentity)") + Logger.info("\(self.TAG) Opted to show Safety Number for identity: \(untrustedIdentity)") - self.presentSafetyNumberViewController(theirIdentityKey: noLongerVerifiedIdentity.identityKey, - theirRecipientId: noLongerVerifiedIdentity.recipientId, + self.presentSafetyNumberViewController(theirIdentityKey: untrustedIdentity.identityKey, + theirRecipientId: untrustedIdentity.recipientId, theirDisplayName: displayName, completion: { completion(false) }) @@ -92,9 +92,9 @@ class SafetyNumberConfirmationAlert: NSObject { UIApplication.shared.frontmostViewController?.present(fingerprintViewController, animated: true, completion: completion) } - private func noLongerVerifiedIdentity(recipientIds: [String]) -> OWSRecipientIdentity? { + private func untrustedIdentityForSending(recipientIds: [String]) -> OWSRecipientIdentity? { return recipientIds.flatMap { - OWSIdentityManager.shared().noLongerVerifiedIdentity(recipientId: $0) + OWSIdentityManager.shared().untrustedIdentityForSending(toRecipientId: $0) }.first } } diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index 7d34663ff..5ac608eb2 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -470,9 +470,21 @@ protocol CallServiceObserver: class { let newCall = SignalCall.incomingCall(localId: UUID(), remotePhoneNumber: thread.contactIdentifier(), signalingId: callId) - guard OWSIdentityManager.shared().isCurrentIdentityTrustedForSending(toRecipientId: thread.contactIdentifier()) else { + let untrustedIdentity = OWSIdentityManager.shared().untrustedIdentityForSending(toRecipientId: thread.contactIdentifier()) + + guard untrustedIdentity == nil else { let callerName = self.contactsManager.displayName(forPhoneIdentifier: thread.contactIdentifier()) - self.notificationsAdapter.presentRejectedCallWithIdentityChange(newCall, callerName: callerName) + + switch(untrustedIdentity!.verificationState) { + case .verified: + assertionFailure("shouldn't have missed a call due to untrusted identity if the identity is verified") + self.notificationsAdapter.presentMissedCall(newCall, callerName: callerName) + case .default: + self.notificationsAdapter.presentMissedCallBecauseOfNewIdentity(call: newCall, callerName: callerName) + case .noLongerVerified: + self.notificationsAdapter.presentMissedCallBecauseOfNoLongerVerifiedIdentity(call: newCall, callerName: callerName) + } + return } diff --git a/Signal/src/call/UserInterface/OWSCallNotificationsAdaptee.h b/Signal/src/call/UserInterface/OWSCallNotificationsAdaptee.h index e63f4bb98..4e6c12c18 100644 --- a/Signal/src/call/UserInterface/OWSCallNotificationsAdaptee.h +++ b/Signal/src/call/UserInterface/OWSCallNotificationsAdaptee.h @@ -4,6 +4,7 @@ NS_ASSUME_NONNULL_BEGIN +@class OWSRecipientIdentity; @class SignalCall; @protocol OWSCallNotificationsAdaptee @@ -12,10 +13,13 @@ NS_ASSUME_NONNULL_BEGIN - (void)presentMissedCall:(SignalCall *)call callerName:(NSString *)callerName; -- (void)presentRejectedCallWithIdentityChange:(SignalCall *)call +- (void)presentMissedCallBecauseOfNewIdentity:(SignalCall *)call callerName:(NSString *)callerName - NS_SWIFT_NAME(presentRejectedCallWithIdentityChange(_:callerName -:)); + NS_SWIFT_NAME(presentMissedCallBecauseOfNewIdentity(call:callerName:)); + +- (void)presentMissedCallBecauseOfNoLongerVerifiedIdentity:(SignalCall *)call + callerName:(NSString *)callerName + NS_SWIFT_NAME(presentMissedCallBecauseOfNoLongerVerifiedIdentity(call:callerName:)); @end diff --git a/Signal/src/environment/NotificationsManager.m b/Signal/src/environment/NotificationsManager.m index 040221bb2..c3831eb79 100644 --- a/Signal/src/environment/NotificationsManager.m +++ b/Signal/src/environment/NotificationsManager.m @@ -96,7 +96,7 @@ NSString *alertMessage; switch (self.notificationPreviewType) { case NotificationNoNameNoPreview: { - alertMessage = [CallStrings missedCallNotificationBody]; + alertMessage = [CallStrings missedCallNotificationBodyWithoutCallerName]; break; } case NotificationNameNoPreview: @@ -113,13 +113,52 @@ [self presentNotification:notification identifier:localCallId]; } -- (void)presentRejectedCallWithIdentityChange:(SignalCall *)call callerName:(NSString *)callerName + +- (void)presentMissedCallBecauseOfNewIdentity:(SignalCall *)call callerName:(NSString *)callerName +{ + TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:call.remotePhoneNumber]; + OWSAssert(thread != nil); + + UILocalNotification *notification = [UILocalNotification new]; + // Use category which allows call back + notification.category = PushManagerCategoriesMissedCall; + NSString *localCallId = call.localId.UUIDString; + notification.userInfo = @{ + PushManagerUserInfoKeysLocalCallId : localCallId, + PushManagerUserInfoKeysCallBackSignalRecipientId : call.remotePhoneNumber, + Signal_Thread_UserInfo_Key : thread.uniqueId + }; + + NSString *alertMessage; + switch (self.notificationPreviewType) { + case NotificationNoNameNoPreview: { + alertMessage = [CallStrings missedCallWithIdentityChangeNotificationBodyWithoutCallerName]; + break; + } + case NotificationNameNoPreview: + case NotificationNamePreview: { + alertMessage = (([UIDevice currentDevice].supportsCallKit && + [[Environment getCurrent].preferences isCallKitPrivacyEnabled]) + ? [CallStrings missedCallWithIdentityChangeNotificationBodyWithoutCallerName] + : [NSString + stringWithFormat:[CallStrings missedCallWithIdentityChangeNotificationBodyWithCallerName], + callerName]); + break; + } + } + notification.alertBody = [NSString stringWithFormat:@"☎️ %@", alertMessage]; + + [self presentNotification:notification identifier:localCallId]; +} + +- (void)presentMissedCallBecauseOfNoLongerVerifiedIdentity:(SignalCall *)call callerName:(NSString *)callerName { TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:call.remotePhoneNumber]; OWSAssert(thread != nil); UILocalNotification *notification = [UILocalNotification new]; - notification.category = PushManagerCategoriesRejectedCallFromIdentityChange; + // Use category which does not allow call back + notification.category = PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity; NSString *localCallId = call.localId.UUIDString; notification.userInfo = @{ PushManagerUserInfoKeysLocalCallId : localCallId, @@ -130,16 +169,16 @@ NSString *alertMessage; switch (self.notificationPreviewType) { case NotificationNoNameNoPreview: { - alertMessage = [CallStrings rejectedCallWithIdentityChangeNotificationBody]; + alertMessage = [CallStrings missedCallWithIdentityChangeNotificationBodyWithoutCallerName]; break; } case NotificationNameNoPreview: case NotificationNamePreview: { alertMessage = (([UIDevice currentDevice].supportsCallKit && [[Environment getCurrent].preferences isCallKitPrivacyEnabled]) - ? [CallStrings rejectedCallWithIdentityChangeNotificationBodyWithoutCallerName] + ? [CallStrings missedCallWithIdentityChangeNotificationBodyWithoutCallerName] : [NSString - stringWithFormat:[CallStrings rejectedCallWithIdentityChangeNotificationBodyWithCallerName], + stringWithFormat:[CallStrings missedCallWithIdentityChangeNotificationBodyWithCallerName], callerName]); break; } diff --git a/Signal/src/network/PushManager.h b/Signal/src/network/PushManager.h index bb5fe32ba..c319a3980 100644 --- a/Signal/src/network/PushManager.h +++ b/Signal/src/network/PushManager.h @@ -22,12 +22,11 @@ extern NSString *const Signal_Message_MarkAsRead_Identifier; extern NSString *const PushManagerCategoriesIncomingCall; extern NSString *const PushManagerCategoriesMissedCall; -extern NSString *const PushManagerCategoriesRejectedCallFromIdentityChange; +extern NSString *const PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity; extern NSString *const PushManagerActionsAcceptCall; extern NSString *const PushManagerActionsDeclineCall; extern NSString *const PushManagerActionsCallBack; -extern NSString *const PushManagerActionsIgnoreIdentityChangeAndCallBack; extern NSString *const PushManagerActionsShowThread; extern NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId; diff --git a/Signal/src/network/PushManager.m b/Signal/src/network/PushManager.m index 390fe79c8..cdcbfb818 100644 --- a/Signal/src/network/PushManager.m +++ b/Signal/src/network/PushManager.m @@ -209,25 +209,6 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe [self.callUIAdapter startAndShowOutgoingCallWithRecipientId:recipientId]; completionHandler(); - } else if ([identifier isEqualToString:PushManagerActionsIgnoreIdentityChangeAndCallBack]) { - NSString *recipientId = notification.userInfo[PushManagerUserInfoKeysCallBackSignalRecipientId]; - if (!recipientId) { - DDLogError(@"%@ missing call back id", self.tag); - return; - } - - NSData *currentIdentityKey = [[OWSIdentityManager sharedManager] identityKeyForRecipientId:recipientId]; - if (currentIdentityKey.length <= 0) { - OWSFail(@"%@ currentIdentityKey unexpectedly empty for recipient: %@", self.tag, recipientId); - completionHandler(); - return; - } - [[OWSIdentityManager sharedManager] setVerificationState:OWSVerificationStateDefault - identityKey:currentIdentityKey - recipientId:recipientId - sendSyncMessage:YES]; - [self.callUIAdapter startAndShowOutgoingCallWithRecipientId:recipientId]; - completionHandler(); } else if ([identifier isEqualToString:PushManagerActionsShowThread]) { NSString *threadId = notification.userInfo[Signal_Thread_UserInfo_Key]; [Environment messageThreadId:threadId]; @@ -364,8 +345,8 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe NSString *const PushManagerCategoriesIncomingCall = @"PushManagerCategoriesIncomingCall"; NSString *const PushManagerCategoriesMissedCall = @"PushManagerCategoriesMissedCall"; -NSString *const PushManagerCategoriesRejectedCallFromIdentityChange = - @"PushManagerCategoriesRejectedCallFromIdentityChange"; +NSString *const PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity = + @"PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity"; NSString *const PushManagerActionsAcceptCall = @"PushManagerActionsAcceptCall"; NSString *const PushManagerActionsDeclineCall = @"PushManagerActionsDeclineCall"; @@ -418,14 +399,8 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager return missedCallCategory; } -- (UIUserNotificationCategory *)signalRejectedCallWithUnseenIdentityChangeCategory +- (UIUserNotificationCategory *)signalMissedCallWithNoLongerVerifiedIdentityChangeCategory { - UIMutableUserNotificationAction *confirmAndCallBackAction = [UIMutableUserNotificationAction new]; - confirmAndCallBackAction.identifier = PushManagerActionsIgnoreIdentityChangeAndCallBack; - confirmAndCallBackAction.title = [CallStrings confirmIdentityAndCallBackButtonTitle]; - confirmAndCallBackAction.activationMode = UIUserNotificationActivationModeForeground; - confirmAndCallBackAction.destructive = NO; - confirmAndCallBackAction.authenticationRequired = YES; UIMutableUserNotificationAction *showThreadAction = [UIMutableUserNotificationAction new]; showThreadAction.identifier = PushManagerActionsShowThread; @@ -435,11 +410,9 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager showThreadAction.authenticationRequired = YES; UIMutableUserNotificationCategory *rejectedCallCategory = [UIMutableUserNotificationCategory new]; - rejectedCallCategory.identifier = PushManagerCategoriesRejectedCallFromIdentityChange; - [rejectedCallCategory setActions:@[ confirmAndCallBackAction, showThreadAction ] - forContext:UIUserNotificationActionContextMinimal]; - [rejectedCallCategory setActions:@[ confirmAndCallBackAction, showThreadAction ] - forContext:UIUserNotificationActionContextDefault]; + rejectedCallCategory.identifier = PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity; + [rejectedCallCategory setActions:@[ showThreadAction ] forContext:UIUserNotificationActionContextMinimal]; + [rejectedCallCategory setActions:@[ showThreadAction ] forContext:UIUserNotificationActionContextDefault]; return rejectedCallCategory; } @@ -460,13 +433,13 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager - (void)validateUserNotificationSettings { - UIUserNotificationSettings *settings = - [UIUserNotificationSettings settingsForTypes:(UIUserNotificationType)[self allNotificationTypes] - categories:[NSSet setWithObjects:[self fullNewMessageNotificationCategory], - [self signalIncomingCallCategory], - [self signalMissedCallCategory], - [self signalRejectedCallWithUnseenIdentityChangeCategory], - nil]]; + UIUserNotificationSettings *settings = [UIUserNotificationSettings + settingsForTypes:(UIUserNotificationType)[self allNotificationTypes] + categories:[NSSet setWithObjects:[self fullNewMessageNotificationCategory], + [self signalIncomingCallCategory], + [self signalMissedCallCategory], + [self signalMissedCallWithNoLongerVerifiedIdentityChangeCategory], + nil]]; [UIApplication.sharedApplication registerUserNotificationSettings:settings]; } diff --git a/Signal/translations/en.lproj/Localizable.strings b/Signal/translations/en.lproj/Localizable.strings index 92b5fdb0c..08c90eec1 100644 --- a/Signal/translations/en.lproj/Localizable.strings +++ b/Signal/translations/en.lproj/Localizable.strings @@ -743,7 +743,7 @@ "MISSED_CALL" = "Missed call"; /* notification title. Embeds {{caller's name or phone number}} */ -"MISSED_CALL_WITH_CHANGED_IDENTITY_BODY_WITH_CALLER_NAME" = "Missed call because the caller's safety number changed."; +"MISSED_CALL_WITH_CHANGED_IDENTITY_BODY_WITH_CALLER_NAME" = "Missed call from %@ because their safety number changed."; /* notification title */ "MISSED_CALL_WITH_CHANGED_IDENTITY_BODY_WITHOUT_CALLER_NAME" = "Missed call because the caller's safety number changed."; From f74c3a0e87b93e87065ad9e0f484ea4caddb066a Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 7 Jun 2017 08:53:10 -0400 Subject: [PATCH 08/10] remove unused code // FREEBIE --- .../Notifications/UserNotificationsAdaptee.swift | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift b/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift index 0b22c0251..764bb8552 100644 --- a/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift +++ b/Signal/src/UserInterface/Notifications/UserNotificationsAdaptee.swift @@ -22,8 +22,7 @@ struct AppNotifications { enum Action { case callBack, - showThread, - confirmIdentityAndCallBack + showThread } static var allCategories: Set { @@ -57,10 +56,6 @@ struct AppNotifications { return UNNotificationAction(identifier: "org.whispersystems.signal.AppNotifications.Action.showThread", title: CallStrings.showThreadButtonTitle, options: .authenticationRequired) - case .confirmIdentityAndCallBack: - return UNNotificationAction(identifier: "org.whispersystems.signal.AppNotifications.Action.confirmIdentityAndCallBack", - title: CallStrings.confirmIdentityAndCallBackButtonTitle, - options: .authenticationRequired) } } } From 8c592a373ad1ff7857b6539e582935a3bf50b5d3 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 7 Jun 2017 10:12:01 -0400 Subject: [PATCH 09/10] log error on assertion failure // FREEBIE --- Signal/src/call/CallService.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Signal/src/call/CallService.swift b/Signal/src/call/CallService.swift index 5ac608eb2..9cb75a79c 100644 --- a/Signal/src/call/CallService.swift +++ b/Signal/src/call/CallService.swift @@ -477,6 +477,7 @@ protocol CallServiceObserver: class { switch(untrustedIdentity!.verificationState) { case .verified: + Logger.error("\(TAG) shouldn't have missed a call due to untrusted identity if the identity is verified") assertionFailure("shouldn't have missed a call due to untrusted identity if the identity is verified") self.notificationsAdapter.presentMissedCall(newCall, callerName: callerName) case .default: From 269297716860473300a6a97ece7bf22b29bc935f Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 7 Jun 2017 10:15:53 -0400 Subject: [PATCH 10/10] [SSK] New identity manager // FREEBIE --- Podfile | 8 ++++---- Podfile.lock | 16 +++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Podfile b/Podfile index 4de5fa3a0..55d7dcd08 100644 --- a/Podfile +++ b/Podfile @@ -3,10 +3,10 @@ source 'https://github.com/CocoaPods/Specs.git' target 'Signal' do pod 'SocketRocket', :git => 'https://github.com/facebook/SocketRocket.git' - #pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git' - pod 'AxolotlKit', path: '../SignalProtocolKit' - #pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git' - pod 'SignalServiceKit', path: '../SignalServiceKit' + pod 'AxolotlKit', git: 'https://github.com/WhisperSystems/SignalProtocolKit.git' + #pod 'AxolotlKit', path: '../SignalProtocolKit' + pod 'SignalServiceKit', git: 'https://github.com/WhisperSystems/SignalServiceKit.git' + #pod 'SignalServiceKit', path: '../SignalServiceKit' pod 'OpenSSL' pod 'JSQMessagesViewController', git: 'https://github.com/WhisperSystems/JSQMessagesViewController.git', branch: 'mkirk/position-edit-menu' #pod 'JSQMessagesViewController' path: '../JSQMessagesViewController' diff --git a/Podfile.lock b/Podfile.lock index e4127585b..e421ac97e 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -109,29 +109,35 @@ PODS: - YapDatabase/SQLCipher/Core DEPENDENCIES: - - AxolotlKit (from `../SignalProtocolKit`) + - AxolotlKit (from `https://github.com/WhisperSystems/SignalProtocolKit.git`) - JSQMessagesViewController (from `https://github.com/WhisperSystems/JSQMessagesViewController.git`, branch `mkirk/position-edit-menu`) - OpenSSL - PureLayout - Reachability - - SignalServiceKit (from `../SignalServiceKit`) + - SignalServiceKit (from `https://github.com/WhisperSystems/SignalServiceKit.git`) - SocketRocket (from `https://github.com/facebook/SocketRocket.git`) EXTERNAL SOURCES: AxolotlKit: - :path: ../SignalProtocolKit + :git: https://github.com/WhisperSystems/SignalProtocolKit.git JSQMessagesViewController: :branch: mkirk/position-edit-menu :git: https://github.com/WhisperSystems/JSQMessagesViewController.git SignalServiceKit: - :path: ../SignalServiceKit + :git: https://github.com/WhisperSystems/SignalServiceKit.git SocketRocket: :git: https://github.com/facebook/SocketRocket.git CHECKOUT OPTIONS: + AxolotlKit: + :commit: 9179d4e326df58185f35af45831e7a5d7250ab85 + :git: https://github.com/WhisperSystems/SignalProtocolKit.git JSQMessagesViewController: :commit: 7054e4b13ee5bcd6d524adb6dc9a726e8c466308 :git: https://github.com/WhisperSystems/JSQMessagesViewController.git + SignalServiceKit: + :commit: d475c58348a0a8c4ed9b0fcdbe352cd87e8ce269 + :git: https://github.com/WhisperSystems/SignalServiceKit.git SocketRocket: :commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf :git: https://github.com/facebook/SocketRocket.git @@ -158,6 +164,6 @@ SPEC CHECKSUMS: UnionFind: c33be5adb12983981d6e827ea94fc7f9e370f52d YapDatabase: cd911121580ff16675f65ad742a9eb0ab4d9e266 -PODFILE CHECKSUM: dc5ed308ade575a81ccadf5c485990530353c4ee +PODFILE CHECKSUM: 48e80d7f1e049bbf544a689fdfdf33e8196c640a COCOAPODS: 1.2.1