Multiple refinements around verification.

* Check for identity key before presenting fingerprint view.
* Show verification state in a separate subtitle in conversation view.
* Let users verify from group members view.

// FREEBIE
pull/1/head
Matthew Chen 8 years ago
parent 11ca51c95f
commit 7da28bd5dc

@ -1273,11 +1273,7 @@ typedef enum : NSUInteger {
// return from FingerprintViewController. // return from FingerprintViewController.
[self dismissKeyBoard]; [self dismissKeyBoard];
FingerprintViewController *fingerprintViewController = [FingerprintViewController new]; [FingerprintViewController showVerificationViewFromViewController:self recipientId:recipientId];
[fingerprintViewController configureWithRecipientId:recipientId];
UINavigationController *navigationController =
[[UINavigationController alloc] initWithRootViewController:fingerprintViewController];
[self presentViewController:navigationController animated:YES completion:nil];
} }
#pragma mark - Calls #pragma mark - Calls

@ -6,7 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface FingerprintViewController : UIViewController @interface FingerprintViewController : UIViewController
- (void)configureWithRecipientId:(NSString *)recipientId NS_SWIFT_NAME(configure(recipientId:)); + (void)showVerificationViewFromViewController:(UIViewController *)viewController recipientId:(NSString *)recipientId;
@end @end

@ -89,6 +89,27 @@ typedef void (^CustomLayoutBlock)();
@implementation FingerprintViewController @implementation FingerprintViewController
+ (void)showVerificationViewFromViewController:(UIViewController *)viewController recipientId:(NSString *)recipientId
{
OWSAssert(recipientId.length > 0);
OWSRecipientIdentity *_Nullable recipientIdentity =
[[OWSIdentityManager sharedManager] recipientIdentityForRecipientId:recipientId];
if (!recipientIdentity) {
[OWSAlerts showAlertWithTitle:NSLocalizedString(@"CANT_VERIFY_IDENTITY_ALERT_TITLE",
@"Title for alert explaining that a user cannot be verified.")
message:NSLocalizedString(@"CANT_VERIFY_IDENTITY_ALERT_MESSAGE",
@"Message for alert explaining that a user cannot be verified.")];
return;
}
FingerprintViewController *fingerprintViewController = [FingerprintViewController new];
[fingerprintViewController configureWithRecipientId:recipientId];
UINavigationController *navigationController =
[[UINavigationController alloc] initWithRootViewController:fingerprintViewController];
[viewController presentViewController:navigationController animated:YES completion:nil];
}
- (instancetype)init - (instancetype)init
{ {
self = [super init]; self = [super init];
@ -493,6 +514,8 @@ typedef void (^CustomLayoutBlock)();
:self.identityKey :self.identityKey
recipientId:self.recipientId recipientId:self.recipientId
sendSyncMessage:YES]; sendSyncMessage:YES];
[self dismissViewControllerAnimated:YES completion:nil];
} }
} }

@ -240,15 +240,16 @@ NS_ASSUME_NONNULL_BEGIN
firstSection.customHeaderHeight = @(100.f); firstSection.customHeaderHeight = @(100.f);
if (!self.isGroupThread && self.thread.hasSafetyNumbers) { if (!self.isGroupThread && self.thread.hasSafetyNumbers) {
[firstSection [firstSection addItem:[OWSTableItem itemWithCustomCellBlock:^{
addItem:[OWSTableItem itemWithCustomCellBlock:^{ return [weakSelf
return [weakSelf disclosureCellWithName:NSLocalizedString(@"VERIFY_PRIVACY", disclosureCellWithName:
@"table cell label in conversation settings") NSLocalizedString(@"VERIFY_PRIVACY",
iconName:@"table_ic_verify"]; @"Label for button or row which allows users to verify the safety number of another user.")
} iconName:@"table_ic_verify"];
actionBlock:^{ }
[weakSelf showVerificationView]; actionBlock:^{
}]]; [weakSelf showVerificationView];
}]];
} }
[firstSection [firstSection
@ -549,55 +550,51 @@ NS_ASSUME_NONNULL_BEGIN
[threadTitleLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft]; [threadTitleLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft];
[threadTitleLabel autoPinEdgeToSuperviewEdge:ALEdgeRight]; [threadTitleLabel autoPinEdgeToSuperviewEdge:ALEdgeRight];
const CGFloat kSubtitlePointSize = 12.f; __block UIView *lastTitleView = threadTitleLabel;
NSMutableAttributedString *subtitle = nil;
if (![self isGroupThread]) { if (![self isGroupThread]) {
const CGFloat kSubtitlePointSize = 12.f;
void (^addSubtitle)(NSAttributedString *) = ^(NSAttributedString *subtitle) {
UILabel *subtitleLabel = [UILabel new];
subtitleLabel.textColor = [UIColor ows_darkGrayColor];
subtitleLabel.font = [UIFont ows_regularFontWithSize:kSubtitlePointSize];
subtitleLabel.attributedText = subtitle;
subtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
[threadNameView addSubview:subtitleLabel];
[subtitleLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:lastTitleView];
[subtitleLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft];
lastTitleView = subtitleLabel;
};
NSString *recipientId = self.thread.contactIdentifier; NSString *recipientId = self.thread.contactIdentifier;
BOOL isVerified = [[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId]
== OWSVerificationStateVerified;
BOOL hasName = ![self.thread.name isEqualToString:recipientId];
if (isVerified || hasName) { BOOL hasName = ![self.thread.name isEqualToString:recipientId];
subtitle = [NSMutableAttributedString new]; if (hasName) {
NSAttributedString *subtitle = [[NSAttributedString alloc]
if (isVerified) { initWithString:[PhoneNumber
// "checkmark" bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber:recipientId]];
[subtitle appendAttributedString:[[NSAttributedString alloc] addSubtitle(subtitle);
initWithString:@"\uf00c " }
attributes:@{
NSFontAttributeName :
[UIFont ows_fontAwesomeFont:kSubtitlePointSize],
}]];
}
if (hasName) { BOOL isVerified = [[OWSIdentityManager sharedManager] verificationStateForRecipientId:recipientId]
[subtitle == OWSVerificationStateVerified;
appendAttributedString: if (isVerified) {
[[NSAttributedString alloc] NSMutableAttributedString *subtitle = [NSMutableAttributedString new];
initWithString:[PhoneNumber bestEffortFormatPartialUserSpecifiedTextToLookLikeAPhoneNumber: // "checkmark"
recipientId]]]; [subtitle appendAttributedString:[[NSAttributedString alloc]
} else { initWithString:@"\uf00c "
[subtitle attributes:@{
appendAttributedString:[[NSAttributedString alloc] NSFontAttributeName :
initWithString:NSLocalizedString(@"PRIVACY_IDENTITY_IS_VERIFIED_BADGE", [UIFont ows_fontAwesomeFont:kSubtitlePointSize],
@"Badge indicating that the user is verified.")]]; }]];
} [subtitle appendAttributedString:[[NSAttributedString alloc]
initWithString:NSLocalizedString(@"PRIVACY_IDENTITY_IS_VERIFIED_BADGE",
@"Badge indicating that the user is verified.")]];
addSubtitle(subtitle);
} }
} }
if (subtitle) { [lastTitleView autoPinEdgeToSuperviewEdge:ALEdgeBottom];
UILabel *threadSubtitleLabel = [UILabel new];
threadSubtitleLabel.textColor = [UIColor ows_darkGrayColor];
threadSubtitleLabel.font = [UIFont ows_regularFontWithSize:kSubtitlePointSize];
threadSubtitleLabel.attributedText = subtitle;
threadSubtitleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
[threadNameView addSubview:threadSubtitleLabel];
[threadSubtitleLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[threadSubtitleLabel autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:threadTitleLabel];
[threadSubtitleLabel autoPinEdgeToSuperviewEdge:ALEdgeLeft];
} else {
[threadTitleLabel autoPinEdgeToSuperviewEdge:ALEdgeBottom];
}
[firstSectionHeader [firstSectionHeader
addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self
@ -679,11 +676,10 @@ NS_ASSUME_NONNULL_BEGIN
- (void)showVerificationView - (void)showVerificationView
{ {
FingerprintViewController *fingerprintViewController = [FingerprintViewController new]; NSString *recipientId = self.thread.contactIdentifier;
[fingerprintViewController configureWithRecipientId:self.thread.contactIdentifier]; OWSAssert(recipientId.length > 0);
UINavigationController *navigationController =
[[UINavigationController alloc] initWithRootViewController:fingerprintViewController]; [FingerprintViewController showVerificationViewFromViewController:self recipientId:recipientId];
[self presentViewController:navigationController animated:YES completion:nil];
} }
- (void)showGroupMembersView - (void)showGroupMembersView

@ -63,7 +63,7 @@ class SafetyNumberConfirmationAlert: NSObject {
} }
actionSheetController.addAction(confirmAction) actionSheetController.addAction(confirmAction)
let showSafetyNumberAction = UIAlertAction(title: NSLocalizedString("VERIFY_PRIVACY", comment: "Action sheet item"), style: .default) { _ in let showSafetyNumberAction = UIAlertAction(title: NSLocalizedString("VERIFY_PRIVACY", comment: "Label for button or row which allows users to verify the safety number of another user."), 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: \(untrustedIdentity)")
self.presentSafetyNumberViewController(theirIdentityKey: untrustedIdentity.identityKey, self.presentSafetyNumberViewController(theirIdentityKey: untrustedIdentity.identityKey,
@ -82,10 +82,11 @@ class SafetyNumberConfirmationAlert: NSObject {
} }
public func presentSafetyNumberViewController(theirIdentityKey: Data, theirRecipientId: String, theirDisplayName: String, completion: (() -> Void)? = nil) { public func presentSafetyNumberViewController(theirIdentityKey: Data, theirRecipientId: String, theirDisplayName: String, completion: (() -> Void)? = nil) {
let fingerprintViewController = FingerprintViewController() guard let fromViewController = UIApplication.shared.frontmostViewController else {
fingerprintViewController.configure(recipientId: theirRecipientId) Logger.info("\(self.TAG) Missing frontmostViewController")
let navigationController = UINavigationController(rootViewController:fingerprintViewController) return
UIApplication.shared.frontmostViewController?.present(navigationController, animated: true, completion: completion) }
FingerprintViewController.showVerificationView(from:fromViewController, recipientId:theirRecipientId)
} }
private func untrustedIdentityForSending(recipientIds: [String]) -> OWSRecipientIdentity? { private func untrustedIdentityForSending(recipientIds: [String]) -> OWSRecipientIdentity? {

@ -274,6 +274,14 @@ NS_ASSUME_NONNULL_BEGIN
handler:^(UIAlertAction *_Nonnull action) { handler:^(UIAlertAction *_Nonnull action) {
[self callMember:recipientId]; [self callMember:recipientId];
}]]; }]];
[actionSheetController
addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"VERIFY_PRIVACY",
@"Label for button or row which allows users to verify the "
@"safety number of another user.")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *_Nonnull action) {
[self verifySafetyNumber:recipientId];
}]];
} }
UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"") UIAlertAction *dismissAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"")
@ -305,6 +313,13 @@ NS_ASSUME_NONNULL_BEGIN
[Environment callUserWithIdentifier:recipientId]; [Environment callUserWithIdentifier:recipientId];
} }
- (void)verifySafetyNumber:(NSString *)recipientId
{
OWSAssert(recipientId.length > 0);
[FingerprintViewController showVerificationViewFromViewController:self recipientId:recipientId];
}
#pragma mark - ContactsViewHelperDelegate #pragma mark - ContactsViewHelperDelegate
- (void)contactsViewHelperDidUpdateContacts - (void)contactsViewHelperDidUpdateContacts

@ -226,6 +226,12 @@
/* The generic name used for calls if CallKit privacy is enabled */ /* The generic name used for calls if CallKit privacy is enabled */
"CALLKIT_ANONYMOUS_CONTACT_NAME" = "Signal User"; "CALLKIT_ANONYMOUS_CONTACT_NAME" = "Signal User";
/* Message for alert explaining that a user cannot be verified. */
"CANT_VERIFY_IDENTITY_ALERT_MESSAGE" = "This user can't be verified until you've exchanged messages with them.";
/* Title for alert explaining that a user cannot be verified. */
"CANT_VERIFY_IDENTITY_ALERT_TITLE" = "Error";
/* Title for the 'censorship circumvention country' view. */ /* Title for the 'censorship circumvention country' view. */
"CENSORSHIP_CIRCUMVENTION_COUNTRY_VIEW_TITLE" = "Select Country"; "CENSORSHIP_CIRCUMVENTION_COUNTRY_VIEW_TITLE" = "Select Country";
@ -1438,8 +1444,7 @@
/* Generic message indicating that verification state changed for a given user. */ /* Generic message indicating that verification state changed for a given user. */
"VERIFICATION_STATE_CHANGE_GENERIC" = "Verification state changed."; "VERIFICATION_STATE_CHANGE_GENERIC" = "Verification state changed.";
/* Action sheet item /* Label for button or row which allows users to verify the safety number of another user. */
table cell label in conversation settings */
"VERIFY_PRIVACY" = "Show Safety Number"; "VERIFY_PRIVACY" = "Show Safety Number";
/* Indicates how to cancel a voice message. */ /* Indicates how to cancel a voice message. */

Loading…
Cancel
Save