show SN confirmation before adding to group

* Extract SN confirmation dialog

// FREEBIE
This commit is contained in:
Michael Kirk 2017-05-26 18:19:46 -07:00
parent 2d7f03a1c8
commit 9a2f218bf3
11 changed files with 297 additions and 154 deletions

View file

@ -143,6 +143,7 @@
45855F381D9498A40084F340 /* OWSContactAvatarBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 45855F361D9498A40084F340 /* OWSContactAvatarBuilder.m */; };
4585C4601ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m in Sources */ = {isa = PBXBuildFile; fileRef = 4585C45F1ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m */; };
4585C4661ED5DF7A00896AEA /* ProfileFetcherJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4585C4651ED5DF7A00896AEA /* ProfileFetcherJob.swift */; };
4585C4681ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4585C4671ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift */; };
458967111DC117CC00E9DD21 /* AccountManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 458967101DC117CC00E9DD21 /* AccountManagerTest.swift */; };
458DE9D61DEE3FD00071BB03 /* PeerConnectionClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 458DE9D51DEE3FD00071BB03 /* PeerConnectionClient.swift */; };
458DE9D91DEE7B360071BB03 /* OWSWebRTCDataProtos.pb.m in Sources */ = {isa = PBXBuildFile; fileRef = 458DE9D81DEE7B360071BB03 /* OWSWebRTCDataProtos.pb.m */; };
@ -559,6 +560,7 @@
4585C45E1ED4FD0400896AEA /* OWS104CreateRecipientIdentities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWS104CreateRecipientIdentities.h; path = Migrations/OWS104CreateRecipientIdentities.h; sourceTree = "<group>"; };
4585C45F1ED4FD0400896AEA /* OWS104CreateRecipientIdentities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWS104CreateRecipientIdentities.m; path = Migrations/OWS104CreateRecipientIdentities.m; sourceTree = "<group>"; };
4585C4651ED5DF7A00896AEA /* ProfileFetcherJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProfileFetcherJob.swift; sourceTree = "<group>"; };
4585C4671ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SafetyNumberConfirmationAlert.swift; sourceTree = "<group>"; };
4589670F1DC117CC00E9DD21 /* SignalTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SignalTests-Bridging-Header.h"; sourceTree = "<group>"; };
458967101DC117CC00E9DD21 /* AccountManagerTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AccountManagerTest.swift; path = Models/AccountManagerTest.swift; sourceTree = "<group>"; };
458DE9D51DEE3FD00071BB03 /* PeerConnectionClient.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PeerConnectionClient.swift; sourceTree = "<group>"; };
@ -976,6 +978,7 @@
340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */,
34B3F8A01E8EA6040035BE1A /* ViewControllerUtils.h */,
34B3F8A11E8EA6040035BE1A /* ViewControllerUtils.m */,
4585C4671ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift */,
);
path = ViewControllers;
sourceTree = "<group>";
@ -2071,6 +2074,7 @@
EF764C351DB67CC5000D9A87 /* UIViewController+CameraPermissions.m in Sources */,
45CD81EF1DC030E7004C9430 /* AccountManager.swift in Sources */,
45794E861E00620000066731 /* CallUIAdapter.swift in Sources */,
4585C4681ED8F8D200896AEA /* SafetyNumberConfirmationAlert.swift in Sources */,
FCFA64B71A24F6730007FB87 /* UIFont+OWS.m in Sources */,
B6B9ECFC198B31BA00C620D3 /* PushManager.m in Sources */,
45DF5DF21DDB843F00C936C7 /* CompareSafetyNumbersActivity.swift in Sources */,

View file

@ -7,6 +7,7 @@
#import "AttachmentSharing.h"
#import "Environment.h"
#import "FLAnimatedImage.h"
#import "FingerprintViewController.h"
#import "NotificationsManager.h"
#import "OWSAnyTouchGestureRecognizer.h"
#import "OWSAudioAttachmentPlayer.h"
@ -56,6 +57,8 @@
#import <SignalServiceKit/OWSMessageSender.h>
#import <SignalServiceKit/OWSOutgoingCallMessage.h>
#import <SignalServiceKit/OWSRecipientIdentity.h>
#import <SignalServiceKit/OWSFingerprintBuilder.h>
#import <SignalServiceKit/OWSFingerprint.h>
#import <SignalServiceKit/OWSSignalService.h>
#import <SignalServiceKit/OWSTurnServerInfoRequest.h>
#import <SignalServiceKit/PhoneNumber.h>

View file

@ -12,4 +12,8 @@ extension UIStoryboard {
class var main: UIStoryboard {
return UIStoryboard(name: StoryboardName.main.rawValue, bundle: Bundle.main)
}
class func instantiateFingerprintViewController() -> FingerprintViewController {
return self.main.instantiateViewController(withIdentifier: "FingerprintViewController") as! FingerprintViewController
}
}

View file

@ -6,6 +6,7 @@
#import "BlockListUIUtils.h"
#import "ContactsViewHelper.h"
#import "OWSContactsManager.h"
#import "Signal-Swift.h"
#import <SignalServiceKit/SignalAccount.h>
NS_ASSUME_NONNULL_BEGIN
@ -50,6 +51,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(phoneNumber.length > 0);
__weak AddToGroupViewController *weakSelf = self;
ContactsViewHelper *helper = self.contactsViewHelper;
if ([helper isRecipientIdBlocked:phoneNumber]) {
[BlockListUIUtils showUnblockPhoneNumberActionSheet:phoneNumber
@ -61,9 +63,27 @@ NS_ASSUME_NONNULL_BEGIN
[weakSelf addToGroup:phoneNumber];
}
}];
} else {
[self addToGroup:phoneNumber];
return;
}
BOOL didShowSNAlert = [SafetyNumberConfirmationAlert
presentAlertIfNecessaryFromViewController:self
recipientId:phoneNumber
confirmationText:
NSLocalizedString(@"SAFETY_NUMBER_CHANGED_CONFIRM_ADD_TO_GROUP_ACTION",
@"button title to confirm adding a recipient to a group when their safety "
@"number has recently changed")
contactsManager:helper.contactsManager
completion:^(BOOL didConfirmIdentity) {
if (didConfirmIdentity) {
[weakSelf addToGroup:phoneNumber];
}
}];
if (didShowSNAlert) {
return;
}
[self addToGroup:phoneNumber];
}
- (BOOL)canSignalAccountBeSelected:(SignalAccount *)signalAccount
@ -83,7 +103,9 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(0);
return;
} else if ([helper isRecipientIdBlocked:signalAccount.recipientId]) {
}
if ([helper isRecipientIdBlocked:signalAccount.recipientId]) {
[BlockListUIUtils showUnblockSignalAccountActionSheet:signalAccount
fromViewController:self
blockingManager:helper.blockingManager
@ -93,9 +115,27 @@ NS_ASSUME_NONNULL_BEGIN
[weakSelf addToGroup:signalAccount.recipientId];
}
}];
} else {
[self addToGroup:signalAccount.recipientId];
return;
}
BOOL didShowSNAlert = [SafetyNumberConfirmationAlert
presentAlertIfNecessaryFromViewController:self
recipientId:signalAccount.recipientId
confirmationText:
NSLocalizedString(@"SAFETY_NUMBER_CHANGED_CONFIRM_ADD_TO_GROUP_ACTION",
@"button title to confirm adding a recipient to a group when their safety "
@"number has recently changed")
contactsManager:helper.contactsManager
completion:^(BOOL didConfirmIdentity) {
if (didConfirmIdentity) {
[weakSelf addToGroup:signalAccount.recipientId];
}
}];
if (didShowSNAlert) {
return;
}
[self addToGroup:signalAccount.recipientId];
}
- (void)addToGroup:(NSString *)recipientId

View file

@ -1,16 +1,11 @@
//
// FingerprintViewController.h
// Signal
//
// Created by Dylan Bourgeois on 02/11/14.
// Copyright (c) 2014 Open Whisper Systems. All rights reserved.
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSQRCodeScanningViewController.h"
NS_ASSUME_NONNULL_BEGIN
@class TSThread;
@class OWSFingerprint;
@class OWSConversationSettingsTableViewController;
@ -18,9 +13,8 @@ NS_ASSUME_NONNULL_BEGIN
@property (nullable) OWSConversationSettingsTableViewController *dismissDelegate;
- (void)configureWithThread:(TSThread *)thread
fingerprint:(OWSFingerprint *)fingerprint
contactName:(NSString *)contactName;
- (void)configureWithFingerprint:(OWSFingerprint *)fingerprint
contactName:(NSString *)contactName NS_SWIFT_NAME(configure(fingerprint:contactName:));
- (void)controller:(OWSQRCodeScanningViewController *)controller didDetectQRCodeWithData:(NSData *)data;

View file

@ -15,14 +15,12 @@
#import <SignalServiceKit/TSStorageManager+IdentityKeyStore.h>
#import <SignalServiceKit/TSStorageManager+SessionStore.h>
#import <SignalServiceKit/TSStorageManager+keyingMaterial.h>
#import <SignalServiceKit/TSThread.h>
NS_ASSUME_NONNULL_BEGIN
@interface FingerprintViewController () <OWSHighlightableLabelDelegate, OWSCompareSafetyNumbersActivityDelegate>
@property (strong, nonatomic) TSStorageManager *storageManager;
@property (strong, nonatomic) TSThread *thread;
@property (strong, nonatomic) OWSFingerprint *fingerprint;
@property (strong, nonatomic) NSString *contactName;
@property (strong, nonatomic) OWSQRCodeScanningViewController *qrScanningController;
@ -45,11 +43,9 @@ NS_ASSUME_NONNULL_BEGIN
@implementation FingerprintViewController
- (void)configureWithThread:(TSThread *)thread
fingerprint:(OWSFingerprint *)fingerprint
contactName:(NSString *)contactName
- (void)configureWithFingerprint:(OWSFingerprint *)fingerprint
contactName:(NSString *)contactName
{
self.thread = thread;
self.fingerprint = fingerprint;
self.contactName = contactName;
}

View file

@ -1567,75 +1567,20 @@ typedef enum : NSUInteger {
#pragma mark - Identity
/**
* Returns the first unconfirmed recipient identity in the thread.
* Shows confirmation dialog if at least one of the recipient id's is not confirmed.
*
* returns YES if an alert was shown
* NO if there were no unconfirmed identities
*/
- (nullable OWSRecipientIdentity *)unconfirmedIdentityThatShouldBlockSending
- (BOOL)showSafetyNumberConfirmationIfNecessaryWithConfirmationText:(NSString *)confirmationText
completion:
(void (^)(BOOL didConfirmedIdentity))completionHandler
{
for (NSString *recipientId in self.thread.recipientIdentifiers) {
OWSRecipientIdentity *unconfirmedIdentity =
[self.storageManager unconfirmedIdentityThatShouldBlockSendingForRecipientId:recipientId];
if (unconfirmedIdentity != nil) {
DDLogInfo(@"%@ unconfirmedIdentityThatShouldBlockSending: %@", self.tag, recipientId);
return unconfirmedIdentity;
}
}
return nil;
}
- (void)showConfirmIdentityUIForRecipientIdentity:(OWSRecipientIdentity *)recipientIdentity
confirmationText:(NSString *)confirmationText
completion:(void (^)(BOOL didConfirmedIdentity))completionHandler
{
NSString *displayName = [self.contactsManager displayNameForPhoneIdentifier:recipientIdentity.recipientId];
NSString *titleFormat = NSLocalizedString(@"CONFIRM_SENDING_TO_CHANGED_IDENTITY_TITLE_FORMAT",
@"Action sheet title presented when a users's SN have recently changed. Embeds {{contact's name or phone "
@"number}}");
NSString *title = [NSString stringWithFormat:titleFormat, displayName];
NSString *bodyFormat = NSLocalizedString(@"CONFIRM_SENDING_TO_CHANGED_IDENTITY_BODY_FORMAT",
@"Action sheet body presented when a users's SN have recently changed. Embeds {{contact's name or phone "
@"number}}");
NSString *body = [NSString stringWithFormat:bodyFormat, displayName];
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:title
message:body
preferredStyle:UIAlertControllerStyleActionSheet];
[actionSheet
addAction:[UIAlertAction
actionWithTitle:confirmationText
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
DDLogInfo(@"%@ Confirmed sending identity: %@", self.tag, recipientIdentity);
dispatch_async([OWSDispatch sessionStoreQueue], ^{
[[TSStorageManager sharedManager] saveRemoteIdentity:recipientIdentity.identityKey
recipientId:recipientIdentity.recipientId
approvedForBlockingUse:YES
approvedForNonBlockingUse:YES];
dispatch_async(dispatch_get_main_queue(), ^{
completionHandler(YES);
});
});
}]];
[actionSheet addAction:[UIAlertAction
actionWithTitle:NSLocalizedString(@"VERIFY_PRIVACY", @"Action sheet item")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
DDLogInfo(@"%@ verifying sending identity: %@", self.tag, recipientIdentity);
[self showFingerprintWithTheirIdentityKey:recipientIdentity.identityKey
theirSignalId:recipientIdentity.recipientId];
completionHandler(NO);
}]];
[actionSheet addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", nil)
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *_Nonnull action) {
completionHandler(NO);
}]];
[self presentViewController:actionSheet animated:YES completion:nil];
return [SafetyNumberConfirmationAlert presentAlertIfNecessaryFromViewController:self
recipientIds:self.thread.recipientIdentifiers
confirmationText:confirmationText
contactsManager:self.contactsManager
completion:completionHandler];
}
- (void)showFingerprintWithTheirIdentityKey:(NSData *)theirIdentityKey theirSignalId:(NSString *)theirSignalId
@ -1663,7 +1608,7 @@ typedef enum : NSUInteger {
}
FingerprintViewController *fingerprintViewController = (FingerprintViewController *)viewController;
[fingerprintViewController configureWithThread:self.thread fingerprint:fingerprint contactName:contactName];
[fingerprintViewController configureWithFingerprint:fingerprint contactName:contactName];
[self presentViewController:fingerprintViewController animated:YES completion:nil];
}
@ -1677,8 +1622,8 @@ typedef enum : NSUInteger {
return;
}
__weak MessagesViewController *weakSelf = self;
if ([self isBlockedContactConversation]) {
__weak MessagesViewController *weakSelf = self;
[self showUnblockContactUI:^(BOOL isBlocked) {
if (!isBlocked) {
[weakSelf callAction:nil];
@ -1687,18 +1632,16 @@ typedef enum : NSUInteger {
return;
}
OWSRecipientIdentity *unconfirmedIdentityThatShouldBlockSending = [self unconfirmedIdentityThatShouldBlockSending];
if (unconfirmedIdentityThatShouldBlockSending != nil) {
__weak MessagesViewController *weakSelf = self;
[self showConfirmIdentityUIForRecipientIdentity:unconfirmedIdentityThatShouldBlockSending
confirmationText:NSLocalizedString(@"SAFETY_NUMBER_CHANGED_CONFIRM_CALL_ACTION",
@"button title to confirm calling a recipient whose safety "
@"number recently changed")
completion:^(BOOL didConfirmedIdentity) {
if (didConfirmedIdentity) {
[weakSelf callAction:sender];
}
}];
BOOL didShowSNAlert = [self showSafetyNumberConfirmationIfNecessaryWithConfirmationText:
NSLocalizedString(@"SAFETY_NUMBER_CHANGED_CONFIRM_CALL_ACTION",
@"button title to confirm calling a recipient whose safety "
@"number recently changed")
completion:^(BOOL didConfirmIdentity) {
if (didConfirmIdentity) {
[weakSelf callAction:sender];
}
}];
if (didShowSNAlert) {
return;
}
@ -1732,8 +1675,9 @@ typedef enum : NSUInteger {
date:(NSDate *)date
updateKeyboardState:(BOOL)updateKeyboardState
{
__weak MessagesViewController *weakSelf = self;
if ([self isBlockedContactConversation]) {
__weak MessagesViewController *weakSelf = self;
[self showUnblockContactUI:^(BOOL isBlocked) {
if (!isBlocked) {
[weakSelf didPressSendButton:button
@ -1747,23 +1691,22 @@ typedef enum : NSUInteger {
return;
}
OWSRecipientIdentity *unconfirmedIdentityThatShouldBlockSending = [self unconfirmedIdentityThatShouldBlockSending];
if (unconfirmedIdentityThatShouldBlockSending != nil) {
__weak MessagesViewController *weakSelf = self;
[self showConfirmIdentityUIForRecipientIdentity:unconfirmedIdentityThatShouldBlockSending
confirmationText:NSLocalizedString(@"SAFETY_NUMBER_CHANGED_CONFIRM_SEND_ACTION",
@"button title to confirm sending to a recipient whose "
@"safety number recently changed")
completion:^(BOOL didConfirmedIdentity) {
if (didConfirmedIdentity) {
[weakSelf didPressSendButton:button
withMessageText:text
senderId:senderId
senderDisplayName:senderDisplayName
date:date
updateKeyboardState:NO];
}
}];
BOOL didShowSNAlert =
[self showSafetyNumberConfirmationIfNecessaryWithConfirmationText:
NSLocalizedString(@"SAFETY_NUMBER_CHANGED_CONFIRM_SEND_ACTION",
@"button title to confirm sending to a recipient whose "
@"safety number recently changed")
completion:^(BOOL didConfirmIdentity) {
if (didConfirmIdentity) {
[weakSelf didPressSendButton:button
withMessageText:text
senderId:senderId
senderDisplayName:senderDisplayName
date:date
updateKeyboardState:NO];
}
}];
if (didShowSNAlert) {
return;
}
@ -2757,7 +2700,7 @@ typedef enum : NSUInteger {
[[UIStoryboard main] instantiateViewControllerWithIdentifier:@"FingerprintViewController"];
NSString *contactName = [self.contactsManager displayNameForPhoneIdentifier:signalId];
[fingerprintViewController configureWithThread:self.thread fingerprint:fingerprint contactName:contactName];
[fingerprintViewController configureWithFingerprint:fingerprint contactName:contactName];
[self presentViewController:fingerprintViewController animated:YES completion:nil];
}
@ -3695,8 +3638,8 @@ typedef enum : NSUInteger {
- (void)didPressAccessoryButton:(UIButton *)sender {
__weak MessagesViewController *weakSelf = self;
if ([self isBlockedContactConversation]) {
__weak MessagesViewController *weakSelf = self;
[self showUnblockContactUI:^(BOOL isBlocked) {
if (!isBlocked) {
[weakSelf didPressAccessoryButton:nil];
@ -3705,20 +3648,19 @@ typedef enum : NSUInteger {
return;
}
OWSRecipientIdentity *unconfirmedIdentityThatShouldBlockSending = [self unconfirmedIdentityThatShouldBlockSending];
if (unconfirmedIdentityThatShouldBlockSending != nil) {
__weak MessagesViewController *weakSelf = self;
[self showConfirmIdentityUIForRecipientIdentity:unconfirmedIdentityThatShouldBlockSending
confirmationText:NSLocalizedString(@"CONFIRMATION_TITLE",
@"Generic button text to proceed with an action")
completion:^(BOOL didConfirmedIdentity) {
if (didConfirmedIdentity) {
[weakSelf didPressAccessoryButton:nil];
}
}];
BOOL didShowSNAlert =
[self showSafetyNumberConfirmationIfNecessaryWithConfirmationText:
NSLocalizedString(@"CONFIRMATION_TITLE", @"Generic button text to proceed with an action")
completion:^(BOOL didConfirmIdentity) {
if (didConfirmIdentity) {
[weakSelf didPressAccessoryButton:nil];
}
}];
if (didShowSNAlert) {
return;
}
UIAlertController *actionSheetController = [UIAlertController alertControllerWithTitle:nil
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
@ -3949,8 +3891,8 @@ typedef enum : NSUInteger {
DDLogError(@"%@ %s", self.tag, __PRETTY_FUNCTION__);
DispatchMainThreadSafe(^{
__weak MessagesViewController *weakSelf = self;
if ([self isBlockedContactConversation]) {
__weak MessagesViewController *weakSelf = self;
[self showUnblockContactUI:^(BOOL isBlocked) {
if (!isBlocked) {
[weakSelf tryToSendAttachmentIfApproved:attachment];
@ -3959,20 +3901,18 @@ typedef enum : NSUInteger {
return;
}
OWSRecipientIdentity *unconfirmedIdentityThatShouldBlockSending =
[self unconfirmedIdentityThatShouldBlockSending];
if (unconfirmedIdentityThatShouldBlockSending != nil) {
__weak MessagesViewController *weakSelf = self;
[self showConfirmIdentityUIForRecipientIdentity:unconfirmedIdentityThatShouldBlockSending
confirmationText:NSLocalizedString(
@"SAFETY_NUMBER_CHANGED_CONFIRM_SEND_ACTION",
@"button title to confirm sending to a recipient whose "
@"safety number recently changed")
completion:^(BOOL didConfirmedIdentity) {
if (didConfirmedIdentity) {
[weakSelf tryToSendAttachmentIfApproved:attachment];
}
}];
BOOL didShowSNAlert = [self
showSafetyNumberConfirmationIfNecessaryWithConfirmationText:
NSLocalizedString(@"SAFETY_NUMBER_CHANGED_CONFIRM_SEND_ACTION",
@"button title to confirm sending to a recipient whose "
@"safety number recently changed")
completion:^(BOOL didConfirmIdentity) {
if (didConfirmIdentity) {
[weakSelf
tryToSendAttachmentIfApproved:attachment];
}
}];
if (didShowSNAlert) {
return;
}
@ -3985,7 +3925,6 @@ typedef enum : NSUInteger {
} else if (skipApprovalDialog) {
[self sendMessageAttachment:attachment];
} else {
__weak MessagesViewController *weakSelf = self;
UIViewController *viewController =
[[AttachmentApprovalViewController alloc] initWithAttachment:attachment
successCompletion:^{

View file

@ -250,6 +250,28 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
}
}];
} else {
BOOL didShowSNAlert = [SafetyNumberConfirmationAlert
presentAlertIfNecessaryFromViewController:self
recipientId:recipientId
confirmationText:NSLocalizedString(
@"SAFETY_NUMBER_CHANGED_CONFIRM_"
@"ADD_TO_GROUP_ACTION",
@"button title to confirm adding "
@"a recipient to a group when "
@"their safety "
@"number has recently changed")
contactsManager:contactsViewHelper.contactsManager
completion:^(BOOL didConfirmIdentity) {
if (didConfirmIdentity) {
[weakSelf addRecipientId:recipientId];
}
}];
if (didShowSNAlert) {
return;
}
[weakSelf addRecipientId:recipientId];
}
}]];
@ -319,6 +341,26 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
}
}];
} else {
BOOL didShowSNAlert = [SafetyNumberConfirmationAlert
presentAlertIfNecessaryFromViewController:self
recipientId:signalAccount.recipientId
confirmationText:NSLocalizedString(
@"SAFETY_NUMBER_CHANGED_CONFIRM_"
@"ADD_TO_GROUP_ACTION",
@"button title to confirm adding "
@"a recipient to a group when "
@"their safety "
@"number has recently changed")
contactsManager:contactsViewHelper.contactsManager
completion:^(BOOL didConfirmIdentity) {
if (didConfirmIdentity) {
[weakSelf addRecipientId:recipientId];
}
}];
if (didShowSNAlert) {
return;
}
[weakSelf addRecipientId:recipientId];
}
}]];

View file

@ -249,9 +249,8 @@ NS_ASSUME_NONNULL_BEGIN
OWSFingerprint *fingerprint =
[fingerprintBuilder fingerprintWithTheirSignalId:strongSelf.thread.contactIdentifier];
[fingerprintViewController configureWithThread:strongSelf.thread
fingerprint:fingerprint
contactName:[strongSelf threadName]];
[fingerprintViewController configureWithFingerprint:fingerprint
contactName:[strongSelf threadName]];
fingerprintViewController.dismissDelegate = strongSelf;
[strongSelf presentViewController:fingerprintViewController animated:YES completion:nil];

View file

@ -0,0 +1,119 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import Foundation
class SafetyNumberConfirmationAlert: NSObject {
let TAG = "[SafetyNumberConfirmationAlert]"
private let contactsManager: OWSContactsManager
private let storageManager: TSStorageManager
init(contactsManager: OWSContactsManager) {
self.contactsManager = contactsManager
self.storageManager = TSStorageManager.shared()
}
public class func presentAlertIfNecessary(fromViewController: UIViewController, recipientId: String, confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void) -> Bool {
return self.presentAlertIfNecessary(fromViewController: fromViewController, recipientIds: [recipientId], confirmationText: confirmationText, contactsManager: contactsManager, completion: completion)
}
public class func presentAlertIfNecessary(fromViewController: UIViewController, recipientIds: [String], confirmationText: String, contactsManager: OWSContactsManager, completion: @escaping (Bool) -> Void) -> Bool {
return SafetyNumberConfirmationAlert(contactsManager: contactsManager).presentIfNecessary(fromViewController: fromViewController,
recipientIds: recipientIds,
confirmationText: confirmationText,
completion: completion)
}
/**
* Shows confirmation dialog if at least one of the recipient id's is not confirmed.
*
* @returns true if an alert was shown
* false if there were no unconfirmed identities
*/
public func presentIfNecessary(fromViewController: UIViewController, recipientIds: [String], confirmationText: String, completion: @escaping (Bool) -> Void) -> Bool {
guard let unconfirmedIdentity = self.unconfirmedIdentityThatShouldBlockSending(recipientIds: recipientIds) else {
// No identities to confirm, no alert to present.
return false
}
let displayName: String = {
if let signalAccount = contactsManager.signalAccountMap[unconfirmedIdentity.recipientId] {
return contactsManager.displayName(for: signalAccount)
} else {
return contactsManager.displayName(forPhoneIdentifier: unconfirmedIdentity.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}}")
let title = String(format: titleFormat, displayName)
let bodyFormat = NSLocalizedString("CONFIRM_SENDING_TO_CHANGED_IDENTITY_BODY_FORMAT",
comment: "Action sheet body presented when a user's SN have recently changed. Embeds {{contact's name or phone nubmer}}")
let body = String(format: bodyFormat, displayName)
let actionSheetController = UIAlertController(title: title, message:body, preferredStyle: .actionSheet)
let confirmAction = UIAlertAction(title: confirmationText, style: .default) { _ in
Logger.info("\(self.TAG) Confirmed identity: \(unconfirmedIdentity)")
OWSDispatch.sessionStoreQueue().async {
self.storageManager.saveRemoteIdentity(unconfirmedIdentity.identityKey,
recipientId: unconfirmedIdentity.recipientId,
approvedForBlockingUse: true,
approvedForNonBlockingUse: true)
DispatchQueue.main.async {
completion(true)
}
}
}
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: \(unconfirmedIdentity)")
self.presentSafetyNumberViewController(fromViewController: fromViewController,
theirIdentityKey: unconfirmedIdentity.identityKey,
theirRecipientId: unconfirmedIdentity.recipientId,
theirDisplayName: displayName,
completion: { completion(false) })
}
actionSheetController.addAction(showSafetyNumberAction)
let dismissAction = UIAlertAction(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: "generic cancel text"), style: .cancel)
actionSheetController.addAction(dismissAction)
fromViewController.present(actionSheetController, animated: true)
return true
}
public func presentSafetyNumberViewController(fromViewController: UIViewController, theirIdentityKey: Data, theirRecipientId: String, theirDisplayName: String, completion: (() -> Void)? = nil) {
let fingerprintViewController = UIStoryboard.instantiateFingerprintViewController()
let fingerprintBuilder = OWSFingerprintBuilder(storageManager: self.storageManager, contactsManager: self.contactsManager)
let fingerprint = fingerprintBuilder.fingerprint(withTheirSignalId: theirRecipientId, theirIdentityKey: theirIdentityKey)
fingerprintViewController.configure(fingerprint: fingerprint, contactName: theirDisplayName)
fromViewController.present(fingerprintViewController, animated: true, completion: completion)
}
private func unconfirmedIdentitiesThatShouldBlockSending(recipientIds: [String]) -> [OWSRecipientIdentity] {
return recipientIds.flatMap {
return self.storageManager.unconfirmedIdentityThatShouldBlockSending(forRecipientId: $0)
}
}
private func unconfirmedIdentityThatShouldBlockSending(recipientIds: [String]) -> OWSRecipientIdentity? {
return unconfirmedIdentitiesThatShouldBlockSending(recipientIds: recipientIds).first
}
private func shouldShow(recipientIds: [String]) -> Bool {
return !unconfirmedIdentitiesThatShouldBlockSending(recipientIds: recipientIds).isEmpty
}
}

View file

@ -241,13 +241,13 @@
/* Button text */
"CONFIRM_LINK_NEW_DEVICE_ACTION" = "Link New Device";
/* Action sheet body presented when a users's SN have recently changed. Embeds {{contact's name or phone number}} */
/* Action sheet body presented when a user's SN have recently changed. Embeds {{contact's name or phone nubmer}} */
"CONFIRM_SENDING_TO_CHANGED_IDENTITY_BODY_FORMAT" = "%@ may have reinstalled or changed devices. Verify your Safety Number with them to ensure privacy.";
/* Action sheet title presented when a users's SN have recently changed. Embeds {{contact's name or phone number}} */
"CONFIRM_SENDING_TO_CHANGED_IDENTITY_TITLE_FORMAT" = "Safety Number with %@ has Changed";
/* No comment provided by engineer. */
/* Generic button text to proceed with an action */
"CONFIRMATION_TITLE" = "Confirm";
/* An indicator that a contact has been blocked. */
@ -1051,6 +1051,9 @@
/* Generic text for button that retries whatever the last action was. */
"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";
/* button title to confirm calling a recipient whose safety number recently changed */
"SAFETY_NUMBER_CHANGED_CONFIRM_CALL_ACTION" = "Confirm and Call";
@ -1276,7 +1279,7 @@
/* No comment provided by engineer. */
"SUCCESSFUL_VERIFICATION_TITLE" = "Safety Number Verified!";
/* No comment provided by engineer. */
/* generic cancel text */
"TXT_CANCEL_TITLE" = "Cancel";
/* No comment provided by engineer. */