Changed Safety numbers no longer block communication

When your partner changes their identity key (e.g. by reinstalling),
you'll see a notice alongside their message, but it will no longer
prevent the message from showing. aka "non blocking".

Existing users will be opted into the previous blocking behavior.

This is configurable for all users in Settings > Privacy.

// FREEBIE
This commit is contained in:
Michael Kirk 2016-11-08 13:08:04 -05:00
parent 28a2a4610c
commit c2aa17e362
48 changed files with 137 additions and 26 deletions

View File

@ -44,7 +44,7 @@ PODS:
- Reachability (3.2)
- SAMKeychain (1.5.2)
- SCWaveformView (1.0.0)
- SignalServiceKit (0.5.3):
- SignalServiceKit (0.6.0):
- '25519'
- AFNetworking
- AxolotlKit
@ -140,7 +140,7 @@ CHECKOUT OPTIONS:
:commit: 03cde781234ade464dd26914d87e6e95afde1119
:git: https://github.com/WhisperSystems/JSQMessagesViewController.git
SignalServiceKit:
:commit: 725153307e605681c45b3f789ed2153f218805a6
:commit: 70e536ca8f81fbd3e0e3b4be9954717d10768717
:git: https://github.com/WhisperSystems/SignalServiceKit.git
SocketRocket:
:commit: 41b57bb2fc292a814f758441a05243eb38457027
@ -164,7 +164,7 @@ SPEC CHECKSUMS:
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
SAMKeychain: 1865333198217411f35327e8da61b43de79b635b
SCWaveformView: 52a96750255d817e300565a80c81fb643e233e07
SignalServiceKit: f596e83ab9d7ff9ef89364dfe4a912afda62d55a
SignalServiceKit: c580eb2197f87212fcba9f7faf56163f410225e9
SocketRocket: dbb1554b8fc288ef8ef370d6285aeca7361be31e
SQLCipher: 4c768761421736a247ed6cf412d9045615d53dff
TwistedOakCollapsingFutures: f359b90f203e9ab13dfb92c9ff41842a7fe1cd0c

View File

@ -14,6 +14,7 @@
450873C41D9D5149006B54F2 /* OWSExpirationTimerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 450873C21D9D5149006B54F2 /* OWSExpirationTimerView.m */; };
450873C71D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 450873C61D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m */; };
450873C81D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 450873C61D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m */; };
4516E3FF1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */ = {isa = PBXBuildFile; fileRef = 4516E3FE1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.m */; };
451DE9F81DC18C9500810E42 /* AccountManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45CD81EE1DC030E7004C9430 /* AccountManager.swift */; };
451DE9FD1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451DE9FC1DC1A28200810E42 /* SyncPushTokensJob.swift */; };
451DE9FE1DC1A28200810E42 /* SyncPushTokensJob.swift in Sources */ = {isa = PBXBuildFile; fileRef = 451DE9FC1DC1A28200810E42 /* SyncPushTokensJob.swift */; };
@ -544,6 +545,8 @@
450873C51D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSIncomingMessageCollectionViewCell.h; sourceTree = "<group>"; };
450873C61D9D867B006B54F2 /* OWSIncomingMessageCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSIncomingMessageCollectionViewCell.m; sourceTree = "<group>"; };
450873C91D9D86F4006B54F2 /* OWSExpirableMessageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSExpirableMessageView.h; sourceTree = "<group>"; };
4516E3FD1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OWS101ExistingUsersBlockOnIdentityChange.h; path = Migrations/OWS101ExistingUsersBlockOnIdentityChange.h; sourceTree = "<group>"; };
4516E3FE1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OWS101ExistingUsersBlockOnIdentityChange.m; path = Migrations/OWS101ExistingUsersBlockOnIdentityChange.m; sourceTree = "<group>"; };
451DE9F11DC1585F00810E42 /* PromiseKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PromiseKit.framework; path = Carthage/Build/iOS/PromiseKit.framework; sourceTree = "<group>"; };
451DE9FC1DC1A28200810E42 /* SyncPushTokensJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SyncPushTokensJob.swift; path = Models/SyncPushTokensJob.swift; sourceTree = "<group>"; };
4520D8D41D417D8E00123472 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; };
@ -1201,6 +1204,8 @@
45666F7A1D9C0533008FE134 /* OWSDatabaseMigration.m */,
45666F7C1D9C0814008FE134 /* OWSDatabaseMigrationRunner.h */,
45666F7D1D9C0814008FE134 /* OWSDatabaseMigrationRunner.m */,
4516E3FD1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.h */,
4516E3FE1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.m */,
);
name = Migrations;
sourceTree = "<group>";
@ -2822,6 +2827,7 @@
B97940271832BD2400BD66CB /* UIUtil.m in Sources */,
4CE0E3771B954546007210CF /* TSAnimatedAdapter.m in Sources */,
76EB05BE18170B33006006FC /* ConfirmPacket.m in Sources */,
4516E3FF1DD2193B00DC4206 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */,
76EB05A818170B33006006FC /* RtpSocket.m in Sources */,
E197B61818BBEC1A00F073E5 /* RemoteIOAudio.m in Sources */,
B67ADDC41989FF8700E1A773 /* RPServerRequestsManager.m in Sources */,

View File

@ -0,0 +1,12 @@
// Created by Michael Kirk on 11/8/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "OWSDatabaseMigration.h"
NS_ASSUME_NONNULL_BEGIN
@interface OWS101ExistingUsersBlockOnIdentityChange : OWSDatabaseMigration
@end
NS_ASSUME_NONNULL_END

View File

@ -0,0 +1,30 @@
// Created by Michael Kirk on 11/8/16.
// Copyright © 2016 Open Whisper Systems. All rights reserved.
#import "OWS101ExistingUsersBlockOnIdentityChange.h"
#import <SignalServiceKit/TSPrivacyPreferences.h>
#import <YapDatabase/YapDatabaseTransaction.h>
NS_ASSUME_NONNULL_BEGIN
// Increment a similar constant for every future DBMigration
static NSString *const OWS101ExistingUsersBlockOnIdentityChangeMigrationId = @"101";
@implementation OWS101ExistingUsersBlockOnIdentityChange
+ (NSString *)migrationId
{
return OWS101ExistingUsersBlockOnIdentityChangeMigrationId;
}
- (void)runUpWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
DDLogWarn(@"[OWS101ExistingUsersBlockOnIdentityChange] Opting existing user into 'blocking' on identity changes.");
TSPrivacyPreferences *preferences = [TSPrivacyPreferences sharedInstance];
preferences.shouldBlockOnIdentityChange = YES;
[preferences saveWithTransaction:transaction];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -3,6 +3,7 @@
#import "OWSDatabaseMigrationRunner.h"
#import "OWS100RemoveTSRecipientsMigration.h"
#import "OWS101ExistingUsersBlockOnIdentityChange.h"
NS_ASSUME_NONNULL_BEGIN
@ -22,7 +23,10 @@ NS_ASSUME_NONNULL_BEGIN
- (NSArray<OWSDatabaseMigration *> *)allMigrations
{
return @[ [[OWS100RemoveTSRecipientsMigration alloc] initWithStorageManager:self.storageManager] ];
return @[
[[OWS100RemoveTSRecipientsMigration alloc] initWithStorageManager:self.storageManager],
[[OWS101ExistingUsersBlockOnIdentityChange alloc] initWithStorageManager:self.storageManager]
];
}
- (void)assumeAllExistingMigrationsRun

View File

@ -53,6 +53,11 @@ typedef NS_ENUM(NSUInteger, TSImageQuality) {
- (nullable NSString *)lastRanVersion;
- (NSString *)setAndGetCurrentVersion;
#pragma mark - Block on Identity Change
- (BOOL)shouldBlockOnIdentityChange;
- (void)setShouldBlockOnIdentityChange:(BOOL)value;
#pragma mark - Push Tokens
- (void)setPushToken:(NSString *)value;

View File

@ -1,6 +1,7 @@
#import "PropertyListPreferences.h"
#import "Constraints.h"
#import "TSStorageHeaders.h"
#import <SignalServiceKit/TSPrivacyPreferences.h>
NS_ASSUME_NONNULL_BEGIN
@ -46,6 +47,11 @@ NSString *const PropertyListPreferencesKeyLastRecordedVoipToken = @"LastRecorded
inCollection:PropertyListPreferencesSignalDatabaseCollection];
}
- (TSPrivacyPreferences *)tsPrivacyPreferences
{
return [TSPrivacyPreferences sharedInstance];
}
#pragma mark - Specific Preferences
- (NSTimeInterval)getCachedOrDefaultDesiredBufferDepth
@ -202,6 +208,19 @@ NSString *const PropertyListPreferencesKeyLastRecordedVoipToken = @"LastRecorded
}
}
#pragma mark - Block on Identity Change
- (BOOL)shouldBlockOnIdentityChange
{
return self.tsPrivacyPreferences.shouldBlockOnIdentityChange;
}
- (void)setShouldBlockOnIdentityChange:(BOOL)value
{
self.tsPrivacyPreferences.shouldBlockOnIdentityChange = value;
[self.tsPrivacyPreferences save];
}
#pragma mark - Push Tokens
- (void)setPushToken:(NSString *)value

View File

@ -59,7 +59,8 @@ NSString *const kCompletedRegistrationSegue = @"CompletedRegistration";
[super viewDidLoad];
[self initializeKeyboardHandlers];
_headerLabel.text = NSLocalizedString(@"VERIFICATION_HEADER", @"Navigation title in the registration flow - during the sms code verification process.");
_challengeTextField.placeholder = NSLocalizedString(@"VERIFICATION_CHALLENGE_DEFAULT_TEXT", @"Text field placeholder for SMS verification code during registartion");
_challengeTextField.placeholder = NSLocalizedString(@"VERIFICATION_CHALLENGE_DEFAULT_TEXT",
@"Text field placeholder for SMS verification code during registration");
_challengeTextField.delegate = self;
[_challengeButton setTitle:NSLocalizedString(@"VERIFICATION_CHALLENGE_SUBMIT_CODE", @"button text during registration to submit your SMS verification code")
forState:UIControlStateNormal];

View File

@ -14,10 +14,20 @@
#import "UIUtil.h"
#import <25519/Curve25519.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, PrivacySettingsTableViewControllerSectionIndex) {
PrivacySettingsTableViewControllerSectionIndexScreenSecurity,
PrivacySettingsTableViewControllerSectionIndexHistoryLog,
PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange
};
@interface PrivacySettingsTableViewController ()
@property (nonatomic, strong) UITableViewCell *enableScreenSecurityCell;
@property (nonatomic, strong) UISwitch *enableScreenSecuritySwitch;
@property (nonatomic, strong) UITableViewCell *blockOnIdentityChangeCell;
@property (nonatomic, strong) UISwitch *blockOnIdentityChangeSwitch;
@property (nonatomic, strong) UITableViewCell *clearHistoryLogCell;
@end
@ -51,37 +61,50 @@
action:@selector(didToggleScreenSecuritySwitch:)
forControlEvents:UIControlEventTouchUpInside];
// Clear History Log Cell
self.clearHistoryLogCell = [[UITableViewCell alloc] init];
self.clearHistoryLogCell.textLabel.text = NSLocalizedString(@"SETTINGS_CLEAR_HISTORY", @"");
self.clearHistoryLogCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Block Identity on KeyChange
self.blockOnIdentityChangeCell = [UITableViewCell new];
self.blockOnIdentityChangeCell.textLabel.text
= NSLocalizedString(@"SETTINGS_BLOCK_ON_IDENTITY_CHANGE_TITLE", @"Table cell label");
self.blockOnIdentityChangeSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
self.blockOnIdentityChangeCell.accessoryView = self.blockOnIdentityChangeSwitch;
[self.blockOnIdentityChangeSwitch setOn:[Environment.preferences shouldBlockOnIdentityChange]];
[self.blockOnIdentityChangeSwitch addTarget:self
action:@selector(didToggleBlockOnIdentityChangeSwitch:)
forControlEvents:UIControlEventTouchUpInside];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 2;
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
switch (section) {
case 0:
case PrivacySettingsTableViewControllerSectionIndexScreenSecurity:
return 1;
case 1:
case PrivacySettingsTableViewControllerSectionIndexHistoryLog:
return 1;
case PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange:
return 1;
// TODO: optionally non-blocking
// case 2:
// return 1;
default:
return 0;
}
}
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
- (nullable NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
switch (section) {
case 0:
case PrivacySettingsTableViewControllerSectionIndexScreenSecurity:
return NSLocalizedString(@"SETTINGS_SCREEN_SECURITY_DETAIL", nil);
case PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange:
return NSLocalizedString(
@"SETTINGS_BLOCK_ON_IDENITY_CHANGE_DETAIL", @"User settings section footer, a detailed explanation");
default:
return nil;
}
@ -89,25 +112,27 @@
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
switch (indexPath.section) {
case 0:
case PrivacySettingsTableViewControllerSectionIndexScreenSecurity:
return self.enableScreenSecurityCell;
case 1:
case PrivacySettingsTableViewControllerSectionIndexHistoryLog:
return self.clearHistoryLogCell;
// TODO - safetynumber settings
// case 2:
// return [UITableViewCell new];
case PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange:
return self.blockOnIdentityChangeCell;
default: {
DDLogError(@"%@ Requested unknown table view cell for row at indexPath: %@", self.tag, indexPath);
return [UITableViewCell new];
}
}
return nil;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
switch (section) {
case 0:
case PrivacySettingsTableViewControllerSectionIndexScreenSecurity:
return NSLocalizedString(@"SETTINGS_SECURITY_TITLE", @"Section header");
case 1:
case PrivacySettingsTableViewControllerSectionIndexHistoryLog:
return NSLocalizedString(@"SETTINGS_HISTORYLOG_TITLE", @"Section header");
case 2:
case PrivacySettingsTableViewControllerSectionIndexBlockOnIdentityChange:
return NSLocalizedString(@"SETTINGS_PRIVACY_VERIFICATION_TITLE", @"Section header");
default:
return nil;
@ -118,7 +143,7 @@
[tableView deselectRowAtIndexPath:indexPath animated:YES];
switch (indexPath.section) {
case 1: {
case PrivacySettingsTableViewControllerSectionIndexHistoryLog: {
[DJWActionSheet showInView:self.parentViewController.view
withTitle:NSLocalizedString(@"SETTINGS_DELETE_HISTORYLOG_CONFIRMATION", @"")
cancelButtonTitle:NSLocalizedString(@"TXT_CANCEL_TITLE", @"")
@ -151,6 +176,13 @@
[Environment.preferences setScreenSecurity:enabled];
}
- (void)didToggleBlockOnIdentityChangeSwitch:(UISwitch *)sender
{
BOOL enabled = self.blockOnIdentityChangeSwitch.isOn;
DDLogInfo(@"%@ toggled blockOnIdentityChange: %@", self.tag, enabled ? @"ON" : @"OFF");
[Environment.preferences setShouldBlockOnIdentityChange:enabled];
}
#pragma mark - Log util
+ (NSString *)tag
@ -164,3 +196,5 @@
}
@end
NS_ASSUME_NONNULL_END