Merge branch 'mkirk/identityManager'

pull/1/head
Michael Kirk 8 years ago
commit 34f59d661a

@ -136,7 +136,7 @@ CHECKOUT OPTIONS:
:commit: 7054e4b13ee5bcd6d524adb6dc9a726e8c466308
:git: https://github.com/WhisperSystems/JSQMessagesViewController.git
SignalServiceKit:
:commit: 43d1aa49dc869486cdba8546b56e716beae5c1d0
:commit: d475c58348a0a8c4ed9b0fcdbe352cd87e8ce269
:git: https://github.com/WhisperSystems/SignalServiceKit.git
SocketRocket:
:commit: 877ac7438be3ad0b45ef5ca3969574e4b97112bf

@ -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 = "<group>"; };
4597E94E1D8313C100040CDE /* sq */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sq; path = translations/sq.lproj/Localizable.strings; sourceTree = "<group>"; };
4597E94F1D8313CB00040CDE /* bg */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = bg; path = translations/bg.lproj/Localizable.strings; sourceTree = "<group>"; };
459B1C661ED480BB00506A04 /* MarkIdentityAsSeenJob.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = MarkIdentityAsSeenJob.swift; path = Jobs/MarkIdentityAsSeenJob.swift; sourceTree = "<group>"; };
45A6DAD51EBBF85500893231 /* ReminderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReminderView.swift; sourceTree = "<group>"; };
45AE48501E0732D6004D96C2 /* TurnServerInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = "<group>"; };
45B201741DAECBFD00C461E0 /* Signal-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Signal-Bridging-Header.h"; sourceTree = "<group>"; };
@ -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 */,

@ -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()
}
}
}

@ -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 {

@ -52,13 +52,14 @@
#import <SignalServiceKit/OWSDispatch.h>
#import <SignalServiceKit/OWSEndSessionMessage.h>
#import <SignalServiceKit/OWSError.h>
#import <SignalServiceKit/OWSFingerprint.h>
#import <SignalServiceKit/OWSFingerprintBuilder.h>
#import <SignalServiceKit/OWSGetMessagesRequest.h>
#import <SignalServiceKit/OWSGetProfileRequest.h>
#import <SignalServiceKit/OWSIdentityManager.h>
#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>
@ -77,7 +78,6 @@
#import <SignalServiceKit/TSNetworkManager.h>
#import <SignalServiceKit/TSSocketManager.h>
#import <SignalServiceKit/TSStorageManager+Calling.h>
#import <SignalServiceKit/TSStorageManager+IdentityKeyStore.h>
#import <SignalServiceKit/TSStorageManager+SessionStore.h>
#import <SignalServiceKit/TSStorageManager+keyingMaterial.h>
#import <SignalServiceKit/TSThread.h>

@ -36,8 +36,12 @@ class CallNotificationsAdapter: NSObject {
adaptee.presentMissedCall(call, callerName: callerName)
}
func presentRejectedCallWithUnseenIdentityChange(_ call: SignalCall, callerName: String) {
Logger.debug("\(TAG) in \(#function)")
adaptee.presentRejectedCallWithUnseenIdentityChange(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)
}
}

@ -14,16 +14,15 @@ 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 {
case callBack,
showThread,
confirmIdentityAndCallBack
showThread
}
static var allCategories: Set<UNNotificationCategory> {
@ -39,9 +38,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: [])
}
@ -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)
}
}
}
@ -118,7 +113,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 +129,7 @@ class UserNotificationsAdaptee: NSObject, OWSCallNotificationsAdaptee, UNUserNot
center.add(request)
}
func presentRejectedCallWithUnseenIdentityChange(_ call: SignalCall, callerName: String) {
public func presentMissedCallBecauseOfNoLongerVerifiedIdentity(call: SignalCall, callerName: String) {
Logger.debug("\(TAG) \(#function)")
let content = UNMutableNotificationContent()
@ -144,16 +139,42 @@ class UserNotificationsAdaptee: NSObject, OWSCallNotificationsAdaptee, UNUserNot
let notificationBody = { () -> String in
switch previewType {
case .noNameNoPreview:
return CallStrings.rejectedCallWithUnseenIdentityChangeNotificationBody
return CallStrings.missedCallWithIdentityChangeNotificationBodyWithoutCallerName
case .nameNoPreview, .namePreview:
return (Environment.getCurrent().preferences.isCallKitPrivacyEnabled()
? CallStrings.rejectedCallWithUnseenIdentityChangeNotificationBodyWithoutCallerName
: String(format: CallStrings.rejectedCallWithUnseenIdentityChangeNotificationBodyWithCallerName, 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)

@ -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}}")
}

@ -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];

@ -834,7 +834,6 @@ typedef enum : NSUInteger {
_callOnOpen = NO;
}
[self updateNavigationBarSubtitleLabel];
[MarkIdentityAsSeenJob runWithThread:self.thread];
[ProfileFetcherJob runWithThread:self.thread networkManager:self.networkManager];
[self markVisibleMessagesAsRead];
@ -1174,7 +1173,6 @@ typedef enum : NSUInteger {
return [SafetyNumberConfirmationAlert presentAlertIfNecessaryWithRecipientIds:self.thread.recipientIdentifiers
confirmationText:confirmationText
contactsManager:self.contactsManager
verifySeen:NO
completion:completionHandler];
}

@ -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
presentRejectedCallWithUnseenIdentityChange: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];

@ -11,8 +11,8 @@
#import <SignalServiceKit/NSDate+millisecondTimeStamp.h>
#import <SignalServiceKit/OWSError.h>
#import <SignalServiceKit/OWSFingerprint.h>
#import <SignalServiceKit/OWSIdentityManager.h>
#import <SignalServiceKit/TSInfoMessage.h>
#import <SignalServiceKit/TSStorageManager+IdentityKeyStore.h>
#import <SignalServiceKit/TSStorageManager+SessionStore.h>
#import <SignalServiceKit/TSStorageManager+keyingMaterial.h>

@ -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];

@ -8,7 +8,7 @@
#import "SettingsTableViewController.h"
#import <SignalServiceKit/ECKeyPair+OWSPrivateKey.h>
#import <SignalServiceKit/OWSDeviceProvisioner.h>
#import <SignalServiceKit/TSStorageManager+IdentityKeyStore.h>
#import <SignalServiceKit/OWSIdentityManager.h>
#import <SignalServiceKit/TSStorageManager+keyingMaterial.h>
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

@ -16,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)
}
@ -33,27 +32,14 @@ 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 {
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 untrustedIdentity = untrustedIdentityForSending(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: 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}}")
@ -69,11 +55,7 @@ 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)
MarkIdentityAsSeenJob.run(recipientId: untrustedIdentity.recipientId)
OWSIdentityManager.shared().setVerificationState(.default, identityKey: untrustedIdentity.identityKey, recipientId: untrustedIdentity.recipientId, sendSyncMessage: true)
DispatchQueue.main.async {
completion(true)
}
@ -110,16 +92,9 @@ class SafetyNumberConfirmationAlert: NSObject {
UIApplication.shared.frontmostViewController?.present(fingerprintViewController, animated: true, completion: completion)
}
private func unconfirmedIdentities(recipientIds: [String]) -> [OWSRecipientIdentity] {
return recipientIds.flatMap {
self.storageManager.unconfirmedIdentityThatShouldBlockSending(forRecipientId: $0)
}
}
private func unseenIdentities(recipientIds: [String]) -> [OWSRecipientIdentity] {
private func untrustedIdentityForSending(recipientIds: [String]) -> OWSRecipientIdentity? {
return recipientIds.flatMap {
self.storageManager.unseenIdentityChange(forRecipientId: $0)
}
OWSIdentityManager.shared().untrustedIdentityForSending(toRecipientId: $0)
}.first
}
}

@ -470,9 +470,22 @@ protocol CallServiceObserver: class {
let newCall = SignalCall.incomingCall(localId: UUID(), remotePhoneNumber: thread.contactIdentifier(), signalingId: callId)
guard self.storageManager.unseenIdentityChange(forRecipientId: thread.contactIdentifier()) == nil else {
let untrustedIdentity = OWSIdentityManager.shared().untrustedIdentityForSending(toRecipientId: thread.contactIdentifier())
guard untrustedIdentity == nil else {
let callerName = self.contactsManager.displayName(forPhoneIdentifier: thread.contactIdentifier())
self.notificationsAdapter.presentRejectedCallWithUnseenIdentityChange(newCall, callerName: callerName)
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:
self.notificationsAdapter.presentMissedCallBecauseOfNewIdentity(call: newCall, callerName: callerName)
case .noLongerVerified:
self.notificationsAdapter.presentMissedCallBecauseOfNoLongerVerifiedIdentity(call: newCall, callerName: callerName)
}
return
}

@ -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)
}

@ -4,6 +4,7 @@
NS_ASSUME_NONNULL_BEGIN
@class OWSRecipientIdentity;
@class SignalCall;
@protocol OWSCallNotificationsAdaptee <NSObject>
@ -12,9 +13,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)presentMissedCall:(SignalCall *)call callerName:(NSString *)callerName;
- (void)presentRejectedCallWithUnseenIdentityChange:(SignalCall *)call
callerName:(NSString *)callerName
NS_SWIFT_NAME(presentRejectedCallWithUnseenIdentityChange(_:callerName:));
- (void)presentMissedCallBecauseOfNewIdentity:(SignalCall *)call
callerName:(NSString *)callerName
NS_SWIFT_NAME(presentMissedCallBecauseOfNewIdentity(call:callerName:));
- (void)presentMissedCallBecauseOfNoLongerVerifiedIdentity:(SignalCall *)call
callerName:(NSString *)callerName
NS_SWIFT_NAME(presentMissedCallBecauseOfNoLongerVerifiedIdentity(call:callerName:));
@end

@ -3,8 +3,8 @@
//
#import "OWS104CreateRecipientIdentities.h"
#import <SignalServiceKit/OWSIdentityManager.h>
#import <SignalServiceKit/OWSRecipientIdentity.h>
#import <SignalServiceKit/TSStorageManager+IdentityKeyStore.h>
#import <YapDatabase/YapDatabaseConnection.h>
#import <YapDatabase/YapDatabaseTransaction.h>
@ -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];

@ -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)presentRejectedCallWithUnseenIdentityChange:(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 = PushManagerCategoriesRejectedCallFromUnseenIdentityChange;
// Use category which does not allow call back
notification.category = PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity;
NSString *localCallId = call.localId.UUIDString;
notification.userInfo = @{
PushManagerUserInfoKeysLocalCallId : localCallId,
@ -130,17 +169,16 @@
NSString *alertMessage;
switch (self.notificationPreviewType) {
case NotificationNoNameNoPreview: {
alertMessage = [CallStrings rejectedCallWithUnseenIdentityChangeNotificationBody];
alertMessage = [CallStrings missedCallWithIdentityChangeNotificationBodyWithoutCallerName];
break;
}
case NotificationNameNoPreview:
case NotificationNamePreview: {
alertMessage = (([UIDevice currentDevice].supportsCallKit &&
[[Environment getCurrent].preferences isCallKitPrivacyEnabled])
? [CallStrings rejectedCallWithUnseenIdentityChangeNotificationBodyWithoutCallerName]
? [CallStrings missedCallWithIdentityChangeNotificationBodyWithoutCallerName]
: [NSString
stringWithFormat:[CallStrings
rejectedCallWithUnseenIdentityChangeNotificationBodyWithCallerName],
stringWithFormat:[CallStrings missedCallWithIdentityChangeNotificationBodyWithCallerName],
callerName]);
break;
}

@ -22,12 +22,11 @@ extern NSString *const Signal_Message_MarkAsRead_Identifier;
extern NSString *const PushManagerCategoriesIncomingCall;
extern NSString *const PushManagerCategoriesMissedCall;
extern NSString *const PushManagerCategoriesRejectedCallFromUnseenIdentityChange;
extern NSString *const PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity;
extern NSString *const PushManagerActionsAcceptCall;
extern NSString *const PushManagerActionsDeclineCall;
extern NSString *const PushManagerActionsCallBack;
extern NSString *const PushManagerActionsConfirmIdentityAndCallBack;
extern NSString *const PushManagerActionsShowThread;
extern NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId;

@ -207,18 +207,6 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe
return;
}
[self.callUIAdapter startAndShowOutgoingCallWithRecipientId:recipientId];
completionHandler();
} else if ([identifier isEqualToString:PushManagerActionsConfirmIdentityAndCallBack]) {
NSString *recipientId = notification.userInfo[PushManagerUserInfoKeysCallBackSignalRecipientId];
if (!recipientId) {
DDLogError(@"%@ missing call back id", self.tag);
return;
}
TSContactThread *thread = [TSContactThread getOrCreateThreadWithContactId:recipientId];
[MarkIdentityAsSeenJob runWithThread:thread];
[self.callUIAdapter startAndShowOutgoingCallWithRecipientId:recipientId];
completionHandler();
} else if ([identifier isEqualToString:PushManagerActionsShowThread]) {
@ -357,13 +345,14 @@ NSString *const Signal_Message_MarkAsRead_Identifier = @"Signal_Message_MarkAsRe
NSString *const PushManagerCategoriesIncomingCall = @"PushManagerCategoriesIncomingCall";
NSString *const PushManagerCategoriesMissedCall = @"PushManagerCategoriesMissedCall";
NSString *const PushManagerCategoriesRejectedCallFromUnseenIdentityChange =
@"PushManagerCategoriesRejectedCallFromUnseenIdentityChange";
NSString *const PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity =
@"PushManagerCategoriesMissedCallFromNoLongerVerifiedIdentity";
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,14 +399,8 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager
return missedCallCategory;
}
- (UIUserNotificationCategory *)signalRejectedCallWithUnseenIdentityChangeCategory
- (UIUserNotificationCategory *)signalMissedCallWithNoLongerVerifiedIdentityChangeCategory
{
UIMutableUserNotificationAction *confirmAndCallBackAction = [UIMutableUserNotificationAction new];
confirmAndCallBackAction.identifier = PushManagerActionsConfirmIdentityAndCallBack;
confirmAndCallBackAction.title = [CallStrings confirmIdentityAndCallBackButtonTitle];
confirmAndCallBackAction.activationMode = UIUserNotificationActivationModeForeground;
confirmAndCallBackAction.destructive = NO;
confirmAndCallBackAction.authenticationRequired = YES;
UIMutableUserNotificationAction *showThreadAction = [UIMutableUserNotificationAction new];
showThreadAction.identifier = PushManagerActionsShowThread;
@ -427,11 +410,9 @@ NSString *const PushManagerUserInfoKeysCallBackSignalRecipientId = @"PushManager
showThreadAction.authenticationRequired = YES;
UIMutableUserNotificationCategory *rejectedCallCategory = [UIMutableUserNotificationCategory new];
rejectedCallCategory.identifier = PushManagerCategoriesRejectedCallFromUnseenIdentityChange;
[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;
}
@ -452,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];
}

@ -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 from %@ because their 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 %@.";
@ -1073,13 +1064,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";
"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%@";

Loading…
Cancel
Save