diff --git a/SignalMessaging/groups/GroupsV2Impl.swift b/SignalMessaging/groups/GroupsV2Impl.swift index 01cf4457ed..c2befda509 100644 --- a/SignalMessaging/groups/GroupsV2Impl.swift +++ b/SignalMessaging/groups/GroupsV2Impl.swift @@ -1163,8 +1163,10 @@ public class GroupsV2Impl: NSObject, GroupsV2Swift { } @objc - public func tryToEnsureProfileKeyCredentialsObjc(for addresses: [SignalServiceAddress]) -> AnyPromise { - return AnyPromise(tryToEnsureProfileKeyCredentials(for: addresses)) + public func tryToEnsureProfileKeyCredentialsObjc(for addresses: [SignalServiceAddress], + ignoreMissingProfiles: Bool) -> AnyPromise { + return AnyPromise(tryToEnsureProfileKeyCredentials(for: addresses, + ignoreMissingProfiles: ignoreMissingProfiles)) } // When creating (or modifying) a v2 group, we need profile key @@ -1176,7 +1178,8 @@ public class GroupsV2Impl: NSObject, GroupsV2Swift { // one of the first things we do is decide whether to create a v1 // or v2 group. We have to create a v1 group unless we know the // uuid and profile key credential for all members. - public func tryToEnsureProfileKeyCredentials(for addresses: [SignalServiceAddress]) -> Promise { + public func tryToEnsureProfileKeyCredentials(for addresses: [SignalServiceAddress], + ignoreMissingProfiles: Bool) -> Promise { var uuidsWithoutProfileKeyCredentials = [UUID]() databaseStorage.read { transaction in @@ -1197,15 +1200,26 @@ public class GroupsV2Impl: NSObject, GroupsV2Swift { return Promise.value(()) } - var promises = [Promise]() + var promises = [Promise]() for uuid in uuidsWithoutProfileKeyCredentials { let address = SignalServiceAddress(uuid: uuid) - promises.append(ProfileFetcherJob.fetchProfilePromise(address: address, - mainAppOnly: false, - ignoreThrottling: true, - fetchType: .versioned)) + + let promise = firstly(on: .global()) { () -> Promise in + ProfileFetcherJob.fetchProfilePromise(address: address, + mainAppOnly: false, + ignoreThrottling: true, + fetchType: .versioned).asVoid() + }.recover(on: .global()) { (error: Error) -> Promise in + if case ProfileFetchError.missing = error, + ignoreMissingProfiles { + Logger.info("Ignoring missing profile: \(error)") + return Promise.value(()) + } + throw error + } + promises.append(promise) } - return when(fulfilled: promises).asVoid() + return when(fulfilled: promises) } // MARK: - Auth Credentials diff --git a/SignalMessaging/groups/GroupsV2Migration.swift b/SignalMessaging/groups/GroupsV2Migration.swift index d44242a6a2..b5e6b10051 100644 --- a/SignalMessaging/groups/GroupsV2Migration.swift +++ b/SignalMessaging/groups/GroupsV2Migration.swift @@ -592,7 +592,8 @@ fileprivate extension GroupsV2Migration { return firstly(on: .global()) { () -> Promise in GroupManager.tryToEnableGroupsV2(for: Array(membersToMigrate), isBlocking: true, ignoreErrors: true) }.then(on: .global()) { () throws -> Promise in - self.groupsV2.tryToEnsureProfileKeyCredentials(for: Array(membersToMigrate)) + self.groupsV2.tryToEnsureProfileKeyCredentials(for: Array(membersToMigrate), + ignoreMissingProfiles: true) }.then(on: .global()) { () throws -> Promise in guard let avatarData = unmigratedState.groupThread.groupModel.groupAvatarData else { // No avatar to upload. diff --git a/SignalMessaging/groups/GroupsV2OutgoingChangesImpl.swift b/SignalMessaging/groups/GroupsV2OutgoingChangesImpl.swift index ee556c5cc5..ae36d99330 100644 --- a/SignalMessaging/groups/GroupsV2OutgoingChangesImpl.swift +++ b/SignalMessaging/groups/GroupsV2OutgoingChangesImpl.swift @@ -359,7 +359,8 @@ public class GroupsV2OutgoingChangesImpl: NSObject, GroupsV2OutgoingChanges { let addressesForProfileKeyCredentials: [SignalServiceAddress] = uuidsForProfileKeyCredentials.map { SignalServiceAddress(uuid: $0) } return firstly { - groupsV2Impl.tryToEnsureProfileKeyCredentials(for: addressesForProfileKeyCredentials) + groupsV2Impl.tryToEnsureProfileKeyCredentials(for: addressesForProfileKeyCredentials, + ignoreMissingProfiles: false) }.then(on: .global()) { (_) -> Promise in groupsV2Impl.loadProfileKeyCredentialData(for: Array(uuidsForProfileKeyCredentials)) }.map(on: .global()) { (profileKeyCredentialMap: ProfileKeyCredentialMap) throws -> GroupsProtoGroupChangeActions in diff --git a/SignalServiceKit/src/groups/GroupManager.swift b/SignalServiceKit/src/groups/GroupManager.swift index 883684b600..b9b4b81c7f 100644 --- a/SignalServiceKit/src/groups/GroupManager.swift +++ b/SignalServiceKit/src/groups/GroupManager.swift @@ -328,7 +328,8 @@ public class GroupManager: NSObject { // try to obtain profile key credentials for all group members // including ourself, unless we already have them on hand. firstly { () -> Promise in - self.groupsV2.tryToEnsureProfileKeyCredentials(for: Array(groupMembership.allMembersOfAnyKind)) + self.groupsV2.tryToEnsureProfileKeyCredentials(for: Array(groupMembership.allMembersOfAnyKind), + ignoreMissingProfiles: false) }.map(on: .global()) { (_) -> GroupMembership in return groupMembership } diff --git a/SignalServiceKit/src/groups/GroupsV2.swift b/SignalServiceKit/src/groups/GroupsV2.swift index 3b4931f8f3..f2a41fb6a8 100644 --- a/SignalServiceKit/src/groups/GroupsV2.swift +++ b/SignalServiceKit/src/groups/GroupsV2.swift @@ -65,7 +65,8 @@ public protocol GroupsV2: AnyObject { func hasProfileKeyCredential(for address: SignalServiceAddress, transaction: SDSAnyReadTransaction) -> Bool - func tryToEnsureProfileKeyCredentialsObjc(for addresses: [SignalServiceAddress]) -> AnyPromise + func tryToEnsureProfileKeyCredentialsObjc(for addresses: [SignalServiceAddress], + ignoreMissingProfiles: Bool) -> AnyPromise func masterKeyData(forGroupModel groupModel: TSGroupModelV2) throws -> Data @@ -94,7 +95,8 @@ public protocol GroupsV2Swift: GroupsV2 { func createNewGroupOnService(groupModel: TSGroupModelV2, disappearingMessageToken: DisappearingMessageToken) -> Promise - func tryToEnsureProfileKeyCredentials(for addresses: [SignalServiceAddress]) -> Promise + func tryToEnsureProfileKeyCredentials(for addresses: [SignalServiceAddress], + ignoreMissingProfiles: Bool) -> Promise func fetchCurrentGroupV2Snapshot(groupModel: TSGroupModelV2) -> Promise @@ -515,11 +517,13 @@ public class MockGroupsV2: NSObject, GroupsV2Swift { owsFail("Not implemented.") } - public func tryToEnsureProfileKeyCredentialsObjc(for addresses: [SignalServiceAddress]) -> AnyPromise { + public func tryToEnsureProfileKeyCredentialsObjc(for addresses: [SignalServiceAddress], + ignoreMissingProfiles: Bool) -> AnyPromise { owsFail("Not implemented.") } - public func tryToEnsureProfileKeyCredentials(for addresses: [SignalServiceAddress]) -> Promise { + public func tryToEnsureProfileKeyCredentials(for addresses: [SignalServiceAddress], + ignoreMissingProfiles: Bool) -> Promise { owsFail("Not implemented.") }