diff --git a/SignalMessaging/profiles/ProfileFetcherJob.swift b/SignalMessaging/profiles/ProfileFetcherJob.swift index ecad059ac..c28236745 100644 --- a/SignalMessaging/profiles/ProfileFetcherJob.swift +++ b/SignalMessaging/profiles/ProfileFetcherJob.swift @@ -135,7 +135,8 @@ public class ProfileFetcherJob: NSObject { Logger.error("getProfile: \(recipientId)") - let udAccess = udManager.udAccess(forRecipientId: recipientId) + let udAccess = udManager.udAccess(forRecipientId: recipientId, + requireSyncAccess: false) return requestProfile(recipientId: recipientId, udAccess: udAccess, canFailoverUDAuth: true) diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 782b17b43..6ea0ce7ce 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -593,7 +593,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; AnyPromise *sendPromise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { OWSUDAccess *_Nullable theirUDAccess; if (senderCertificate != nil && selfUDAccess != nil) { - theirUDAccess = [self.udManager udAccessForRecipientId:recipient.recipientId]; + theirUDAccess = [self.udManager udAccessForRecipientId:recipient.recipientId requireSyncAccess:YES]; } OWSMessageSend *messageSend = [[OWSMessageSend alloc] initWithMessage:message @@ -633,7 +633,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; OWSUDAccess *_Nullable selfUDAccess; if (senderCertificate) { - selfUDAccess = [self.udManager udAccessForRecipientId:self.tsAccountManager.localNumber]; + selfUDAccess = [self.udManager udAccessForRecipientId:self.tsAccountManager.localNumber requireSyncAccess:YES]; } void (^successHandler)(void) = ^() { diff --git a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift index 95219d9f9..65a4eb7a7 100644 --- a/SignalServiceKit/src/Messages/UD/OWSUDManager.swift +++ b/SignalServiceKit/src/Messages/UD/OWSUDManager.swift @@ -79,7 +79,8 @@ public class OWSUDAccess: NSObject { func udAccessKey(forRecipientId recipientId: RecipientIdentifier) -> SMKUDAccessKey? @objc - func udAccess(forRecipientId recipientId: RecipientIdentifier) -> OWSUDAccess? + func udAccess(forRecipientId recipientId: RecipientIdentifier, + requireSyncAccess: Bool) -> OWSUDAccess? // MARK: Sender Certificate @@ -152,13 +153,7 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { @objc public func isUDEnabled() -> Bool { - // Only enable UD if UD is supported by all linked devices, - // so that sync messages can also be sent via UD. - guard let localNumber = tsAccountManager.localNumber() else { - return false - } - let ourAccessMode = unidentifiedAccessMode(forRecipientId: localNumber) - return ourAccessMode == .enabled || ourAccessMode == .unrestricted + return true } @objc @@ -184,35 +179,44 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { } private func unidentifiedAccessMode(forRecipientId recipientId: RecipientIdentifier, + isLocalNumber: Bool, transaction: YapDatabaseReadTransaction) -> UnidentifiedAccessMode { + let defaultValue: UnidentifiedAccessMode = isLocalNumber ? .enabled : .unknown guard let existingRawValue = transaction.object(forKey: recipientId, inCollection: kUnidentifiedAccessCollection) as? Int else { - return .unknown + return defaultValue } guard let existingValue = UnidentifiedAccessMode(rawValue: existingRawValue) else { - return .unknown + return defaultValue } return existingValue } @objc public func unidentifiedAccessMode(forRecipientId recipientId: RecipientIdentifier) -> UnidentifiedAccessMode { + var isLocalNumber = false + if let localNumber = tsAccountManager.localNumber() { + isLocalNumber = recipientId == localNumber + } + var mode: UnidentifiedAccessMode = .unknown dbConnection.read { (transaction) in - mode = self.unidentifiedAccessMode(forRecipientId: recipientId, transaction: transaction) + mode = self.unidentifiedAccessMode(forRecipientId: recipientId, isLocalNumber: isLocalNumber, transaction: transaction) } return mode } @objc public func setUnidentifiedAccessMode(_ mode: UnidentifiedAccessMode, recipientId: String) { + var isLocalNumber = false if let localNumber = tsAccountManager.localNumber() { if recipientId == localNumber { Logger.info("Setting local UD access mode: \(string(forUnidentifiedAccessMode: mode))") + isLocalNumber = true } } dbConnection.readWrite { (transaction) in - let oldMode = self.unidentifiedAccessMode(forRecipientId: recipientId, transaction: transaction) + let oldMode = self.unidentifiedAccessMode(forRecipientId: recipientId, isLocalNumber: isLocalNumber, transaction: transaction) transaction.setObject(mode.rawValue as Int, forKey: recipientId, inCollection: self.kUnidentifiedAccessCollection) @@ -241,29 +245,33 @@ public class OWSUDManagerImpl: NSObject, OWSUDManager { // Returns the UD access key for sending to a given recipient. @objc - public func udAccess(forRecipientId recipientId: RecipientIdentifier) -> OWSUDAccess? { - // This check is currently redundant with the "send access key for local number" - // check below, but behavior of isUDEnabled() may change. + public func udAccess(forRecipientId recipientId: RecipientIdentifier, + requireSyncAccess: Bool) -> OWSUDAccess? { guard isUDEnabled() else { if isUDVerboseLoggingEnabled() { Logger.info("UD Send disabled for \(recipientId), UD disabled.") } return nil } - guard let localNumber = tsAccountManager.localNumber() else { - if isUDVerboseLoggingEnabled() { - Logger.info("UD Send disabled for \(recipientId), no local number.") - } - return nil - } - if localNumber != recipientId { - guard udAccess(forRecipientId: localNumber) != nil else { + + if requireSyncAccess { + guard let localNumber = tsAccountManager.localNumber() else { if isUDVerboseLoggingEnabled() { - Logger.info("UD Send disabled for \(recipientId), UD disabled for sync messages.") + Logger.info("UD Send disabled for \(recipientId), no local number.") } return nil } + if localNumber != recipientId { + let selfAccessMode = unidentifiedAccessMode(forRecipientId: localNumber) + guard selfAccessMode != .disabled else { + if isUDVerboseLoggingEnabled() { + Logger.info("UD Send disabled for \(recipientId), UD disabled for sync messages.") + } + return nil + } + } } + let accessMode = unidentifiedAccessMode(forRecipientId: recipientId) if accessMode == .unrestricted { if let udAccessKey = udAccessKey(forRecipientId: recipientId) {