@@ -246,103 +246,99 @@ class GroupManagerV2Impl @Inject constructor(
246246 memberInvites : List <MemberInvite >,
247247 isReinvite : Boolean
248248 ): Unit = scope.launchAndWait(group, if (isReinvite) " Reinvite members" else " Invite members" ) {
249- try {
250- val adminKey = requireAdminAccess(group)
251- val groupAuth = OwnedSwarmAuth .ofClosedGroup(group, adminKey)
252-
253- val batchRequests = mutableListOf<SnodeAPI .SnodeBatchRequestInfo >()
254-
255- val subAccountTokens = configFactory.withMutableGroupConfigs(group) { configs ->
256- val shareHistoryHexes = mutableListOf<String >()
257-
258- for ((id, shareHistory) in memberInvites) {
259- val hex = id.hexString
260-
261- val toSet = configs.groupMembers.get(hex)
262- ?.also { existing ->
263- val status = configs.groupMembers.status(existing)
264- if (status == GroupMember .Status .INVITE_FAILED || status == GroupMember .Status .INVITE_SENT ) {
265- existing.setSupplement(shareHistory)
266- }
267- }
268- ? : configs.groupMembers.getOrConstruct(hex).also { member ->
269- val contact = configFactory.withUserConfigs { it.contacts.get(hex) }
270- member.setName(contact?.name.orEmpty())
271- member.setProfilePic(contact?.profilePicture ? : UserPic .DEFAULT )
272- member.setSupplement(shareHistory)
273- }
274-
275- if (shareHistory) shareHistoryHexes + = hex
276-
277- toSet.setInvited()
278- configs.groupMembers.set(toSet)
279- }
280-
281- if (shareHistoryHexes.isNotEmpty()) {
282- val memberKey = configs.groupKeys.supplementFor(shareHistoryHexes)
283- batchRequests.add(
284- SnodeAPI .buildAuthenticatedStoreBatchInfo(
285- namespace = Namespace .GROUP_KEYS (),
286- message = SnodeMessage (
287- recipient = group.hexString,
288- data = Base64 .encodeBytes(memberKey),
289- ttl = SnodeMessage .CONFIG_TTL ,
290- timestamp = clock.currentTimeMills(),
291- ),
292- auth = groupAuth,
293- )
294- )
295- }
296-
297- configs.rekey()
298- memberInvites.map { configs.groupKeys.getSubAccountToken(it.id.hexString) }
299- }
300-
301- // Call un-revocate API on new members, in case they have been removed before
302- batchRequests + = SnodeAPI .buildAuthenticatedUnrevokeSubKeyBatchRequest(
303- groupAdminAuth = groupAuth,
304- subAccountTokens = subAccountTokens
305- )
306-
307- try {
308- val swarmNode = SnodeAPI .getSingleTargetSnode(group.hexString).await()
309- val response = SnodeAPI .getBatchResponse(swarmNode, group.hexString, batchRequests)
310-
311- // Make sure every request is successful
312- response.requireAllRequestsSuccessful(" Failed to invite members" )
313-
314- // Wait for the group configs to be pushed
315- configFactory.waitUntilGroupConfigsPushed(group)
316- } catch (e: Exception ) {
317- // Update every member's status to "invite failed" and return group name
318- val groupName = configFactory.withMutableGroupConfigs(group) { configs ->
319- for ((id, _) in memberInvites) {
320- configs.groupMembers.get(id.hexString)?.apply {
321- setInviteFailed()
322- configs.groupMembers.set(this )
323- }
324- }
325- configs.groupInfo.getName().orEmpty()
326- }
327-
328- Log .w(TAG , " Failed to invite members to group $group " , e)
329-
330- throw GroupInviteException (
331- isPromotion = false ,
332- inviteeAccountIds = memberInvites.map { it.id.hexString },
333- groupName = groupName,
334- underlying = e,
335- isReinvite = isReinvite
336- )
337- } finally {
338- // Send a group update message to the group telling members someone has been invited
339- if (! isReinvite) {
340- sendGroupUpdateForAddingMembers(group, adminKey, memberInvites.map { it.id })
341- }
342- }
343- }catch (e : Exception ){
344- Log .w(TAG , " Failed to invite members to group $group " , e)
345- }
249+ val adminKey = requireAdminAccess(group)
250+ val groupAuth = OwnedSwarmAuth .ofClosedGroup(group, adminKey)
251+
252+ val batchRequests = mutableListOf<SnodeAPI .SnodeBatchRequestInfo >()
253+
254+ val subAccountTokens = configFactory.withMutableGroupConfigs(group) { configs ->
255+ val shareHistoryHexes = mutableListOf<String >()
256+
257+ for ((id, shareHistory) in memberInvites) {
258+ val hex = id.hexString
259+
260+ val toSet = configs.groupMembers.get(hex)
261+ ?.also { existing ->
262+ val status = configs.groupMembers.status(existing)
263+ if (status == GroupMember .Status .INVITE_FAILED || status == GroupMember .Status .INVITE_SENT ) {
264+ existing.setSupplement(shareHistory)
265+ }
266+ }
267+ ? : configs.groupMembers.getOrConstruct(hex).also { member ->
268+ val contact = configFactory.withUserConfigs { it.contacts.get(hex) }
269+ member.setName(contact?.name.orEmpty())
270+ member.setProfilePic(contact?.profilePicture ? : UserPic .DEFAULT )
271+ member.setSupplement(shareHistory)
272+ }
273+
274+ if (shareHistory) shareHistoryHexes + = hex
275+
276+ toSet.setInvited()
277+ configs.groupMembers.set(toSet)
278+ }
279+
280+ if (shareHistoryHexes.isNotEmpty()) {
281+ val memberKey = configs.groupKeys.supplementFor(shareHistoryHexes)
282+ batchRequests.add(
283+ SnodeAPI .buildAuthenticatedStoreBatchInfo(
284+ namespace = Namespace .GROUP_KEYS (),
285+ message = SnodeMessage (
286+ recipient = group.hexString,
287+ data = Base64 .encodeBytes(memberKey),
288+ ttl = SnodeMessage .CONFIG_TTL ,
289+ timestamp = clock.currentTimeMills(),
290+ ),
291+ auth = groupAuth,
292+ )
293+ )
294+ }
295+
296+ configs.rekey()
297+ memberInvites.map { configs.groupKeys.getSubAccountToken(it.id.hexString) }
298+ }
299+
300+ // Call un-revocate API on new members, in case they have been removed before
301+ batchRequests + = SnodeAPI .buildAuthenticatedUnrevokeSubKeyBatchRequest(
302+ groupAdminAuth = groupAuth,
303+ subAccountTokens = subAccountTokens
304+ )
305+
306+ try {
307+ val swarmNode = SnodeAPI .getSingleTargetSnode(group.hexString).await()
308+ val response = SnodeAPI .getBatchResponse(swarmNode, group.hexString, batchRequests)
309+
310+ // Make sure every request is successful
311+ response.requireAllRequestsSuccessful(" Failed to invite members" )
312+
313+ // Wait for the group configs to be pushed
314+ configFactory.waitUntilGroupConfigsPushed(group)
315+ } catch (e: Exception ) {
316+ // Update every member's status to "invite failed" and return group name
317+ val groupName = configFactory.withMutableGroupConfigs(group) { configs ->
318+ for ((id, _) in memberInvites) {
319+ configs.groupMembers.get(id.hexString)?.apply {
320+ setInviteFailed()
321+ configs.groupMembers.set(this )
322+ }
323+ }
324+ configs.groupInfo.getName().orEmpty()
325+ }
326+
327+ Log .w(TAG , " Failed to invite members to group $group " , e)
328+
329+ throw GroupInviteException (
330+ isPromotion = false ,
331+ inviteeAccountIds = memberInvites.map { it.id.hexString },
332+ groupName = groupName,
333+ underlying = e,
334+ isReinvite = isReinvite
335+ )
336+ } finally {
337+ // Send a group update message to the group telling members someone has been invited
338+ if (! isReinvite) {
339+ sendGroupUpdateForAddingMembers(group, adminKey, memberInvites.map { it.id })
340+ }
341+ }
346342
347343 // Send the invitation message to the new members
348344 JobQueue .shared.add(
0 commit comments