2021-02-19 10:40:41 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Copyright 2020-2021 Signal Messenger, LLC
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-30 15:34:04 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// SPDX-License-Identifier: AGPL-3.0-only
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								import  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  compact , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Dictionary , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  difference , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  flatten , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  fromPairs , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  isNumber , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  values , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  from  'lodash' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  {  ClientZkGroupCipher  }  from  'zkgroup' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  {  v4  as  getGuid  }  from  'uuid' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								import  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  getCredentialsForToday , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GROUP_CREDENTIALS_KEY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  maybeFetchNewCredentials , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  from  './services/groupCredentialFetcher' ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  {  isStorageWriteFeatureEnabled  }  from  './storage/isFeatureEnabled' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  dataInterface  from  './sql/Client' ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  {  toWebSafeBase64 ,  fromWebSafeBase64  }  from  './util/webSafeBase64' ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  {  assert  }  from  './util/assert' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								import  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GroupV2MemberType , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  GroupV2PendingAdminApprovalType , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  GroupV2PendingMemberType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  MessageAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  from  './model-types.d' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  createProfileKeyCredentialPresentation , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  decryptGroupBlob , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  decryptProfileKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  decryptProfileKeyCredentialPresentation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  decryptUuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  deriveGroupID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  deriveGroupPublicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  deriveGroupSecretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  encryptGroupBlob , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  encryptUuid , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  getAuthCredentialPresentation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  getClientZkAuthOperations , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  getClientZkGroupCipher , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  getClientZkProfileOperations , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}  from  './util/zkgroup' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  arrayBufferToBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  arrayBufferToHex , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  base64ToArrayBuffer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  computeHash , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  deriveMasterKeyFromGroupV1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  fromEncodedBinaryToArrayBuffer , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  getRandomBytes , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								}  from  './Crypto' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  AccessRequiredEnum , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  GroupAttributeBlobClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GroupChangeClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GroupChangesClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GroupClass , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  GroupJoinInfoClass , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  MemberClass , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  MemberPendingAdminApprovalClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  MemberPendingProfileKeyClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ProtoBigNumberType , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  ProtoBinaryType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  from  './textsecure.d' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GroupCredentialsType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  GroupLogResponseType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  from  './textsecure/WebAPI' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								import  MessageSender ,  {  CallbackResultType  }  from  './textsecure/SendMessage' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								import  {  CURRENT_SCHEMA_VERSION  as  MAX_MESSAGE_SCHEMA  }  from  '../js/modules/types/message' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-24 13:57:54 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  {  ConversationModel  }  from  './models/conversations' ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								import  {  getGroupSizeHardLimit  }  from  './groups/limits' ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  {  joinViaLink  }  from  './groups/joinViaLink' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  type  GroupV2AccessCreateChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'create' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2AccessAttributesChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'access-attributes' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newPrivilege : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2AccessMembersChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'access-members' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newPrivilege : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  type  GroupV2AccessInviteLinkChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'access-invite-link' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newPrivilege : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2AvatarChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'avatar' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  removed : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2TitleChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'title' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Allow for null, because the title could be removed entirely
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newTitle? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  type  GroupV2GroupLinkAddChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'group-link-add' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  privilege : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2GroupLinkResetChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'group-link-reset' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2GroupLinkRemoveChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'group-link-remove' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// No disappearing messages timer change type - message.expirationTimerUpdate used instead
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2MemberAddChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'member-add' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2MemberAddFromInviteChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'member-add-from-invite' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-28 10:22:57 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  inviter? : string ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  type  GroupV2MemberAddFromLinkChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'member-add-from-link' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2MemberAddFromAdminApprovalChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'member-add-from-admin-approval' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2MemberPrivilegeChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'member-privilege' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newPrivilege : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2MemberRemoveChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'member-remove' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2PendingAddOneChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'pending-add-one' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2PendingAddManyChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'pending-add-many' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  count : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Note: pending-remove is only used if user didn't also join the group at the same time
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2PendingRemoveOneChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'pending-remove-one' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviter? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Note: pending-remove is only used if user didn't also join the group at the same time
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2PendingRemoveManyChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'pending-remove-many' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  count : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviter? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  type  GroupV2AdminApprovalAddOneChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'admin-approval-add-one' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Note: admin-approval-remove-one is only used if user didn't also join the group at
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//   the same time
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2AdminApprovalRemoveOneChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  type :  'admin-approval-remove-one' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviter? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2ChangeDetailType  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2AccessAttributesChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  |  GroupV2AccessCreateChangeType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2AccessInviteLinkChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2AccessMembersChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  |  GroupV2AdminApprovalAddOneChangeType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2AdminApprovalRemoveOneChangeType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2AvatarChangeType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2GroupLinkAddChangeType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2GroupLinkResetChangeType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2GroupLinkRemoveChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2MemberAddChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  |  GroupV2MemberAddFromAdminApprovalChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2MemberAddFromInviteChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  |  GroupV2MemberAddFromLinkChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2MemberPrivilegeChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  |  GroupV2MemberRemoveChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2PendingAddManyChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  |  GroupV2PendingAddOneChangeType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2PendingRemoveManyChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  |  GroupV2PendingRemoveOneChangeType 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  |  GroupV2TitleChangeType ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  type  GroupV2ChangeType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  from ? :  string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  details : Array < GroupV2ChangeDetailType > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  {  updateConversation  }  =  dataInterface ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								if  ( ! isNumber ( MAX_MESSAGE_SCHEMA ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    'groups.ts: Unable to capture max message schema from js/modules/types/message' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  MemberType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  profileKey : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuid : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  UpdatesResultType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // The array of new messages to be added into the message timeline
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChangeMessages : Array < MessageAttributesType > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // The set of members in the group, and we largely just pull profile keys for each,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   because the group membership is updated in newAttributes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  members : Array < MemberType > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // To be merged into the conversation model
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newAttributes : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								type  UploadedAvatarType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  data : ArrayBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  hash : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  key : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// Constants
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  const  MASTER_KEY_LENGTH  =  32 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-10 16:32:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  GROUP_TITLE_MAX_ENCRYPTED_BYTES  =  1024 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-16 13:34:41 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  const  ID_V1_LENGTH  =  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  const  ID_LENGTH  =  32 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								const  TEMPORAL_AUTH_REJECTED_CODE  =  401 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  GROUP_ACCESS_DENIED_CODE  =  403 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  GROUP_NONEXISTENT_CODE  =  404 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  SUPPORTED_CHANGE_EPOCH  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  const  LINK_VERSION_ERROR  =  'LINK_VERSION_ERROR' ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  GROUP_INVITE_LINK_PASSWORD_LENGTH  =  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// Group Links
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  generateGroupInviteLinkPassword ( ) :  ArrayBuffer  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  getRandomBytes ( GROUP_INVITE_LINK_PASSWORD_LENGTH ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Group Links
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  getPreJoinGroupInfo ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviteLinkPasswordBase64 : string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  masterKeyBase64 : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < GroupJoinInfoClass >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  data  =  window . Signal . Groups . deriveGroupFields ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    base64ToArrayBuffer ( masterKeyBase64 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId :  ` groupv2( ${ data . id } ) ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams : arrayBufferToBase64 ( data . publicParams ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams : arrayBufferToBase64 ( data . secretParams ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    request :  ( sender ,  options )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sender . getGroupFromLink ( inviteLinkPasswordBase64 ,  options ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildGroupLink ( conversation : ConversationModel ) :  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  masterKey ,  groupInviteLinkPassword  }  =  conversation . attributes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  subProto  =  new  window . textsecure . protobuf . GroupInviteLink . GroupInviteLinkContentsV1 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  subProto . groupMasterKey  =  window . Signal . Crypto . base64ToArrayBuffer ( masterKey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  subProto . inviteLinkPassword  =  window . Signal . Crypto . base64ToArrayBuffer ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupInviteLinkPassword 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  proto  =  new  window . textsecure . protobuf . GroupInviteLink ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  proto . v1Contents  =  subProto ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  bytes  =  proto . toArrayBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  hash  =  toWebSafeBase64 ( window . Signal . Crypto . arrayBufferToBase64 ( bytes ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-01 17:57:42 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  return  ` https://signal.group/# ${ hash } ` ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  parseGroupLink ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  hash : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  {  masterKey : string ;  inviteLinkPassword : string  }  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  base64  =  fromWebSafeBase64 ( hash ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  buffer  =  base64ToArrayBuffer ( base64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  inviteLinkProto  =  window . textsecure . protobuf . GroupInviteLink . decode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    buffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    inviteLinkProto . contents  !==  'v1Contents'  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ! inviteLinkProto . v1Contents 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  error  =  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'parseGroupLink: Parsed proto is missing v1Contents' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    error . name  =  LINK_VERSION_ERROR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! hasData ( inviteLinkProto . v1Contents . groupMasterKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'v1Contents.groupMasterKey had no data!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! hasData ( inviteLinkProto . v1Contents . inviteLinkPassword ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'v1Contents.inviteLinkPassword had no data!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKey : string  =  inviteLinkProto . v1Contents . groupMasterKey . toString ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    'base64' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( masterKey . length  !==  44 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( ` masterKey had unexpected length  ${ masterKey . length } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  inviteLinkPassword : string  =  inviteLinkProto . v1Contents . inviteLinkPassword . toString ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    'base64' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( inviteLinkPassword . length  ===  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` inviteLinkPassword had unexpected length  ${ inviteLinkPassword . length } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  {  masterKey ,  inviteLinkPassword  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Group Modifications
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								async  function  uploadAvatar ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  options :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  &  ( {  path : string  }  |  {  data : ArrayBuffer  } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < UploadedAvatarType >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  logId ,  publicParams ,  secretParams  }  =  options ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  clientZkGroupCipher  =  getClientZkGroupCipher ( secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    let  data : ArrayBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( 'data'  in  options )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ( {  data  }  =  options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      data  =  await  window . Signal . Migrations . readAttachmentData ( options . path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  hash  =  await  computeHash ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  blob  =  new  window . textsecure . protobuf . GroupAttributeBlob ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    blob . avatar  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  blobPlaintext  =  blob . toArrayBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  ciphertext  =  encryptGroupBlob ( clientZkGroupCipher ,  blobPlaintext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  key  =  await  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      logId :  ` uploadGroupAvatar/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      secretParams , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      request :  ( sender ,  requestOptions )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sender . uploadGroupAvatar ( ciphertext ,  requestOptions ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      data , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      hash , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      key , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` uploadAvatar/ ${ logId }  Failed to upload avatar ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      error . stack 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 13:16:56 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function  buildGroupTitleBuffer ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  clientZkGroupCipher : ClientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  title : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  ArrayBuffer  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  titleBlob  =  new  window . textsecure . protobuf . GroupAttributeBlob ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  titleBlob . title  =  title ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  titleBlobPlaintext  =  titleBlob . toArrayBuffer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-10 16:32:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  result  =  encryptGroupBlob ( clientZkGroupCipher ,  titleBlobPlaintext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( result . byteLength  >  GROUP_TITLE_MAX_ENCRYPTED_BYTES )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'buildGroupTitleBuffer: encrypted group title is too long' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 13:16:56 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function  buildGroupProto ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  attributes : Pick < 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'accessControl' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'expireTimer' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'id' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'membersV2' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'name' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'pendingMembersV2' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'publicParams' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'revision' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    |  'secretParams' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  >  &  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    avatarUrl? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  GroupClass  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ACCESS_ENUM  =  window . textsecure . protobuf . AccessControl . AccessRequired ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  ` groupv2( ${ attributes . id } ) ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  publicParams ,  secretParams  }  =  attributes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! publicParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildGroupProto/ ${ logId } : attributes were missing publicParams! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildGroupProto/ ${ logId } : attributes were missing secretParams! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  serverPublicParamsBase64  =  window . getServerPublicParams ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkProfileCipher  =  getClientZkProfileOperations ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  proto  =  new  window . textsecure . protobuf . Group ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  proto . publicKey  =  base64ToArrayBuffer ( publicParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  proto . version  =  attributes . revision  ||  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 13:16:56 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( attributes . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    proto . title  =  buildGroupTitleBuffer ( clientZkGroupCipher ,  attributes . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( attributes . avatarUrl )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    proto . avatar  =  attributes . avatarUrl ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( attributes . expireTimer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  timerBlob  =  new  window . textsecure . protobuf . GroupAttributeBlob ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    timerBlob . disappearingMessagesDuration  =  attributes . expireTimer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  timerBlobPlaintext  =  timerBlob . toArrayBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    proto . disappearingMessagesTimer  =  encryptGroupBlob ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      timerBlobPlaintext 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  accessControl  =  new  window . textsecure . protobuf . AccessControl ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( attributes . accessControl )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    accessControl . attributes  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      attributes . accessControl . attributes  ||  ACCESS_ENUM . MEMBER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    accessControl . members  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      attributes . accessControl . members  ||  ACCESS_ENUM . MEMBER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    accessControl . attributes  =  ACCESS_ENUM . MEMBER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    accessControl . members  =  ACCESS_ENUM . MEMBER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  proto . accessControl  =  accessControl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  proto . members  =  ( attributes . membersV2  ||  [ ] ) . map ( item  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  member  =  new  window . textsecure . protobuf . Member ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  conversation  =  window . ConversationController . get ( item . conversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! conversation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( ` buildGroupProto/ ${ logId } : no conversation for member! ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  profileKeyCredentialBase64  =  conversation . get ( 'profileKeyCredential' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! profileKeyCredentialBase64 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-01 13:55:49 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ` buildGroupProto/ ${ logId } : member was missing profileKeyCredential! ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  presentation  =  createProfileKeyCredentialPresentation ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      clientZkProfileCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      profileKeyCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      secretParams 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    member . role  =  item . role  ||  MEMBER_ROLE_ENUM . DEFAULT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    member . presentation  =  presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildGroupProto/ ${ logId } : unable to find our own conversationId! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  me  =  window . ConversationController . get ( ourConversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! me )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildGroupProto/ ${ logId } : unable to find our own conversation! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourUuid  =  me . get ( 'uuid' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! ourUuid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( ` buildGroupProto/ ${ logId } : unable to find our own uuid! ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourUuidCipherTextBuffer  =  encryptUuid ( clientZkGroupCipher ,  ourUuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  proto . membersPendingProfileKey  =  ( attributes . pendingMembersV2  ||  [ ] ) . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    item  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  pendingMember  =  new  window . textsecure . protobuf . MemberPendingProfileKey ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  member  =  new  window . textsecure . protobuf . Member ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      const  conversation  =  window . ConversationController . get ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        item . conversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! conversation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 'buildGroupProto: no conversation for pending member!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      const  uuid  =  conversation . get ( 'uuid' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! uuid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 'buildGroupProto: pending member was missing uuid!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      const  uuidCipherTextBuffer  =  encryptUuid ( clientZkGroupCipher ,  uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . userId  =  uuidCipherTextBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . role  =  item . role  ||  MEMBER_ROLE_ENUM . DEFAULT ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      pendingMember . member  =  member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      pendingMember . timestamp  =  item . timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      pendingMember . addedByUserId  =  ourUuidCipherTextBuffer ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      return  pendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  proto ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-11 15:29:31 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  async  function  buildAddMembersChange ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : Pick < 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    'id'  |  'publicParams'  |  'revision'  |  'secretParams' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationIds : ReadonlyArray < string > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < undefined  |  GroupChangeClass.Actions >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  id ,  publicParams ,  revision ,  secretParams  }  =  conversation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  ` groupv2( ${ id } ) ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! publicParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildAddMembersChange/ ${ logId } : attributes were missing publicParams! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildAddMembersChange/ ${ logId } : attributes were missing secretParams! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  newGroupVersion  =  ( revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  serverPublicParamsBase64  =  window . getServerPublicParams ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkProfileCipher  =  getClientZkProfileOperations ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationIdOrThrow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversation  =  window . ConversationController . get ( ourConversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourUuid  =  ourConversation ? . get ( 'uuid' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! ourUuid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildAddMembersChange/ ${ logId } : unable to find our own UUID! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourUuidCipherTextBuffer  =  encryptUuid ( clientZkGroupCipher ,  ourUuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  now  =  Date . now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  addMembers : Array < GroupChangeClass.Actions.AddMemberAction >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  addPendingMembers : Array < GroupChangeClass.Actions.AddMemberPendingProfileKeyAction >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  Promise . all ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversationIds . map ( async  conversationId  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  contact  =  window . ConversationController . get ( conversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! contact )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` buildAddMembersChange/ ${ logId } : missing local contact, skipping ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  uuid  =  contact . get ( 'uuid' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! uuid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( false ,  ` buildAddMembersChange/ ${ logId } : missing UUID; skipping ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // Refresh our local data to be sure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ! contact . get ( 'capabilities' ) ? . gv2  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ! contact . get ( 'profileKey' )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ! contact . get ( 'profileKeyCredential' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        await  contact . getProfiles ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! contact . get ( 'capabilities' ) ? . gv2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` buildAddMembersChange/ ${ logId } : member is missing GV2 capability; skipping ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  profileKey  =  contact . get ( 'profileKey' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  profileKeyCredential  =  contact . get ( 'profileKeyCredential' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! profileKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` buildAddMembersChange/ ${ logId } : member is missing profile key; skipping ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  member  =  new  window . textsecure . protobuf . Member ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . userId  =  encryptUuid ( clientZkGroupCipher ,  uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . role  =  MEMBER_ROLE_ENUM . DEFAULT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . joinedAtVersion  =  newGroupVersion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // This is inspired by [Android's equivalent code][0].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // [0]: https://github.com/signalapp/Signal-Android/blob/2be306867539ab1526f0e49d1aa7bd61e783d23f/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/GroupsV2Operations.java#L152-L174
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( profileKey  &&  profileKeyCredential )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        member . presentation  =  createProfileKeyCredentialPresentation ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          clientZkProfileCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          profileKeyCredential , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          secretParams 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  addMemberAction  =  new  window . textsecure . protobuf . GroupChange . Actions . AddMemberAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addMemberAction . added  =  member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addMemberAction . joinFromInviteLink  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addMembers . push ( addMemberAction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  memberPendingProfileKey  =  new  window . textsecure . protobuf . MemberPendingProfileKey ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        memberPendingProfileKey . member  =  member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        memberPendingProfileKey . addedByUserId  =  ourUuidCipherTextBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        memberPendingProfileKey . timestamp  =  now ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  addPendingMemberAction  =  new  window . textsecure . protobuf . GroupChange . Actions . AddMemberPendingProfileKeyAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addPendingMemberAction . added  =  memberPendingProfileKey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addPendingMembers . push ( addPendingMemberAction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! addMembers . length  &&  ! addPendingMembers . length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // This shouldn't happen. When these actions are passed to `modifyGroupV2`, a warning
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   will be logged.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( addMembers . length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . addMembers  =  addMembers ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( addPendingMembers . length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . addPendingMembers  =  addPendingMembers ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  newGroupVersion ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-09 13:16:56 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  async  function  buildUpdateAttributesChange ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : Pick < 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    'id'  |  'revision'  |  'publicParams'  |  'secretParams' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  attributes : Readonly < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    avatar? : undefined  |  ArrayBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    title? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < undefined  |  GroupChangeClass.Actions >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  publicParams ,  secretParams ,  revision ,  id  }  =  conversation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  ` groupv2( ${ id } ) ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! publicParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildUpdateAttributesChange/ ${ logId } : attributes were missing publicParams! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` buildUpdateAttributesChange/ ${ logId } : attributes were missing secretParams! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  hasChangedSomething  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // There are three possible states here:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // 1. 'avatar' not in attributes: we don't want to change the avatar.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // 2. attributes.avatar === undefined: we want to clear the avatar.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // 3. attributes.avatar !== undefined: we want to update the avatar.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 'avatar'  in  attributes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    hasChangedSomething  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyAvatar  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyAvatarAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  avatar  }  =  attributes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( avatar )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  uploadedAvatar  =  await  uploadAvatar ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        data : avatar , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        logId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . modifyAvatar . avatar  =  uploadedAvatar . key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // If we don't set `actions.modifyAvatar.avatar`, it will be cleared.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  title  }  =  attributes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( title )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    hasChangedSomething  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyTitle  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyTitleAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyTitle . title  =  buildGroupTitleBuffer ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      title 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! hasChangedSomething )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // This shouldn't happen. When these actions are passed to `modifyGroupV2`, a warning
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   will be logged.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildDisappearingMessagesTimerChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  expireTimer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  expireTimer? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  blob  =  new  window . textsecure . protobuf . GroupAttributeBlob ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  blob . disappearingMessagesDuration  =  expireTimer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'buildDisappearingMessagesTimerChange: group was missing secretParams!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( group . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  blobPlaintext  =  blob . toArrayBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  blobCipherText  =  encryptGroupBlob ( clientZkGroupCipher ,  blobPlaintext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  timerAction  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyDisappearingMessagesTimerAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  timerAction . timer  =  blobCipherText ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyDisappearingMessagesTimer  =  timerAction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  buildInviteLinkPasswordChange ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviteLinkPassword : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  inviteLinkPasswordAction  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyInviteLinkPasswordAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviteLinkPasswordAction . inviteLinkPassword  =  base64ToArrayBuffer ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    inviteLinkPassword 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyInviteLinkPassword  =  inviteLinkPasswordAction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildNewGroupLinkChange ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviteLinkPassword : string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  addFromInviteLinkAccess : AccessRequiredEnum 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  accessControlAction  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyAddFromInviteLinkAccessControlAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  accessControlAction . addFromInviteLinkAccess  =  addFromInviteLinkAccess ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  inviteLinkPasswordAction  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyInviteLinkPasswordAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviteLinkPasswordAction . inviteLinkPassword  =  base64ToArrayBuffer ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    inviteLinkPassword 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyAddFromInviteLinkAccess  =  accessControlAction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyInviteLinkPassword  =  inviteLinkPasswordAction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildAccessControlAddFromInviteLinkChange ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  value : AccessRequiredEnum 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  accessControlAction  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyAddFromInviteLinkAccessControlAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  accessControlAction . addFromInviteLinkAccess  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyAddFromInviteLinkAccess  =  accessControlAction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildAccessControlAttributesChange ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  value : AccessRequiredEnum 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  accessControlAction  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyAttributesAccessControlAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  accessControlAction . attributesAccess  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyAttributesAccess  =  accessControlAction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildAccessControlMembersChange ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  value : AccessRequiredEnum 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  accessControlAction  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyMembersAccessControlAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  accessControlAction . membersAccess  =  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyMemberAccess  =  accessControlAction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								// TODO AND-1101
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildDeletePendingAdminApprovalMemberChange ( { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  uuid , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  uuid : string ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'buildDeletePendingAdminApprovalMemberChange: group was missing secretParams!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( group . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  uuidCipherTextBuffer  =  encryptUuid ( clientZkGroupCipher ,  uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  deleteMemberPendingAdminApproval  =  new  window . textsecure . protobuf . GroupChange . Actions . DeleteMemberPendingAdminApprovalAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  deleteMemberPendingAdminApproval . deletedUserId  =  uuidCipherTextBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . deleteMemberPendingAdminApprovals  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    deleteMemberPendingAdminApproval , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  buildAddPendingAdminApprovalMemberChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  profileKeyCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  profileKeyCredentialBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'buildAddPendingAdminApprovalMemberChange: group was missing secretParams!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkProfileCipher  =  getClientZkProfileOperations ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  addMemberPendingAdminApproval  =  new  window . textsecure . protobuf . GroupChange . Actions . AddMemberPendingAdminApprovalAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  presentation  =  createProfileKeyCredentialPresentation ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    clientZkProfileCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    profileKeyCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group . secretParams 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  added  =  new  window . textsecure . protobuf . MemberPendingAdminApproval ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  added . presentation  =  presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  addMemberPendingAdminApproval . added  =  added ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . addMemberPendingAdminApprovals  =  [ addMemberPendingAdminApproval ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildAddMember ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  profileKeyCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  profileKeyCredentialBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  joinFromInviteLink? : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'buildAddMember: group was missing secretParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkProfileCipher  =  getClientZkProfileOperations ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  addMember  =  new  window . textsecure . protobuf . GroupChange . Actions . AddMemberAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  presentation  =  createProfileKeyCredentialPresentation ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    clientZkProfileCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    profileKeyCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group . secretParams 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  added  =  new  window . textsecure . protobuf . Member ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  added . presentation  =  presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  added . role  =  MEMBER_ROLE_ENUM . DEFAULT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  addMember . added  =  added ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . addMembers  =  [ addMember ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  buildDeletePendingMemberChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuids , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuids : Array < string > ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'buildDeletePendingMemberChange: group was missing secretParams!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( group . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  deletePendingMembers  =  uuids . map ( uuid  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  uuidCipherTextBuffer  =  encryptUuid ( clientZkGroupCipher ,  uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  deletePendingMember  =  new  window . textsecure . protobuf . GroupChange . Actions . DeleteMemberPendingProfileKeyAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    deletePendingMember . deletedUserId  =  uuidCipherTextBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  deletePendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  actions . deletePendingMembers  =  deletePendingMembers ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildDeleteMemberChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuid : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'buildDeleteMemberChange: group was missing secretParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( group . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  uuidCipherTextBuffer  =  encryptUuid ( clientZkGroupCipher ,  uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  deleteMember  =  new  window . textsecure . protobuf . GroupChange . Actions . DeleteMemberAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  deleteMember . deletedUserId  =  uuidCipherTextBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . deleteMembers  =  [ deleteMember ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 16:19:24 -05:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  buildModifyMemberRoleChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  role , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuid : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  role : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'buildMakeAdminChange: group was missing secretParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( group . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  uuidCipherTextBuffer  =  encryptUuid ( clientZkGroupCipher ,  uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  toggleAdmin  =  new  window . textsecure . protobuf . GroupChange . Actions . ModifyMemberRoleAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  toggleAdmin . userId  =  uuidCipherTextBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  toggleAdmin . role  =  role ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyMemberRoles  =  [ toggleAdmin ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  function  buildPromotePendingAdminApprovalMemberChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuid : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'buildAddPendingAdminApprovalMemberChange: group was missing secretParams!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( group . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  uuidCipherTextBuffer  =  encryptUuid ( clientZkGroupCipher ,  uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  promotePendingMember  =  new  window . textsecure . protobuf . GroupChange . Actions . PromoteMemberPendingAdminApprovalAction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  promotePendingMember . userId  =  uuidCipherTextBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  promotePendingMember . role  =  MEMBER_ROLE_ENUM . DEFAULT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . promoteMemberPendingAdminApprovals  =  [ promotePendingMember ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  buildPromoteMemberChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  profileKeyCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  profileKeyCredentialBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  actions  =  new  window . textsecure . protobuf . GroupChange . Actions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'buildDisappearingMessagesTimerChange: group was missing secretParams!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkProfileCipher  =  getClientZkProfileOperations ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  presentation  =  createProfileKeyCredentialPresentation ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    clientZkProfileCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    profileKeyCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group . secretParams 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  promotePendingMember  =  new  window . textsecure . protobuf . GroupChange . Actions . PromoteMemberPendingProfileKeyAction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  promotePendingMember . presentation  =  presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . version  =  ( group . revision  ||  0 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . promotePendingMembers  =  [ promotePendingMember ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  uploadGroupChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  inviteLinkPassword , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions : GroupChangeClass.Actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  inviteLinkPassword? : string ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < GroupChangeClass >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Ensure we have the credentials we need before attempting GroupsV2 operations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  maybeFetchNewCredentials ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'uploadGroupChange: group was missing secretParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . publicParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'uploadGroupChange: group was missing publicParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  return  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId :  ` uploadGroupChange/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams : group.publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams : group.secretParams , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    request :  ( sender ,  options )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sender . modifyGroup ( actions ,  options ,  inviteLinkPassword ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  async  function  modifyGroupV2 ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  createGroupChange , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-24 14:28:55 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  extraConversationsForSend , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  inviteLinkPassword , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  createGroupChange :  ( )  = >  Promise < GroupChangeClass.Actions  |  undefined > ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-24 14:28:55 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  extraConversationsForSend? : Array < string > ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  inviteLinkPassword? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  name : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  idLog  =  ` ${ name } / ${ conversation . idForLogging ( ) } ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! conversation . isGroupV2 ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` modifyGroupV2/ ${ idLog } : Called for non-GroupV2 conversation ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ONE_MINUTE  =  1000  *  60 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  startTime  =  Date . now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  timeoutTime  =  startTime  +  ONE_MINUTE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  MAX_ATTEMPTS  =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  for  ( let  attempt  =  0 ;  attempt  <  MAX_ATTEMPTS ;  attempt  +=  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . info ( ` modifyGroupV2/ ${ idLog } : Starting attempt  ${ attempt } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // eslint-disable-next-line no-await-in-loop
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      await  window . waitForEmptyEventQueue ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . info ( ` modifyGroupV2/ ${ idLog } : Queuing attempt  ${ attempt } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // eslint-disable-next-line no-await-in-loop
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      await  conversation . queueJob ( async  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . info ( ` modifyGroupV2/ ${ idLog } : Running attempt  ${ attempt } ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  actions  =  await  createGroupChange ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! actions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` modifyGroupV2/ ${ idLog } : No change actions. Returning early. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // The new revision has to be exactly one more than the current revision
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //   or it won't upload properly, and it won't apply in maybeUpdateGroup
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  currentRevision  =  conversation . get ( 'revision' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  newRevision  =  actions . version ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( currentRevision  ||  0 )  +  1  !==  newRevision )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` modifyGroupV2/ ${ idLog } : Revision mismatch -  ${ currentRevision }  to  ${ newRevision } . ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Upload. If we don't have permission, the server will return an error here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  groupChange  =  await  window . Signal . Groups . uploadGroupChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          actions , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          inviteLinkPassword , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          group : conversation.attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  groupChangeBuffer  =  groupChange . toArrayBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  groupChangeBase64  =  arrayBufferToBase64 ( groupChangeBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Apply change locally, just like we would with an incoming change. This will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //   change conversation state and add change notifications to the timeline.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        await  window . Signal . Groups . maybeUpdateGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          groupChangeBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Send message to notify group members (including pending members) of change
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  profileKey  =  conversation . get ( 'profileSharing' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ?  window . storage . get ( 'profileKey' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          :  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  sendOptions  =  conversation . getSendOptions ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  timestamp  =  Date . now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  promise  =  conversation . wrapSend ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . textsecure . messaging . sendMessageToGroup ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              groupV2 : conversation.getGroupV2Info ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                groupChange : groupChangeBuffer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                includePendingMembers : true , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-24 14:28:55 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                extraConversationsForSend , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								              } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              profileKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            sendOptions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // We don't save this message; we just use it to ensure that a sync message is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //   sent to our linked devices.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  m  =  new  window . Whisper . Message ( ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId : conversation.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          type :  'not-to-save' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          sent_at : timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          received_at : timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          // TODO: DESKTOP-722
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          // this type does not fully implement the interface it is expected to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  as  unknown )  as  MessageAttributesType ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // This is to ensure that the functions in send() and sendSyncMessage()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        //   don't save anything to the database.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        m . doNotSave  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        await  m . send ( promise ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // If we've gotten here with no error, we exit!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` modifyGroupV2/ ${ idLog } : Update complete, with attempt  ${ attempt } ! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( error . code  ===  409  &&  Date . now ( )  <=  timeoutTime )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` modifyGroupV2/ ${ idLog } : Conflict while updating. Trying again... ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // eslint-disable-next-line no-await-in-loop
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        await  conversation . fetchLatestGroupV2Data ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  if  ( error . code  ===  409 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` modifyGroupV2/ ${ idLog } : Conflict while updating. Timed out; not retrying. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // We don't wait here because we're breaking out of the loop immediately.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        conversation . fetchLatestGroupV2Data ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  errorString  =  error  &&  error . stack  ?  error.stack  : error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` modifyGroupV2/ ${ idLog } : Error updating:  ${ errorString } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// Utility
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  idForLogging ( groupId : string  |  undefined ) :  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  ` groupv2( ${ groupId } ) ` ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  deriveGroupFields ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  masterKey : ArrayBuffer 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								) :  {  id : ArrayBuffer ;  secretParams : ArrayBuffer ;  publicParams : ArrayBuffer  }  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  secretParams  =  deriveGroupSecretParams ( masterKey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  publicParams  =  deriveGroupPublicParams ( secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  id  =  deriveGroupID ( secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-13 13:57:55 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								async  function  makeRequestWithTemporalRetry < T > ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  logId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  request , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  logId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  publicParams : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  secretParams : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  request :  ( sender : MessageSender ,  options : GroupCredentialsType )  = >  Promise < T > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < T >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  data  =  window . storage . get ( GROUP_CREDENTIALS_KEY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! data )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` makeRequestWithTemporalRetry/ ${ logId } : No group credentials! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupCredentials  =  getCredentialsForToday ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  sender  =  window . textsecure . messaging ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! sender )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` makeRequestWithTemporalRetry/ ${ logId } : textsecure.messaging is not available! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  todayOptions  =  getGroupCredentials ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    authCredentialBase64 : groupCredentials.today.credential , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupPublicParamsBase64 : publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupSecretParamsBase64 : secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 : window.getServerPublicParams ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  await  request ( sender ,  todayOptions ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( todayError )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( todayError . code  ===  TEMPORAL_AUTH_REJECTED_CODE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` makeRequestWithTemporalRetry/ ${ logId } : Trying again with tomorrow's credentials ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  tomorrowOptions  =  getGroupCredentials ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        authCredentialBase64 : groupCredentials.tomorrow.credential , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupPublicParamsBase64 : publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupSecretParamsBase64 : secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        serverPublicParamsBase64 : window.getServerPublicParams ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  request ( sender ,  tomorrowOptions ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  todayError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  fetchMembershipProof ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  publicParams : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  secretParams : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < string  |  undefined >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Ensure we have the credentials we need before attempting GroupsV2 operations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  maybeFetchNewCredentials ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! publicParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'fetchMembershipProof: group was missing publicParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'fetchMembershipProof: group was missing secretParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  response  =  await  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId :  'fetchMembershipProof' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    request :  ( sender ,  options )  = >  sender . getGroupMembershipToken ( options ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  response . token ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Creating a group
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  createGroupV2 ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  avatar , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationIds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  Readonly < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  name : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  avatar : undefined  |  ArrayBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationIds : Array < string > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} > ) :  Promise < ConversationModel >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Ensure we have the credentials we need before attempting GroupsV2 operations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  maybeFetchNewCredentials ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isStorageWriteFeatureEnabled ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'createGroupV2: storage service write is not enabled. Cannot create the group' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ACCESS_ENUM  =  window . textsecure . protobuf . AccessControl . AccessRequired ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKeyBuffer  =  getRandomBytes ( 32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  fields  =  deriveGroupFields ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupId  =  arrayBufferToBase64 ( fields . id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  ` groupv2( ${ groupId } ) ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKey  =  arrayBufferToBase64 ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  secretParams  =  arrayBufferToBase64 ( fields . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  publicParams  =  arrayBufferToBase64 ( fields . publicParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationIdOrThrow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversation  =  window . ConversationController . get ( ourConversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! ourConversation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` createGroupV2/ ${ logId } : cannot get our own conversation. Cannot create the group ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  membersV2 : Array < GroupV2MemberType >  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversationId : ourConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      role : MEMBER_ROLE_ENUM.ADMINISTRATOR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      joinedAtVersion : 0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  pendingMembersV2 : Array < GroupV2PendingMemberType >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  uploadedAvatar : undefined  |  UploadedAvatarType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  Promise . all ( [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . conversationIds . map ( async  conversationId  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  contact  =  window . ConversationController . get ( conversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! contact )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` createGroupV2/ ${ logId } : missing local contact, skipping ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! contact . get ( 'uuid' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( false ,  ` createGroupV2/ ${ logId } : missing UUID; skipping ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // Refresh our local data to be sure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ! contact . get ( 'capabilities' ) ? . gv2  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ! contact . get ( 'profileKey' )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ! contact . get ( 'profileKeyCredential' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        await  contact . getProfiles ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! contact . get ( 'capabilities' ) ? . gv2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` createGroupV2/ ${ logId } : member is missing GV2 capability; skipping ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( contact . get ( 'profileKey' )  &&  contact . get ( 'profileKeyCredential' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        membersV2 . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          role : MEMBER_ROLE_ENUM.DEFAULT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          joinedAtVersion : 0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pendingMembersV2 . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          addedByUserId : ourConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          timestamp : Date.now ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          role : MEMBER_ROLE_ENUM.DEFAULT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( async  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! avatar )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      uploadedAvatar  =  await  uploadAvatar ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        data : avatar , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        logId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( membersV2 . length  +  pendingMembersV2 . length  >  getGroupSizeHardLimit ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` createGroupV2/ ${ logId } : Too many members! Member count:  ${ membersV2 . length } , Pending member count:  ${ pendingMembersV2 . length } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  protoAndConversationAttributes  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Core GroupV2 info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    revision : 0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // GroupV2 state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    accessControl :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      attributes : ACCESS_ENUM.MEMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      members : ACCESS_ENUM.MEMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      addFromInviteLink : ACCESS_ENUM.UNSATISFIABLE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    membersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pendingMembersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupProto  =  await  buildGroupProto ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    id : groupId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    avatarUrl : uploadedAvatar?.key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . protoAndConversationAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId :  ` createGroupV2/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    request :  ( sender ,  options )  = >  sender . createGroup ( groupProto ,  options ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  avatarAttribute : ConversationAttributesType [ 'avatar' ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( uploadedAvatar )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      avatarAttribute  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        url : uploadedAvatar.key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        path : await  window . Signal . Migrations . writeNewAttachmentData ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          uploadedAvatar . data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        hash : uploadedAvatar.hash , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` createGroupV2/ ${ logId } : avatar failed to save to disk. Continuing on ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  now  =  Date . now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  conversation  =  await  window . ConversationController . getOrCreateAndWait ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    'group' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . protoAndConversationAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      active_at : now , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      addedBy : ourConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      avatar : avatarAttribute , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupVersion : 2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      masterKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      profileSharing : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      timestamp : now , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      needsStorageServiceSync : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  conversation . queueJob ( ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . Signal . Services . storageServiceUploadJob ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  timestamp  =  Date . now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  profileKey  =  ourConversation . get ( 'profileKey' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupV2Info  =  conversation . getGroupV2Info ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    includePendingMembers : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  wrapWithSyncMessageSend ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId :  ` sendMessageToGroup/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    send : async  sender  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sender . sendMessageToGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupV2 : groupV2Info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        profileKey : profileKey  ?  base64ToArrayBuffer ( profileKey )  :  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  createdTheGroupMessage : MessageAttributesType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sourceUuid : conversation.ourUuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversationId : conversation.id , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-08 07:23:57 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    received_at : window.Signal.Util.incrementMessageCounter ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    received_at_ms : timestamp , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    sent_at : timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupV2Change :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      from :  ourConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      details :  [ {  type :  'create'  } ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  window . Signal . Data . saveMessages ( [ createdTheGroupMessage ] ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    forceSave : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  model  =  new  window . Whisper . Message ( createdTheGroupMessage ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  window . MessageController . register ( model . id ,  model ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation . trigger ( 'newmessage' ,  model ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  conversation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Migrating a group
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  hasV1GroupBeenMigrated ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < boolean >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  conversation . idForLogging ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  isGroupV1  =  conversation . isGroupV1 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isGroupV1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` checkForGV2Existence/ ${ logId } : Called for non-GroupV1 conversation! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Ensure we have the credentials we need before attempting GroupsV2 operations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  maybeFetchNewCredentials ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupId  =  conversation . get ( 'groupId' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! groupId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( ` checkForGV2Existence/ ${ logId } : No groupId! ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  idBuffer  =  fromEncodedBinaryToArrayBuffer ( groupId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKeyBuffer  =  await  deriveMasterKeyFromGroupV1 ( idBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  fields  =  deriveGroupFields ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    await  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      logId :  ` getGroup/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      publicParams : arrayBufferToBase64 ( fields . publicParams ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      secretParams : arrayBufferToBase64 ( fields . secretParams ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      request :  ( sender ,  options )  = >  sender . getGroup ( options ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  code  }  =  error ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-12 07:44:44 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  code  !==  GROUP_NONEXISTENT_CODE ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  maybeDeriveGroupV2Id ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < boolean >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  isGroupV1  =  conversation . isGroupV1 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupV1Id  =  conversation . get ( 'groupId' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  derived  =  conversation . get ( 'derivedGroupV2Id' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isGroupV1  ||  ! groupV1Id  ||  derived )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  v1IdBuffer  =  fromEncodedBinaryToArrayBuffer ( groupV1Id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKeyBuffer  =  await  deriveMasterKeyFromGroupV1 ( v1IdBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  fields  =  deriveGroupFields ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  derivedGroupV2Id  =  arrayBufferToBase64 ( fields . id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation . set ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    derivedGroupV2Id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  MigratePropsType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChangeBase64? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  receivedAt? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sentAt? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  isGroupEligibleToMigrate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < boolean >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! conversation . isGroupV1 ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  areWeMember  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ! conversation . get ( 'left' )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ourConversationId  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversation . hasMember ( ourConversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! areWeMember )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  members  =  conversation . get ( 'members' )  ||  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  for  ( let  i  =  0 ,  max  =  members . length ;  i  <  max ;  i  +=  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  identifier  =  members [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  contact  =  window . ConversationController . get ( identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! contact )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! contact . get ( 'uuid' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 08:42:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  async  function  getGroupMigrationMembers ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  droppedGV2MemberIds : Array < string > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  membersV2 : Array < GroupV2MemberType > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  pendingMembersV2 : Array < GroupV2PendingMemberType > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  previousGroupV1Members : Array < string > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  conversation . idForLogging ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` getGroupMigrationMembers/ ${ logId } : Couldn't fetch our own conversationId! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  areWeMember  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  areWeInvited  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  previousGroupV1Members  =  conversation . get ( 'members' )  ||  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  now  =  Date . now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  memberLookup : Record < string ,  boolean >  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  membersV2 : Array < GroupV2MemberType >  =  compact ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    await  Promise . all ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      previousGroupV1Members . map ( async  e164  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  contact  =  window . ConversationController . get ( e164 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! contact )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` getGroupMigrationMembers/ ${ logId } : membersV2 - missing local contact for  ${ e164 } , skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-12 07:44:44 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! contact . isMe ( )  &&  window . GV2_MIGRATION_DISABLE_ADD )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` getGroupMigrationMembers/ ${ logId } : membersV2 - skipping  ${ e164 }  due to GV2_MIGRATION_DISABLE_ADD flag ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 08:42:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( ! contact . get ( 'uuid' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` getGroupMigrationMembers/ ${ logId } : membersV2 - missing uuid for  ${ e164 } , skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! contact . get ( 'profileKey' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` getGroupMigrationMembers/ ${ logId } : membersV2 - missing profileKey for member  ${ e164 } , skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        let  capabilities  =  contact . get ( 'capabilities' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Refresh our local data to be sure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ! capabilities  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ! capabilities . gv2  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ! capabilities [ 'gv1-migration' ]  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ! contact . get ( 'profileKeyCredential' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          await  contact . getProfiles ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        capabilities  =  contact . get ( 'capabilities' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! capabilities  ||  ! capabilities . gv2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` getGroupMigrationMembers/ ${ logId } : membersV2 - member  ${ e164 }  is missing gv2 capability, skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! capabilities  ||  ! capabilities [ 'gv1-migration' ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` getGroupMigrationMembers/ ${ logId } : membersV2 - member  ${ e164 }  is missing gv1-migration capability, skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! contact . get ( 'profileKeyCredential' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` getGroupMigrationMembers/ ${ logId } : membersV2 - no profileKeyCredential for  ${ e164 } , skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  conversationId  =  contact . id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( conversationId  ===  ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          areWeMember  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        memberLookup [ conversationId ]  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          role : MEMBER_ROLE_ENUM.ADMINISTRATOR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          joinedAtVersion : 0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  droppedGV2MemberIds : Array < string >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  pendingMembersV2 : Array < GroupV2PendingMemberType >  =  compact ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( previousGroupV1Members  ||  [ ] ) . map ( e164  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  contact  =  window . ConversationController . get ( e164 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! contact )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` getGroupMigrationMembers/ ${ logId } : pendingMembersV2 - missing local contact for  ${ e164 } , skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  conversationId  =  contact . id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // If we've already added this contact above, we'll skip here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( memberLookup [ conversationId ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-12 07:44:44 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  ( ! contact . isMe ( )  &&  window . GV2_MIGRATION_DISABLE_INVITE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` getGroupMigrationMembers/ ${ logId } : pendingMembersV2 - skipping  ${ e164 }  due to GV2_MIGRATION_DISABLE_INVITE flag ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        droppedGV2MemberIds . push ( conversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 08:42:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  ( ! contact . get ( 'uuid' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` getGroupMigrationMembers/ ${ logId } : pendingMembersV2 - missing uuid for  ${ e164 } , skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        droppedGV2MemberIds . push ( conversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  capabilities  =  contact . get ( 'capabilities' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! capabilities  ||  ! capabilities . gv2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` getGroupMigrationMembers/ ${ logId } : pendingMembersV2 - member  ${ e164 }  is missing gv2 capability, skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        droppedGV2MemberIds . push ( conversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! capabilities  ||  ! capabilities [ 'gv1-migration' ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` getGroupMigrationMembers/ ${ logId } : pendingMembersV2 - member  ${ e164 }  is missing gv1-migration capability, skipping. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        droppedGV2MemberIds . push ( conversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( conversationId  ===  ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        areWeInvited  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        timestamp : now , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addedByUserId : ourConversationId , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        role : MEMBER_ROLE_ENUM.ADMINISTRATOR , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 08:42:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( ! areWeMember )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( ` getGroupMigrationMembers/ ${ logId } : We are not a member! ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( areWeInvited )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( ` getGroupMigrationMembers/ ${ logId } : We are invited! ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 08:42:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    droppedGV2MemberIds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    membersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pendingMembersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    previousGroupV1Members , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// This is called when the user chooses to migrate a GroupV1. It will update the server,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//   then let all members know about the new group.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  initiateMigrationToGroupV2 ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Ensure we have the credentials we need before attempting GroupsV2 operations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  maybeFetchNewCredentials ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  let  ourProfileKey : undefined  |  string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    await  conversation . queueJob ( async  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  ACCESS_ENUM  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . textsecure . protobuf . AccessControl . AccessRequired ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  isEligible  =  isGroupEligibleToMigrate ( conversation ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  previousGroupV1Id  =  conversation . get ( 'groupId' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! isEligible  ||  ! previousGroupV1Id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` initiateMigrationToGroupV2: conversation is not eligible to migrate!  ${ conversation . idForLogging ( ) } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  groupV1IdBuffer  =  fromEncodedBinaryToArrayBuffer ( previousGroupV1Id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  masterKeyBuffer  =  await  deriveMasterKeyFromGroupV1 ( groupV1IdBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  fields  =  deriveGroupFields ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  groupId  =  arrayBufferToBase64 ( fields . id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  logId  =  ` groupv2( ${ groupId } ) ` ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` initiateMigrationToGroupV2/ ${ logId } : Migrating from  ${ conversation . idForLogging ( ) } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  masterKey  =  arrayBufferToBase64 ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  secretParams  =  arrayBufferToBase64 ( fields . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  publicParams  =  arrayBufferToBase64 ( fields . publicParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` initiateMigrationToGroupV2/ ${ logId } : Couldn't fetch our own conversationId! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      const  ourConversation  =  window . ConversationController . get ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! ourConversation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` initiateMigrationToGroupV2/ ${ logId } : cannot get our own conversation. Cannot migrate ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ourProfileKey  =  ourConversation . get ( 'profileKey' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 08:42:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      const  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        membersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pendingMembersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        droppedGV2MemberIds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        previousGroupV1Members , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  =  await  getGroupMigrationMembers ( conversation ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        membersV2 . length  +  pendingMembersV2 . length  > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        getGroupSizeHardLimit ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 08:42:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` initiateMigrationToGroupV2/ ${ logId } : Too many members! Member count:  ${ membersV2 . length } , Pending member count:  ${ pendingMembersV2 . length } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      // Note: A few group elements don't need to change here:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      //   - name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      //   - expireTimer
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      let  avatarAttribute : ConversationAttributesType [ 'avatar' ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  avatarPath  =  conversation . attributes . avatar ? . path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( avatarPath )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  {  hash ,  key  }  =  await  uploadAvatar ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          logId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          path : avatarPath , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        avatarAttribute  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          url : key , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          path : avatarPath , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          hash , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  newAttributes  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        . . . conversation . attributes , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        avatar : avatarAttribute , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Core GroupV2 info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        revision : 0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupVersion : 2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        masterKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // GroupV2 state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        accessControl :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          attributes : ACCESS_ENUM.MEMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          members : ACCESS_ENUM.MEMBER , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          addFromInviteLink : ACCESS_ENUM.UNSATISFIABLE , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        membersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pendingMembersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Capture previous GroupV1 data for future use
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        previousGroupV1Id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        previousGroupV1Members , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Clear storage ID, since we need to start over on the storage service
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        storageID : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Clear obsolete data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        derivedGroupV2Id : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        members : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      const  groupProto  =  buildGroupProto ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        . . . newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        avatarUrl : avatarAttribute?.url , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        await  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          logId :  ` createGroup/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          request :  ( sender ,  options )  = >  sender . createGroup ( groupProto ,  options ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` initiateMigrationToGroupV2/ ${ logId } : Error creating group: ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          error . stack 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  groupChangeMessages : Array < MessageAttributesType >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeMessages . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        type :  'group-v1-migration' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        invitedGV2Members : pendingMembersV2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        droppedGV2MemberIds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      await  updateGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        updates :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          groupChangeMessages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          members :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( window . storage . isGroupBlocked ( previousGroupV1Id ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . storage . addBlockedGroup ( groupId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // Save these most recent updates to conversation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      updateConversation ( conversation . attributes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  logId  =  conversation . idForLogging ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! conversation . isGroupV1 ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  alreadyMigrated  =  await  hasV1GroupBeenMigrated ( conversation ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! alreadyMigrated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` initiateMigrationToGroupV2/ ${ logId } : Group has not already been migrated, re-throwing error ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    await  respondToGroupV2Migration ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // We've migrated the group, now we need to let all other group members know about it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  conversation . idForLogging ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  timestamp  =  Date . now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  wrapWithSyncMessageSend ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId :  ` sendMessageToGroup/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    send : async  sender  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // Minimal message to notify group members about migration
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sender . sendMessageToGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupV2 : conversation.getGroupV2Info ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          includePendingMembers : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        timestamp , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-03 14:09:58 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        profileKey : ourProfileKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ?  base64ToArrayBuffer ( ourProfileKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          :  undefined , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 16:02:50 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  async  function  wrapWithSyncMessageSend ( { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  logId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  send , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  logId : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  send :  ( sender : MessageSender )  = >  Promise < CallbackResultType  |  undefined > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  timestamp : number ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-09 16:02:50 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ) :  Promise < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  sender  =  window . textsecure . messaging ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! sender )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` initiateMigrationToGroupV2/ ${ logId } : textsecure.messaging is not available! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  response : CallbackResultType  |  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    response  =  await  send ( sender ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( conversation . processSendResponse ( error ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      response  =  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! response )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` wrapWithSyncMessageSend/ ${ logId } : message send didn't return result!! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Minimal implementation of sending same message to linked devices
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  dataMessage  }  =  response ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! dataMessage )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` wrapWithSyncMessageSend/ ${ logId } : dataMessage was not returned by send! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` wrapWithSyncMessageSend/ ${ logId } : Cannot get our conversationId! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversation  =  window . ConversationController . get ( ourConversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! ourConversation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` wrapWithSyncMessageSend/ ${ logId } : Cannot get our conversation! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  sender . sendSyncMessage ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dataMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ourConversation . get ( 'e164' ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ourConversation . get ( 'uuid' ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    null ,  // expirationStartTimestamp
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ ] ,  // sentTo
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    [ ] ,  // unidentifiedDeliveries
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    undefined ,  // isUpdate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    undefined  // options
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  waitThenRespondToGroupV2Migration ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  options : MigratePropsType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // First wait to process all incoming messages on the websocket
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  window . waitForEmptyEventQueue ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Then wait to process all outstanding messages for this conversation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  conversation  }  =  options ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  conversation . queueJob ( async  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // And finally try to migrate the group
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      await  respondToGroupV2Migration ( options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` waitThenRespondToGroupV2Migration/ ${ conversation . idForLogging ( ) } : respondToGroupV2Migration failure: ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  buildMigrationBubble ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  previousGroupV1MembersIds : Array < string > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newAttributes : ConversationAttributesType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  MessageAttributesType  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationIdOrThrow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Assemble items to commemorate this event for the timeline..
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  combinedConversationIds : Array < string >  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . ( newAttributes . membersV2  ||  [ ] ) . map ( item  = >  item . conversationId ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . ( newAttributes . pendingMembersV2  ||  [ ] ) . map ( item  = >  item . conversationId ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  droppedMemberIds : Array < string >  =  difference ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    previousGroupV1MembersIds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    combinedConversationIds 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) . filter ( id  = >  id  &&  id  !==  ourConversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  invitedMembers  =  ( newAttributes . pendingMembersV2  ||  [ ] ) . filter ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    item  = >  item . conversationId  !==  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  areWeInvited  =  ( newAttributes . pendingMembersV2  ||  [ ] ) . some ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    item  = >  item . conversationId  ===  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    type :  'group-v1-migration' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupMigration :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      areWeInvited , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      invitedMembers , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      droppedMemberIds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  joinGroupV2ViaLinkAndMigrate ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  approvalRequired , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviteLinkPassword , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  revision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  approvalRequired : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  inviteLinkPassword : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  revision : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  isGroupV1  =  conversation . isGroupV1 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  previousGroupV1Id  =  conversation . get ( 'groupId' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isGroupV1  ||  ! previousGroupV1Id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` joinGroupV2ViaLinkAndMigrate: Conversation is not GroupV1!  ${ conversation . idForLogging ( ) } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Derive GroupV2 fields
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupV1IdBuffer  =  fromEncodedBinaryToArrayBuffer ( previousGroupV1Id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKeyBuffer  =  await  deriveMasterKeyFromGroupV1 ( groupV1IdBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  fields  =  deriveGroupFields ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupId  =  arrayBufferToBase64 ( fields . id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( groupId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ` joinGroupV2ViaLinkAndMigrate/ ${ logId } : Migrating from  ${ conversation . idForLogging ( ) } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKey  =  arrayBufferToBase64 ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  secretParams  =  arrayBufferToBase64 ( fields . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  publicParams  =  arrayBufferToBase64 ( fields . publicParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // A mini-migration, which will not show dropped/invited members
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  newAttributes  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . conversation . attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Core GroupV2 info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    revision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupVersion : 2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    masterKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupInviteLinkPassword : inviteLinkPassword , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    left : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Capture previous GroupV1 data for future use
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    previousGroupV1Id : conversation.get ( 'groupId' ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    previousGroupV1Members : conversation.get ( 'members' ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Clear storage ID, since we need to start over on the storage service
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    storageID : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Clear obsolete data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    derivedGroupV2Id : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupChangeMessages  =  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-v1-migration' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupMigration :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        areWeInvited : false , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        invitedMembers :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        droppedMemberIds :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  updateGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    updates :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeMessages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      members :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Now things are set up, so we can go through normal channels
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  conversation . joinGroupV2ViaLink ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    inviteLinkPassword , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    approvalRequired , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// This may be called from storage service, an out-of-band check, or an incoming message.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//   If this is kicked off via an incoming message, we want to do the right thing and hit
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								//   the log endpoint - the parameters beyond conversation are needed in that scenario.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  respondToGroupV2Migration ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChangeBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  receivedAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sentAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  MigratePropsType ) :  Promise < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Ensure we have the credentials we need before attempting GroupsV2 operations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  maybeFetchNewCredentials ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  isGroupV1  =  conversation . isGroupV1 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  previousGroupV1Id  =  conversation . get ( 'groupId' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isGroupV1  ||  ! previousGroupV1Id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` respondToGroupV2Migration: Conversation is not GroupV1!  ${ conversation . idForLogging ( ) } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationIdOrThrow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  wereWePreviouslyAMember  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ! conversation . get ( 'left' )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ourConversationId  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversation . hasMember ( ourConversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Derive GroupV2 fields
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupV1IdBuffer  =  fromEncodedBinaryToArrayBuffer ( previousGroupV1Id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKeyBuffer  =  await  deriveMasterKeyFromGroupV1 ( groupV1IdBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  fields  =  deriveGroupFields ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupId  =  arrayBufferToBase64 ( fields . id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ` respondToGroupV2Migration/ ${ logId } : Migrating from  ${ conversation . idForLogging ( ) } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  masterKey  =  arrayBufferToBase64 ( masterKeyBuffer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  secretParams  =  arrayBufferToBase64 ( fields . secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  publicParams  =  arrayBufferToBase64 ( fields . publicParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  previousGroupV1Members  =  conversation . get ( 'members' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  previousGroupV1MembersIds  =  conversation . getMemberIds ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Skeleton of the new group state - not useful until we add the group's server state
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  attributes  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . conversation . attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Core GroupV2 info
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    revision : 0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupVersion : 2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    masterKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Capture previous GroupV1 data for future use
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    previousGroupV1Id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    previousGroupV1Members , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Clear storage ID, since we need to start over on the storage service
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    storageID : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Clear obsolete data
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    derivedGroupV2Id : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  firstGroupState : GroupClass  |  undefined  |  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  response : GroupLogResponseType  =  await  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      logId :  ` getGroupLog/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      request :  ( sender ,  options )  = >  sender . getGroupLog ( 0 ,  options ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Attempt to start with the first group state, only later processing future updates
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    firstGroupState  =  response ? . changes ? . groupChanges ? . [ 0 ] ? . groupState ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( error . code  ===  GROUP_ACCESS_DENIED_CODE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` respondToGroupV2Migration/ ${ logId } : Failed to access log endpoint; fetching full group state ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-12 07:44:44 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        firstGroupState  =  await  makeRequestWithTemporalRetry ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          logId :  ` getGroup/ ${ logId } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          request :  ( sender ,  options )  = >  sender . getGroup ( options ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  catch  ( secondError )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( secondError . code  ===  GROUP_ACCESS_DENIED_CODE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` respondToGroupV2Migration/ ${ logId } : Failed to access state endpoint; user is no longer part of group ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          // We don't want to add another event to the timeline
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          if  ( wereWePreviouslyAMember )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            const  ourNumber  =  window . textsecure . storage . user . getNumber ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            await  updateGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              receivedAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              sentAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              updates :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                newAttributes :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                  . . . conversation . attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                  left : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                  members :  ( conversation . get ( 'members' )  ||  [ ] ) . filter ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    item  = >  item  !==  ourConversationId  &&  item  !==  ourNumber 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                  ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                groupChangeMessages :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    groupV2Change :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      details :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          type :  'member-remove'  as  const , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          conversationId : ourConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                members :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  secondError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! firstGroupState )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` respondToGroupV2Migration/ ${ logId } : Couldn't get a first group state! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupState  =  decryptGroupState ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    firstGroupState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    attributes . secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  newAttributes  =  await  applyGroupState ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group : attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // Generate notifications into the timeline
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupChangeMessages : Array < MessageAttributesType >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChangeMessages . push ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    buildMigrationBubble ( previousGroupV1MembersIds ,  newAttributes ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  areWeInvited  =  ( newAttributes . pendingMembersV2  ||  [ ] ) . some ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    item  = >  item . conversationId  ===  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  areWeMember  =  ( newAttributes . membersV2  ||  [ ] ) . some ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    item  = >  item . conversationId  ===  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( ! areWeInvited  &&  ! areWeMember )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // Add a message to the timeline saying the user was removed. This shouldn't happen.
 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    groupChangeMessages . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupV2Change :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        details :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            type :  'member-remove'  as  const , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            conversationId : ourConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // This buffer ensures that all migration-related messages are sorted above
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   any initiating message. We need to do this because groupChangeMessages are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   already sorted via updates to sentAt inside of updateGroup().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  SORT_BUFFER  =  1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  updateGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    receivedAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sentAt : sentAt  ?  sentAt  -  SORT_BUFFER  : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    updates :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeMessages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      members :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( window . storage . isGroupBlocked ( previousGroupV1Id ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . storage . addBlockedGroup ( groupId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Save these most recent updates to conversation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  updateConversation ( conversation . attributes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Finally, check for any changes to the group since its initial creation using normal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   group update codepaths.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  maybeUpdateGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupChangeBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    receivedAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sentAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								// Fetching and applying group changes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  MaybeUpdatePropsType  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-24 13:57:54 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  groupChangeBase64? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision? : number ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 14:04:45 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  receivedAt? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sentAt? : number ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage? : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  async  function  waitThenMaybeUpdateGroup ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  options : MaybeUpdatePropsType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  // First wait to process all incoming messages on the websocket
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  window . waitForEmptyEventQueue ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Then wait to process all outstanding messages for this conversation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  conversation  }  =  options ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  conversation . queueJob ( async  ( )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // And finally try to update the group
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      await  maybeUpdateGroup ( options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` waitThenMaybeUpdateGroup/ ${ conversation . idForLogging ( ) } : maybeUpdateGroup failure: ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								export  async  function  maybeUpdateGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 14:04:45 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  groupChangeBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 14:04:45 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  receivedAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sentAt , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-16 07:22:46 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} :  MaybeUpdatePropsType ) :  Promise < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  conversation . idForLogging ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Ensure we have the credentials we need before attempting GroupsV2 operations
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    await  maybeFetchNewCredentials ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  updates  =  await  getGroupUpdates ( { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      group : conversation.attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      serverPublicParamsBase64 : window.getServerPublicParams ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      dropInitialJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    await  updateGroup ( {  conversation ,  receivedAt ,  sentAt ,  updates  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` maybeUpdateGroup/ ${ logId } : Failed to update group: ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								async  function  updateGroup ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  receivedAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sentAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  updates , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation : ConversationModel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  receivedAt? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sentAt? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  updates : UpdatesResultType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  newAttributes ,  groupChangeMessages ,  members  }  =  updates ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  startingRevision  =  conversation . get ( 'revision' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  endingRevision  =  newAttributes . revision ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  isInitialDataFetch  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ! isNumber ( startingRevision )  &&  isNumber ( endingRevision ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  isInGroup  =  ! updates . newAttributes . left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  justJoinedGroup  =  conversation . get ( 'left' )  &&  isInGroup ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Ensure that all generated messages are ordered properly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Before the provided timestamp so update messages appear before the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   initiating message, or after now().
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-17 15:48:58 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  finalReceivedAt  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    receivedAt  ||  window . Signal . Util . incrementMessageCounter ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  initialSentAt  =  sentAt  ||  Date . now ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // GroupV1 -> GroupV2 migration changes the groupId, and we need to update our id-based
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   lookups if there's a change on that field.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  previousId  =  conversation . get ( 'groupId' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  idChanged  =  previousId  &&  previousId  !==  newAttributes . groupId ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversation . set ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // We force this conversation into the left pane if this is the first time we've
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   fetched data about it, and we were able to fetch its name. Nobody likes to see
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   Unknown Group in the left pane.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    active_at : 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ( isInitialDataFetch  ||  justJoinedGroup )  &&  newAttributes . name 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-17 15:48:58 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ?  initialSentAt 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        :  newAttributes . active_at , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    temporaryMemberCount : isInGroup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ?  undefined 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      :  newAttributes . temporaryMemberCount , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( idChanged )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    conversation . trigger ( 'idUpdated' ,  conversation ,  'groupId' ,  previousId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // Save all synthetic messages describing group changes
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-17 15:48:58 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  let  syntheticSentAt  =  initialSentAt  -  ( groupChangeMessages . length  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  changeMessagesToSave  =  groupChangeMessages . map ( changeMessage  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // We do this to preserve the order of the timeline. We only update sentAt to ensure
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   that we don't stomp on messages received around the same time as the message
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   which initiated this group fetch and in-conversation messages.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    syntheticSentAt  +=  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . changeMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversationId : conversation.id , 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-17 15:48:58 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      received_at : finalReceivedAt , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      received_at_ms : syntheticSentAt , 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      sent_at : syntheticSentAt , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( changeMessagesToSave . length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    await  window . Signal . Data . saveMessages ( changeMessagesToSave ,  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      forceSave : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    changeMessagesToSave . forEach ( changeMessage  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  model  =  new  window . Whisper . Message ( changeMessage ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . MessageController . register ( model . id ,  model ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversation . trigger ( 'newmessage' ,  model ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Capture profile key for each member in the group, if we don't have it yet
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  members . forEach ( member  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  contact  =  window . ConversationController . get ( member . uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( member . profileKey  &&  contact  &&  ! contact . get ( 'profileKey' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      contact . setProfileKey ( member . profileKey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // No need for convo.updateLastMessage(), 'newmessage' handler does that
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								async  function  getGroupUpdates ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChangeBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage? : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChangeBase64? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision? : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  window . log . info ( ` getGroupUpdates/ ${ logId } : Starting... ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  currentRevision  =  group . revision ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  isFirstFetch  =  ! isNumber ( group . revision ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  isInitialCreationMessage  =  isFirstFetch  &&  newRevision  ===  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  weAreAwaitingApproval  =  ( group . pendingAdminApprovalV2  ||  [ ] ) . find ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    item  = >  item . conversationId  ===  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  isOneVersionUp  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    isNumber ( currentRevision )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    isNumber ( newRevision )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newRevision  ===  currentRevision  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    window . GV2_ENABLE_SINGLE_CHANGE_PROCESSING  && 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    groupChangeBase64  && 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    isNumber ( newRevision )  && 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ( isInitialCreationMessage  ||  weAreAwaitingApproval  ||  isOneVersionUp ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . info ( ` getGroupUpdates/ ${ logId } : Processing just one change ` ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  groupChangeBuffer  =  base64ToArrayBuffer ( groupChangeBase64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  groupChange  =  window . textsecure . protobuf . GroupChange . decode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeBuffer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:39:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  isChangeSupported  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ! isNumber ( groupChange . changeEpoch )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChange . changeEpoch  <=  SUPPORTED_CHANGE_EPOCH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( isChangeSupported )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      return  updateGroupViaSingleChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupChange , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:39:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` getGroupUpdates/ ${ logId } : Failing over; group change unsupported ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( isNumber ( newRevision )  &&  window . GV2_ENABLE_CHANGE_PROCESSING )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  result  =  await  updateGroupViaLogs ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( error . code  ===  TEMPORAL_AUTH_REJECTED_CODE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // We will fail over to the updateGroupViaState call below
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` getGroupUpdates/ ${ logId } : Temporal credential failure, now fetching full group state ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  if  ( error . code  ===  GROUP_ACCESS_DENIED_CODE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // We will fail over to the updateGroupViaState call below
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` getGroupUpdates/ ${ logId } : Log access denied, now fetching full group state ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( window . GV2_ENABLE_STATE_PROCESSING )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  updateGroupViaState ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      dropInitialJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ` getGroupUpdates/ ${ logId } : No processing was legal! Returning empty changeset. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newAttributes : group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupChangeMessages :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								async  function  updateGroupViaState ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage? : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  data  =  window . storage . get ( GROUP_CREDENTIALS_KEY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! data )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'updateGroupViaState: No group credentials!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupCredentials  =  getCredentialsForToday ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  stateOptions  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dropInitialJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    authCredentialBase64 : groupCredentials.today.credential , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` updateGroupViaState/ ${ logId } : Getting full group state... ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // We await this here so our try/catch below takes effect
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  result  =  await  getCurrentGroupState ( stateOptions ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( error . code  ===  GROUP_ACCESS_DENIED_CODE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  generateLeftGroupChanges ( group ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( error . code  ===  TEMPORAL_AUTH_REJECTED_CODE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` updateGroupViaState/ ${ logId } : Credential for today failed, failing over to tomorrow... ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  result  =  await  getCurrentGroupState ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          . . . stateOptions , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          authCredentialBase64 : groupCredentials.tomorrow.credential , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      }  catch  ( subError )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( subError . code  ===  GROUP_ACCESS_DENIED_CODE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								          return  generateLeftGroupChanges ( group ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  error ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								async  function  updateGroupViaSingleChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChange , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChange : GroupChangeClass ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  wasInGroup  =  ! group . left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  result : UpdatesResultType  =  await  integrateGroupChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupChange , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  nowInGroup  =  ! result . newAttributes . left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // If we were just added to the group (for example, via a join link), we go fetch the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   entire group state to make sure we're up to date.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! wasInGroup  &&  nowInGroup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  newAttributes ,  members  }  =  await  updateGroupViaState ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      group : result.newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // We discard any change events that come out of this full group fetch, but we do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   keep the final group attributes generated, as well as any new members.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . result , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      members :  [ . . . result . members ,  . . . members ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								async  function  updateGroupViaLogs ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  data  =  window . storage . get ( GROUP_CREDENTIALS_KEY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! data )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'getGroupUpdates: No group credentials!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupCredentials  =  getCredentialsForToday ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  deltaOptions  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    authCredentialBase64 : groupCredentials.today.credential , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` updateGroupViaLogs/ ${ logId } : Getting group delta from  ${ group . revision }  to  ${ newRevision }  for group groupv2( ${ group . groupId } )... ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  result  =  await  getGroupDelta ( deltaOptions ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( error . code  ===  TEMPORAL_AUTH_REJECTED_CODE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` updateGroupViaLogs/ ${ logId } : Credential for today failed, failing over to tomorrow... ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  getGroupDelta ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        . . . deltaOptions , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        authCredentialBase64 : groupCredentials.tomorrow.credential , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    throw  error ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								function  generateBasicMessage() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    id : getGuid ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    schemaVersion : MAX_MESSAGE_SCHEMA , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-24 13:57:54 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // this is missing most properties to fulfill this type
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  as  MessageAttributesType ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								async  function  generateLeftGroupChanges ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  window . log . info ( ` generateLeftGroupChanges/ ${ logId } : Starting... ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'generateLeftGroupChanges: We do not have a conversationId!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  masterKey ,  groupInviteLinkPassword  }  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  {  revision  }  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( masterKey  &&  groupInviteLinkPassword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` generateLeftGroupChanges/ ${ logId } : Have invite link. Attempting to fetch latest revision with it. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  preJoinInfo  =  await  getPreJoinGroupInfo ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupInviteLinkPassword , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        masterKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      revision  =  preJoinInfo . version ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'generateLeftGroupChanges: Failed to fetch latest revision via group link. Code:' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      error . code 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  existingMembers  =  group . membersV2  ||  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  newAttributes : ConversationAttributesType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    membersV2 : existingMembers.filter ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member  = >  member . conversationId  !==  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    left : true , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    revision , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  isNewlyRemoved  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    existingMembers . length  >  ( newAttributes . membersV2  ||  [ ] ) . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  youWereRemovedMessage  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupV2Change :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      details :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          type :  'member-remove'  as  const , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId : ourConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupChangeMessages : isNewlyRemoved  ?  [ youWereRemovedMessage ]  :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								function  getGroupCredentials ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  authCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupSecretParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  authCredentialBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupSecretParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  GroupCredentialsType  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  authOperations  =  getClientZkAuthOperations ( serverPublicParamsBase64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  presentation  =  getAuthCredentialPresentation ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    authOperations , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    authCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupSecretParamsBase64 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupPublicParamsHex : arrayBufferToHex ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      base64ToArrayBuffer ( groupPublicParamsBase64 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    authCredentialPresentationHex : arrayBufferToHex ( presentation ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								async  function  getGroupDelta ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  authCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  authCredentialBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  sender  =  window . textsecure . messaging ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! sender )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'getGroupDelta: textsecure.messaging is not available!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . publicParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'getGroupDelta: group was missing publicParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'getGroupDelta: group was missing secretParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  options  =  getGroupCredentials ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    authCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupPublicParamsBase64 : group.publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupSecretParamsBase64 : group.secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  currentRevision  =  group . revision ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  revisionToFetch  =  isNumber ( currentRevision )  ?  currentRevision  +  1  : 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  response ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  changes : Array < GroupChangesClass >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  do  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // eslint-disable-next-line no-await-in-loop
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    response  =  await  sender . getGroupLog ( revisionToFetch ,  options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    changes . push ( response . changes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( response . end )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      revisionToFetch  =  response . end  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  while  ( response . end  &&  response . end  <  newRevision ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Would be nice to cache the unused groupChanges here, to reduce server roundtrips
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  integrateGroupChanges ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    changes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								async  function  integrateGroupChanges ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  changes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newRevision : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  changes : Array < GroupChangesClass > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  let  attributes  =  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  finalMessages : Array < Array < MessageAttributesType > >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  finalMembers : Array < Array < MemberType > >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  imax  =  changes . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  for  ( let  i  =  0 ;  i  <  imax ;  i  +=  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  groupChanges  }  =  changes [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! groupChanges )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  jmax  =  groupChanges . length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( let  j  =  0 ;  j  <  jmax ;  j  +=  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  changeState  =  groupChanges [ j ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      const  {  groupChange ,  groupState  }  =  changeState ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-08 13:55:21 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  ( ! groupChange  &&  ! groupState )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'integrateGroupChanges: item had neither groupState nor groupChange. Skipping.' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          groupChangeMessages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          members , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          // eslint-disable-next-line no-await-in-loop
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        }  =  await  integrateGroupChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          group : attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          groupChange , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          groupState , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        attributes  =  newAttributes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        finalMessages . push ( groupChangeMessages ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        finalMembers . push ( members ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          ` integrateGroupChanges/ ${ logId } : Failed to apply change log, continuing to apply remaining change logs. ` , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								          error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // If this is our first fetch, we will collapse this down to one set of messages
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  isFirstFetch  =  ! isNumber ( group . revision ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( isFirstFetch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // The first array in finalMessages is from the first revision we could process. It
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   should contain a message about how we joined the group.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  joinMessages  =  finalMessages [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  alreadyHaveJoinMessage  =  joinMessages  &&  joinMessages . length  >  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // There have been other changes since that first revision, so we generate diffs for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   the whole of the change since then, likely without the initial join message.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  otherMessages  =  extractDiffs ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      old : group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      current : attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      dropInitialJoinMessage : alreadyHaveJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  groupChangeMessages  =  alreadyHaveJoinMessage 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ?  [ joinMessages [ 0 ] ,  . . . otherMessages ] 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      :  otherMessages ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newAttributes : attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeMessages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      members : flatten ( finalMembers ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newAttributes : attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupChangeMessages : flatten ( finalMessages ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members : flatten ( finalMembers ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								async  function  integrateGroupChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupChange , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  groupState , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  newRevision , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-08 13:55:21 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  groupChange? : GroupChangeClass ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  groupState? : GroupClass ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  newRevision : number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` integrateGroupChange/ ${ logId } : Group was missing secretParams! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-08 13:55:21 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( ! groupChange  &&  ! groupState )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` integrateGroupChange/ ${ logId } : Neither groupChange nor groupState received! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  isFirstFetch  =  ! isNumber ( group . revision ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationIdOrThrow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  weAreAwaitingApproval  =  ( group . pendingAdminApprovalV2  ||  [ ] ) . find ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    item  = >  item . conversationId  ===  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-08 13:55:21 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // These need to be populated from the groupChange. But we might not get one!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  isChangeSupported  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  isMoreThanOneVersionUp  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  groupChangeActions : undefined  |  GroupChangeClass . Actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  decryptedChangeActions : undefined  |  GroupChangeClass . Actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  sourceConversationId : undefined  |  string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( groupChange )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupChangeActions  =  window . textsecure . protobuf . GroupChange . Actions . decode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChange . actions . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeActions . version  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeActions . version  >  newRevision 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        newAttributes : group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupChangeMessages :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        members :  [ ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    decryptedChangeActions  =  decryptGroupChange ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeActions , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      group . secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      logId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  sourceUuid  }  =  decryptedChangeActions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  sourceConversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sourceUuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sourceConversationId  =  sourceConversation . id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    isChangeSupported  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ! isNumber ( groupChange . changeEpoch )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChange . changeEpoch  <=  SUPPORTED_CHANGE_EPOCH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    isMoreThanOneVersionUp  =  Boolean ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeActions . version  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        isNumber ( group . revision )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        groupChangeActions . version  >  group . revision  +  1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-08 13:55:21 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ! groupChange  || 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ! isChangeSupported  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    isFirstFetch  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( isMoreThanOneVersionUp  &&  ! weAreAwaitingApproval ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:39:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! groupState )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` integrateGroupChange/ ${ logId } : No group state, but we can't apply changes! ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    window . log . info ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:39:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ` integrateGroupChange/ ${ logId } : Applying full group state, from version  ${ group . revision }  to  ${ groupState . version } ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-08 13:55:21 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        isChangePresent : Boolean ( groupChange ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:39:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        isChangeSupported , 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-08 13:55:21 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        isFirstFetch , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        isMoreThanOneVersionUp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        weAreAwaitingApproval , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-20 17:39:13 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  decryptedGroupState  =  decryptGroupState ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      group . secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      logId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  newAttributes  =  await  applyGroupState ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState : decryptedGroupState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sourceConversationId : isFirstFetch  ?  sourceConversationId  : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupChangeMessages : extractDiffs ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        old : group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        current : newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sourceConversationId : isFirstFetch  ?  sourceConversationId  : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      members : getMembers ( decryptedGroupState ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-08 13:55:21 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( ! sourceConversationId  ||  ! groupChangeActions  ||  ! decryptedChangeActions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` integrateGroupChange/ ${ logId } : Missing necessary information that should have come from group actions ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ` integrateGroupChange/ ${ logId } : Applying group change actions, from version  ${ group . revision }  to  ${ groupChangeActions . version } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  {  newAttributes ,  newProfileKeys  }  =  await  applyGroupChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions : decryptedChangeActions , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    sourceConversationId , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupChangeMessages  =  extractDiffs ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old : group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    current : newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sourceConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupChangeMessages , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members : newProfileKeys.map ( item  = >  ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . item , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      profileKey : arrayBufferToBase64 ( item . profileKey ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 08:42:35 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								async  function  getCurrentGroupState ( { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  authCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  authCredentialBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage? : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  serverPublicParamsBase64 : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < UpdatesResultType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  sender  =  window . textsecure . messaging ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! sender )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'textsecure.messaging is not available!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'getCurrentGroupState: group was missing secretParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! group . publicParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'getCurrentGroupState: group was missing publicParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  options  =  getGroupCredentials ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    authCredentialBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupPublicParamsBase64 : group.publicParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupSecretParamsBase64 : group.secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    serverPublicParamsBase64 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  groupState  =  await  sender . getGroup ( options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  decryptedGroupState  =  decryptGroupState ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group . secretParams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    logId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-19 10:40:41 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  oldVersion  =  group . version ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  newVersion  =  decryptedGroupState . version ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ` getCurrentGroupState/ ${ logId } : Applying full group state, from version  ${ oldVersion }  to  ${ newVersion } . ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  newAttributes  =  await  applyGroupState ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState : decryptedGroupState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupChangeMessages : extractDiffs ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      old : group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      current : newAttributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      dropInitialJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members : getMembers ( decryptedGroupState ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								function  extractDiffs ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  current , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  old , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sourceConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  current : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  dropInitialJoinMessage? : boolean ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  old : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sourceConversationId? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Array < MessageAttributesType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( old . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  details : Array < GroupV2ChangeDetailType >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  ACCESS_ENUM  =  window . textsecure . protobuf . AccessControl . AccessRequired ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  let  areWeInGroup  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  let  areWeInvitedToGroup  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  whoInvitedUsUserId  =  null ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // access control
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    current . accessControl  && 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    old . accessControl  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . accessControl . attributes  !==  undefined  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . accessControl . attributes  !==  current . accessControl . attributes 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'access-attributes' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newPrivilege : current.accessControl.attributes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    current . accessControl  && 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    old . accessControl  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . accessControl . members  !==  undefined  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . accessControl . members  !==  current . accessControl . members 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'access-members' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newPrivilege : current.accessControl.members , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  linkPreviouslyEnabled  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . accessControl ? . addFromInviteLink  ===  ACCESS_ENUM . ANY  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . accessControl ? . addFromInviteLink  ===  ACCESS_ENUM . ADMINISTRATOR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  linkCurrentlyEnabled  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    current . accessControl ? . addFromInviteLink  ===  ACCESS_ENUM . ANY  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    current . accessControl ? . addFromInviteLink  ===  ACCESS_ENUM . ADMINISTRATOR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! linkPreviouslyEnabled  &&  linkCurrentlyEnabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-link-add' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      privilege : current.accessControl?.addFromInviteLink  ||  ACCESS_ENUM . ANY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  if  ( linkPreviouslyEnabled  &&  ! linkCurrentlyEnabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-link-remove' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    linkPreviouslyEnabled  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    linkCurrentlyEnabled  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . accessControl ? . addFromInviteLink  !== 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      current . accessControl ? . addFromInviteLink 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'access-invite-link' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newPrivilege : current.accessControl?.addFromInviteLink  ||  ACCESS_ENUM . ANY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // avatar
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Boolean ( old . avatar )  !==  Boolean ( current . avatar )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . avatar ? . hash  !==  current . avatar ? . hash 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'avatar' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      removed :  ! current . avatar , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( old . name  !==  current . name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'title' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newTitle : current.name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // groupInviteLinkPassword
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Note: we only capture link resets here. Enable/disable are controlled by the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   accessControl.addFromInviteLink
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . groupInviteLinkPassword  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    current . groupInviteLinkPassword  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    old . groupInviteLinkPassword  !==  current . groupInviteLinkPassword 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-link-reset' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  // No disappearing message timer check here - see below
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // membersV2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  oldMemberLookup : Dictionary < GroupV2MemberType >  =  fromPairs ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( old . membersV2  ||  [ ] ) . map ( member  = >  [ member . conversationId ,  member ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  oldPendingMemberLookup : Dictionary < GroupV2PendingMemberType >  =  fromPairs ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( old . pendingMembersV2  ||  [ ] ) . map ( member  = >  [ member . conversationId ,  member ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  oldPendingAdminApprovalLookup : Dictionary < GroupV2PendingAdminApprovalType >  =  fromPairs ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( old . pendingAdminApprovalV2  ||  [ ] ) . map ( member  = >  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( current . membersV2  ||  [ ] ) . forEach ( currentMember  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  conversationId  }  =  currentMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ourConversationId  &&  conversationId  ===  ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      areWeInGroup  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  oldMember  =  oldMemberLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! oldMember )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  pendingMember  =  oldPendingMemberLookup [ conversationId ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-28 10:22:57 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  ( pendingMember )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          type :  'member-add-from-invite' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          inviter : pendingMember.addedByUserId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      }  else  if  ( currentMember . joinedFromLink )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          type :  'member-add-from-link' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  if  ( currentMember . approvedByAdmin )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          type :  'member-add-from-admin-approval' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          type :  'member-add' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( oldMember . role  !==  currentMember . role )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        type :  'member-privilege' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        newPrivilege : currentMember.role , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // We don't want to generate an admin-approval-remove event for this newly-added
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   member. But we don't know for sure if this is an admin approval; for that we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   consulted the approvedByAdmin flag saved on the member.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    delete  oldPendingAdminApprovalLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // If we capture a pending remove here, it's an 'accept invitation', and we don't
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    //   want to generate a pending-remove event for it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    delete  oldPendingMemberLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    // This deletion makes it easier to capture removals
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    delete  oldMemberLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  removedMemberIds  =  Object . keys ( oldMemberLookup ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  removedMemberIds . forEach ( conversationId  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'member-remove' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // pendingMembersV2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  let  lastPendingConversationId : string  |  undefined ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  let  pendingCount  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  ( current . pendingMembersV2  ||  [ ] ) . forEach ( currentPendingMember  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  conversationId  }  =  currentPendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  oldPendingMember  =  oldPendingMemberLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ourConversationId  &&  conversationId  ===  ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      areWeInvitedToGroup  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      whoInvitedUsUserId  =  currentPendingMember . addedByUserId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! oldPendingMember )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      lastPendingConversationId  =  conversationId ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      pendingCount  +=  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // This deletion makes it easier to capture removals
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    delete  oldPendingMemberLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( pendingCount  >  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'pending-add-many' , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      count : pendingCount , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  }  else  if  ( pendingCount  ===  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( lastPendingConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        type :  'pending-add-one' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        conversationId : lastPendingConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ` extractDiffs/ ${ logId } : pendingCount was 1, no last conversationId available ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Note: The only members left over here should be people who were moved from the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   pending list but also not added to the group at the same time.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  removedPendingMemberIds  =  Object . keys ( oldPendingMemberLookup ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( removedPendingMemberIds . length  >  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  firstConversationId  =  removedPendingMemberIds [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  firstRemovedMember  =  oldPendingMemberLookup [ firstConversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  inviter  =  firstRemovedMember . addedByUserId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  allSameInviter  =  removedPendingMemberIds . every ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      id  = >  oldPendingMemberLookup [ id ] . addedByUserId  ===  inviter 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'pending-remove-many' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      count : removedPendingMemberIds.length , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      inviter : allSameInviter  ?  inviter  : undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  if  ( removedPendingMemberIds . length  ===  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  conversationId  =  removedPendingMemberIds [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  removedMember  =  oldPendingMemberLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'pending-remove-one' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      inviter : removedMember.addedByUserId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // pendingAdminApprovalV2
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( current . pendingAdminApprovalV2  ||  [ ] ) . forEach ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    currentPendingAdminAprovalMember  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  {  conversationId  }  =  currentPendingAdminAprovalMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  oldPendingMember  =  oldPendingAdminApprovalLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! oldPendingMember )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          type :  'admin-approval-add-one' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      // This deletion makes it easier to capture removals
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      delete  oldPendingAdminApprovalLookup [ conversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Note: The only members left over here should be people who were moved from the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   pendingAdminApproval list but also not added to the group at the same time.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  removedPendingAdminApprovalIds  =  Object . keys ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    oldPendingAdminApprovalLookup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  removedPendingAdminApprovalIds . forEach ( conversationId  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    details . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'admin-approval-remove-one' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // final processing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  let  message : MessageAttributesType  |  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  let  timerNotification : MessageAttributesType  |  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  conversation  =  sourceConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ?  window . ConversationController . get ( sourceConversationId ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    :  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  sourceUuid  =  conversation  ?  conversation . get ( 'uuid' )  :  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  firstUpdate  =  ! isNumber ( old . revision ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // Here we hardcode initial messages if this is our first time processing data this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   group. Ideally we can collapse it down to just one of: 'you were added',
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   'you were invited', or 'you created.'
 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 07:15:37 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( firstUpdate  &&  ourConversationId  &&  areWeInvitedToGroup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Note, we will add 'you were invited' to group even if dropInitialJoinMessage = true
 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    message  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupV2Change :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 07:15:37 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        from :  whoInvitedUsUserId  ||  sourceConversationId , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        details :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 07:15:37 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            type :  'pending-add-one' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            conversationId : ourConversationId , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 07:15:37 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  }  else  if  ( firstUpdate  &&  dropInitialJoinMessage )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // None of the rest of the messages should be added if dropInitialJoinMessage = true
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    message  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    firstUpdate  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ourConversationId  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sourceConversationId  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sourceConversationId  ===  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    message  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupV2Change :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 07:15:37 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        from :  sourceConversationId , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        details :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          { 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-10 07:15:37 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            type :  'create' , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  }  else  if  ( firstUpdate  &&  ourConversationId  &&  areWeInGroup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    message  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupV2Change :  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        from :  sourceConversationId , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        details :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            type :  'member-add' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            conversationId : ourConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  }  else  if  ( firstUpdate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    message  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupV2Change :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        from :  sourceConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        details :  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            type :  'create' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  }  else  if  ( details . length  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    message  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'group-v2-change' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sourceUuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupV2Change :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        from :  sourceConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        details , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // This is checked differently, because it needs to be its own entry in the timeline,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   with its own icon, etc.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Turn on or turned off
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    Boolean ( old . expireTimer )  !==  Boolean ( current . expireTimer )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Still on, but changed value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( Boolean ( old . expireTimer )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      Boolean ( current . expireTimer )  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      old . expireTimer  !==  current . expireTimer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    timerNotification  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . generateBasicMessage ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      type :  'timer-notification' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sourceUuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      flags : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . textsecure . protobuf . DataMessage . Flags . EXPIRATION_TIMER_UPDATE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      expirationTimerUpdate :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        expireTimer : current.expireTimer  ||  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sourceUuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  result  =  compact ( [ message ,  timerNotification ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  window . log . info ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ` extractDiffs/ ${ logId }  complete, generated  ${ result . length }  change messages ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								function  getMembers ( groupState : GroupClass )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! groupState . members  ||  ! groupState . members . length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  groupState . members . map ( ( member : MemberClass )  = >  ( { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-29 19:29:11 -04:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    profileKey : arrayBufferToBase64 ( member . profileKey ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    uuid : member.userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  GroupChangeMemberType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  profileKey : ArrayBuffer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  uuid : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								type  GroupChangeResultType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newAttributes : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  newProfileKeys : Array < GroupChangeMemberType > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								async  function  applyGroupChange ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions , 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sourceConversationId , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions : GroupChangeClass.Actions ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sourceConversationId : string ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < GroupChangeResultType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  ACCESS_ENUM  =  window . textsecure . protobuf . AccessControl . AccessRequired ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  version  =  actions . version  ||  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  result  =  {  . . . group  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  newProfileKeys : Array < GroupChangeMemberType >  =  [ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  members : Dictionary < GroupV2MemberType >  =  fromPairs ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( result . membersV2  ||  [ ] ) . map ( member  = >  [ member . conversationId ,  member ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  pendingMembers : Dictionary < GroupV2PendingMemberType >  =  fromPairs ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( result . pendingMembersV2  ||  [ ] ) . map ( member  = >  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  pendingAdminApprovalMembers : Dictionary < GroupV2PendingAdminApprovalType >  =  fromPairs ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( result . pendingAdminApprovalV2  ||  [ ] ) . map ( member  = >  [ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . conversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // version?: number;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result . revision  =  version ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // addMembers?: Array<GroupChangeClass.Actions.AddMemberAction>;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  ( actions . addMembers  ||  [ ] ) . forEach ( addMember  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    const  {  added  }  =  addMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! added )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 'applyGroupChange: addMember.added is missing' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      added . userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'private' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        profileKey : added.profileKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ?  arrayBufferToBase64 ( added . profileKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          :  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( members [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Attempt to add member failed; already in members. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members [ conversation . id ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversationId : conversation.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      role : added.role  ||  MEMBER_ROLE_ENUM . DEFAULT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      joinedAtVersion : version , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      joinedFromLink : addMember.joinFromInviteLink  ||  false , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pendingMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Removing newly-added member from pendingMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      delete  pendingMembers [ conversation . id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    // Capture who added us
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ourConversationId  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      sourceConversationId  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversation . id  ===  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      result . addedBy  =  sourceConversationId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( added . profileKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newProfileKeys . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        profileKey : added.profileKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        uuid : added.userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // deleteMembers?: Array<GroupChangeClass.Actions.DeleteMemberAction>;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . deleteMembers  ||  [ ] ) . forEach ( deleteMember  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  deletedUserId  }  =  deleteMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! deletedUserId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'applyGroupChange: deleteMember.deletedUserId is missing' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      deletedUserId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( members [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      delete  members [ conversation . id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Attempt to remove member failed; was not in members. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyMemberRoles?: Array<GroupChangeClass.Actions.ModifyMemberRoleAction>;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . modifyMemberRoles  ||  [ ] ) . forEach ( modifyMemberRole  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  role ,  userId  }  =  modifyMemberRole ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! role  ||  ! userId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 'applyGroupChange: modifyMemberRole had a missing value' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( members [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      members [ conversation . id ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        . . . members [ conversation . id ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        role , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'applyGroupChange: modifyMemberRole tried to modify nonexistent member' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // modifyMemberProfileKeys?:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Array<GroupChangeClass.Actions.ModifyMemberProfileKeyAction>;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . modifyMemberProfileKeys  ||  [ ] ) . forEach ( modifyMemberProfileKey  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  profileKey ,  uuid  }  =  modifyMemberProfileKey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! profileKey  ||  ! uuid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'applyGroupChange: modifyMemberProfileKey had a missing value' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newProfileKeys . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      profileKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      uuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // addPendingMembers?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.AddMemberPendingProfileKeyAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . addPendingMembers  ||  [ ] ) . forEach ( addPendingMember  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  added  }  =  addPendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! added  ||  ! added . member )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        'applyGroupChange: addPendingMembers had a missing value' 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      added . member . userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( members [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Attempt to add pendingMember failed; was already in members. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pendingMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Attempt to add pendingMember failed; was already in pendingMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pendingMembers [ conversation . id ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversationId : conversation.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      addedByUserId : added.addedByUserId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      timestamp : added.timestamp , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      role : added.member.role  ||  MEMBER_ROLE_ENUM . DEFAULT , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( added . member  &&  added . member . profileKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      newProfileKeys . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        profileKey : added.member.profileKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        uuid : added.member.userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // deletePendingMembers?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.DeleteMemberPendingProfileKeyAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . deletePendingMembers  ||  [ ] ) . forEach ( deletePendingMember  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  deletedUserId  }  =  deletePendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! deletedUserId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'applyGroupChange: deletePendingMember.deletedUserId is null!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      deletedUserId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pendingMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      delete  pendingMembers [ conversation . id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Attempt to remove pendingMember failed; was not in pendingMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // promotePendingMembers?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.PromoteMemberPendingProfileKeyAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . promotePendingMembers  ||  [ ] ) . forEach ( promotePendingMember  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  profileKey ,  uuid  }  =  promotePendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! profileKey  ||  ! uuid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'applyGroupChange: promotePendingMember had a missing value' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      uuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'private' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        profileKey : profileKey  ?  arrayBufferToBase64 ( profileKey )  :  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  previousRecord  =  pendingMembers [ conversation . id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( pendingMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      delete  pendingMembers [ conversation . id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Attempt to promote pendingMember failed; was not in pendingMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( members [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Attempt to promote pendingMember failed; was already in members. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members [ conversation . id ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      conversationId : conversation.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      joinedAtVersion : version , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      role : previousRecord.role  ||  MEMBER_ROLE_ENUM . DEFAULT , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newProfileKeys . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      profileKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      uuid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyTitle?: GroupChangeClass.Actions.ModifyTitleAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( actions . modifyTitle )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  {  title  }  =  actions . modifyTitle ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( title  &&  title . content  ===  'title' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      result . name  =  title . title ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Clearing group title due to missing data. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      result . name  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyAvatar?: GroupChangeClass.Actions.ModifyAvatarAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( actions . modifyAvatar )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  {  avatar  }  =  actions . modifyAvatar ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    await  applyNewAvatar ( avatar ,  result ,  logId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // modifyDisappearingMessagesTimer?:
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.ModifyDisappearingMessagesTimerAction;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( actions . modifyDisappearingMessagesTimer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  disappearingMessagesTimer : GroupAttributeBlobClass  |  undefined  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . modifyDisappearingMessagesTimer . timer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      disappearingMessagesTimer  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      disappearingMessagesTimer . content  ===  'disappearingMessagesDuration' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      result . expireTimer  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        disappearingMessagesTimer . disappearingMessagesDuration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` applyGroupChange/ ${ logId } : Clearing group expireTimer due to missing data. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      result . expireTimer  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result . accessControl  =  result . accessControl  ||  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members : ACCESS_ENUM.MEMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    attributes : ACCESS_ENUM.MEMBER , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    addFromInviteLink : ACCESS_ENUM.UNSATISFIABLE , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // modifyAttributesAccess?:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // GroupChangeClass.Actions.ModifyAttributesAccessControlAction;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( actions . modifyAttributesAccess )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . accessControl  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . result . accessControl , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      attributes : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        actions . modifyAttributesAccess . attributesAccess  ||  ACCESS_ENUM . MEMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyMemberAccess?: GroupChangeClass.Actions.ModifyMembersAccessControlAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( actions . modifyMemberAccess )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . accessControl  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . result . accessControl , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-10 13:06:26 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      members : actions.modifyMemberAccess.membersAccess  ||  ACCESS_ENUM . MEMBER , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // modifyAddFromInviteLinkAccess?:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.ModifyAddFromInviteLinkAccessControlAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( actions . modifyAddFromInviteLinkAccess )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . accessControl  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      . . . result . accessControl , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      addFromInviteLink : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        actions . modifyAddFromInviteLinkAccess . addFromInviteLinkAccess  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ACCESS_ENUM . UNSATISFIABLE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // addMemberPendingAdminApprovals?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.AddMemberPendingAdminApprovalAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . addMemberPendingAdminApprovals  ||  [ ] ) . forEach ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pendingAdminApproval  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  {  added  }  =  pendingAdminApproval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! added )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'applyGroupChange: modifyMemberProfileKey had a missing value' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        added . userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( members [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` applyGroupChange/ ${ logId } : Attempt to add pending admin approval failed; was already in members. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( pendingMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` applyGroupChange/ ${ logId } : Attempt to add pending admin approval failed; was already in pendingMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( pendingAdminApprovalMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` applyGroupChange/ ${ logId } : Attempt to add pending admin approval failed; was already in pendingAdminApprovalMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      pendingAdminApprovalMembers [ conversation . id ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        conversationId : conversation.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        timestamp : added.timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( added . profileKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        newProfileKeys . push ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          profileKey : added.profileKey , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          uuid : added.userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // deleteMemberPendingAdminApprovals?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.DeleteMemberPendingAdminApprovalAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . deleteMemberPendingAdminApprovals  ||  [ ] ) . forEach ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    deleteAdminApproval  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  {  deletedUserId  }  =  deleteAdminApproval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! deletedUserId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'applyGroupChange: deleteAdminApproval.deletedUserId is null!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        deletedUserId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( pendingAdminApprovalMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        delete  pendingAdminApprovalMembers [ conversation . id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` applyGroupChange/ ${ logId } : Attempt to remove pendingAdminApproval failed; was not in pendingAdminApprovalMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // promoteMemberPendingAdminApprovals?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.PromoteMemberPendingAdminApprovalAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ( actions . promoteMemberPendingAdminApprovals  ||  [ ] ) . forEach ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    promoteAdminApproval  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  {  userId ,  role  }  =  promoteAdminApproval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! userId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'applyGroupChange: promoteAdminApproval had a missing value' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( pendingAdminApprovalMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        delete  pendingAdminApprovalMembers [ conversation . id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` applyGroupChange/ ${ logId } : Attempt to promote pendingAdminApproval failed; was not in pendingAdminApprovalMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( pendingMembers [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        delete  pendingAdminApprovalMembers [ conversation . id ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` applyGroupChange/ ${ logId } : Deleted pendingAdminApproval from pendingMembers. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( members [ conversation . id ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` applyGroupChange/ ${ logId } : Attempt to promote pendingMember failed; was already in members. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      members [ conversation . id ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        conversationId : conversation.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        joinedAtVersion : version , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        role : role  ||  MEMBER_ROLE_ENUM . DEFAULT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        approvedByAdmin : true , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyInviteLinkPassword?: GroupChangeClass.Actions.ModifyInviteLinkPasswordAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( actions . modifyInviteLinkPassword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  {  inviteLinkPassword  }  =  actions . modifyInviteLinkPassword ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( inviteLinkPassword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      result . groupInviteLinkPassword  =  inviteLinkPassword ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      result . groupInviteLinkPassword  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . left  =  ! members [ ourConversationId ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Go from lookups back to arrays
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result . membersV2  =  values ( members ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result . pendingMembersV2  =  values ( pendingMembers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  result . pendingAdminApprovalV2  =  values ( pendingAdminApprovalMembers ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newAttributes : result , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    newProfileKeys , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 14:39:26 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  async  function  decryptGroupAvatar ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  avatarKey : string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  secretParamsBase64 : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Promise < ArrayBuffer >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  sender  =  window . textsecure . messaging ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! sender )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'decryptGroupAvatar: textsecure.messaging is not available!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ciphertext  =  await  sender . getGroupAvatar ( avatarKey ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( secretParamsBase64 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  plaintext  =  decryptGroupBlob ( clientZkGroupCipher ,  ciphertext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  blob  =  window . textsecure . protobuf . GroupAttributeBlob . decode ( plaintext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( blob . content  !==  'avatar' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` decryptGroupAvatar: Returned blob had incorrect content:  ${ blob . content } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  blob . avatar . toArrayBuffer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								// Ovewriting result.avatar as part of functionality
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* eslint-disable no-param-reassign */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  async  function  applyNewAvatar ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  newAvatar : string  |  undefined , 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  result : Pick < ConversationAttributesType ,  'avatar'  |  'secretParams' > , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  logId : string 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								) :  Promise < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Avatar has been dropped
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! newAvatar  &&  result . avatar )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      await  window . Signal . Migrations . deleteAttachmentData ( result . avatar . path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      result . avatar  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    // Group has avatar; has it changed?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( newAvatar  &&  ( ! result . avatar  ||  result . avatar . url  !==  newAvatar ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! result . secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 'applyNewAvatar: group was missing secretParams!' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-10 14:39:26 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      const  data  =  await  decryptGroupAvatar ( newAvatar ,  result . secretParams ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      const  hash  =  await  computeHash ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( result . avatar  &&  result . avatar . path  &&  result . avatar . hash  !==  hash )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        await  window . Signal . Migrations . deleteAttachmentData ( result . avatar . path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        result . avatar  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! result . avatar )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  path  =  await  window . Signal . Migrations . writeNewAttachmentData ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        result . avatar  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          url : newAvatar , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          path , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          hash , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` applyNewAvatar/ ${ logId }  Failed to handle avatar, clearing it ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      error . stack 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( result . avatar  &&  result . avatar . path )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      await  window . Signal . Migrations . deleteAttachmentData ( result . avatar . path ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . avatar  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* eslint-enable no-param-reassign */ 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								async  function  applyGroupState ( { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupState , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sourceConversationId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  group : ConversationAttributesType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  groupState : GroupClass ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  sourceConversationId? : string ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ) :  Promise < ConversationAttributesType >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  logId  =  idForLogging ( group . groupId ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  ACCESS_ENUM  =  window . textsecure . protobuf . AccessControl . AccessRequired ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  version  =  groupState . version  ||  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-20 09:30:45 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  result  =  {  . . . group  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // version
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result . revision  =  version ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // title
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Note: During decryption, title becomes a GroupAttributeBlob
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  {  title  }  =  groupState ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( title  &&  title . content  ===  'title' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . name  =  title . title ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . name  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // avatar
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  await  applyNewAvatar ( groupState . avatar ,  result ,  logId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // disappearingMessagesTimer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Note: during decryption, disappearingMessageTimer becomes a GroupAttributeBlob
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  const  {  disappearingMessagesTimer  }  =  groupState ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    disappearingMessagesTimer  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    disappearingMessagesTimer . content  ===  'disappearingMessagesDuration' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . expireTimer  =  disappearingMessagesTimer . disappearingMessagesDuration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . expireTimer  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // accessControl
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  accessControl  }  =  groupState ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result . accessControl  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    attributes : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ( accessControl  &&  accessControl . attributes )  ||  ACCESS_ENUM . MEMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    members :  ( accessControl  &&  accessControl . members )  ||  ACCESS_ENUM . MEMBER , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    addFromInviteLink : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ( accessControl  &&  accessControl . addFromInviteLink )  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ACCESS_ENUM . UNSATISFIABLE , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Optimization: we assume we have left the group unless we are found in members
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  result . left  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ourConversationId  =  window . ConversationController . getOurConversationId ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // members
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( groupState . members )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . membersV2  =  groupState . members . map ( ( member : MemberClass )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      const  conversation  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        member . userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'private' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          profileKey : member.profileKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ?  arrayBufferToBase64 ( member . profileKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            :  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ourConversationId  &&  conversation . id  ===  ourConversationId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        result . left  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-06 10:06:34 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        // Capture who added us if we were previously not in group
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          sourceConversationId  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ( result . membersV2  ||  [ ] ) . every ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            item  = >  item . conversationId  !==  ourConversationId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          result . addedBy  =  sourceConversationId ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      if  ( ! isValidRole ( member . role ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` applyGroupState: Member had invalid role  ${ member . role } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        role : member.role  ||  MEMBER_ROLE_ENUM . DEFAULT , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        joinedAtVersion : member.joinedAtVersion  ||  version , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        conversationId : conversation.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // membersPendingProfileKey
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( groupState . membersPendingProfileKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . pendingMembersV2  =  groupState . membersPendingProfileKey . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ( member : MemberPendingProfileKeyClass )  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        let  pending ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        let  invitedBy ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( member . member  &&  member . member . userId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          pending  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            member . member . userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'private' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              profileKey : member.member.profileKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ?  arrayBufferToBase64 ( member . member . profileKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                :  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            'applyGroupState: Member pending profile key did not have an associated userId' 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( member . addedByUserId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          invitedBy  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            member . addedByUserId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'private' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            'applyGroupState: Member pending profile key did not have an addedByUserID' 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! isValidRole ( member . member . role ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` applyGroupState: Member pending profile key had invalid role  ${ member . member . role } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          addedByUserId : invitedBy.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId : pending.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          timestamp : member.timestamp , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          role : member.member.role  ||  MEMBER_ROLE_ENUM . DEFAULT , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // membersPendingAdminApproval
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( groupState . membersPendingAdminApproval )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . pendingAdminApprovalV2  =  groupState . membersPendingAdminApproval . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ( member : MemberPendingAdminApprovalClass )  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        let  pending ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( member . userId )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          pending  =  window . ConversationController . getOrCreate ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            member . userId , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'private' , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              profileKey : member.profileKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ?  arrayBufferToBase64 ( member . profileKey ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                :  undefined , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'applyGroupState: Pending admin approval did not have an associated userId' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          conversationId : pending.id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          timestamp : member.timestamp , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // inviteLinkPassword
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  inviteLinkPassword  }  =  groupState ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( inviteLinkPassword )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . groupInviteLinkPassword  =  inviteLinkPassword ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    result . groupInviteLinkPassword  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-01 15:45:39 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function  isValidRole ( role? : number ) :  role  is  number  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  MEMBER_ROLE_ENUM  =  window . textsecure . protobuf . Member . Role ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    role  ===  MEMBER_ROLE_ENUM . ADMINISTRATOR  ||  role  ===  MEMBER_ROLE_ENUM . DEFAULT 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function  isValidAccess ( access? : number ) :  access  is  number  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  const  ACCESS_ENUM  =  window . textsecure . protobuf . AccessControl . AccessRequired ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  access  ===  ACCESS_ENUM . ADMINISTRATOR  ||  access  ===  ACCESS_ENUM . MEMBER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function  isValidLinkAccess ( access? : number ) :  access  is  number  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  ACCESS_ENUM  =  window . textsecure . protobuf . AccessControl . AccessRequired ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    access  ===  ACCESS_ENUM . UNKNOWN  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    access  ===  ACCESS_ENUM . ANY  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    access  ===  ACCESS_ENUM . ADMINISTRATOR  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    access  ===  ACCESS_ENUM . UNSATISFIABLE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								function  isValidProfileKey ( buffer? : ArrayBuffer ) :  boolean  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  Boolean ( buffer  &&  buffer . byteLength  ===  32 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								function  hasData ( data : ProtoBinaryType ) :  boolean  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  data  &&  data . limit  >  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function  normalizeTimestamp ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  timestamp : ProtoBigNumberType 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  number  |  ProtoBigNumberType  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! timestamp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  asNumber  =  timestamp . toNumber ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  now  =  Date . now ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! asNumber  ||  asNumber  >  now )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  now ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  asNumber ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* eslint-disable no-param-reassign */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								function  decryptGroupChange ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  actions : GroupChangeClass.Actions , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  groupSecretParams : string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  logId : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  GroupChangeClass . Actions  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( groupSecretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( actions . sourceUuid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . sourceUuid  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        actions . sourceUuid . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptGroupChange/ ${ logId } : Unable to decrypt sourceUuid. Clearing sourceUuid. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . sourceUuid  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . normalizeUuids ( actions ,  [ 'sourceUuid' ] ,  'groups.decryptGroupChange' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! window . isValidGuid ( actions . sourceUuid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptGroupChange/ ${ logId } : Invalid sourceUuid. Clearing sourceUuid. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . sourceUuid  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'decryptGroupChange: Missing sourceUuid' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // addMembers?: Array<GroupChangeClass.Actions.AddMemberAction>;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . addMembers  =  compact ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ( actions . addMembers  ||  [ ] ) . map ( addMember  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      if  ( addMember . added )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  decrypted  =  decryptMember ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          addMember . added , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          logId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! decrypted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addMember . added  =  decrypted ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  addMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 'decryptGroupChange: AddMember was missing added field!' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // deleteMembers?: Array<GroupChangeClass.Actions.DeleteMemberAction>;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . deleteMembers  =  compact ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ( actions . deleteMembers  ||  [ ] ) . map ( deleteMember  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      if  ( hasData ( deleteMember . deletedUserId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          deleteMember . deletedUserId  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            deleteMember . deletedUserId . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` decryptGroupChange/ ${ logId } : Unable to decrypt deleteMembers.deletedUserId. Dropping member. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'decryptGroupChange: deleteMember.deletedUserId was missing' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . normalizeUuids ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        deleteMember , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ 'deletedUserId' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'groups.decryptGroupChange' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! window . isValidGuid ( deleteMember . deletedUserId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` decryptGroupChange/ ${ logId } : Dropping deleteMember due to invalid userId ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  deleteMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyMemberRoles?: Array<GroupChangeClass.Actions.ModifyMemberRoleAction>;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyMemberRoles  =  compact ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ( actions . modifyMemberRoles  ||  [ ] ) . map ( modifyMember  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      if  ( hasData ( modifyMember . userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          modifyMember . userId  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            modifyMember . userId . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` decryptGroupChange/ ${ logId } : Unable to decrypt modifyMemberRole.userId. Dropping member. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'decryptGroupChange: modifyMemberRole.userId was missing' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . normalizeUuids ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        modifyMember , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ 'userId' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'groups.decryptGroupChange' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! window . isValidGuid ( modifyMember . userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` decryptGroupChange/ ${ logId } : Dropping modifyMemberRole due to invalid userId ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! isValidRole ( modifyMember . role ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								          ` decryptGroupChange: modifyMemberRole had invalid role  ${ modifyMember . role } ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  modifyMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // modifyMemberProfileKeys?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.ModifyMemberProfileKeyAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  actions . modifyMemberProfileKeys  =  compact ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ( actions . modifyMemberProfileKeys  ||  [ ] ) . map ( modifyMemberProfileKey  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      if  ( hasData ( modifyMemberProfileKey . presentation ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  {  profileKey ,  uuid  }  =  decryptProfileKeyCredentialPresentation ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          modifyMemberProfileKey . presentation . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        modifyMemberProfileKey . profileKey  =  profileKey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        modifyMemberProfileKey . uuid  =  uuid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ! modifyMemberProfileKey . uuid  || 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ! modifyMemberProfileKey . profileKey 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'decryptGroupChange: uuid or profileKey missing after modifyMemberProfileKey decryption!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! window . isValidGuid ( modifyMemberProfileKey . uuid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` decryptGroupChange/ ${ logId } : Dropping modifyMemberProfileKey due to invalid userId ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! isValidProfileKey ( modifyMemberProfileKey . profileKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'decryptGroupChange: modifyMemberProfileKey had invalid profileKey' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'decryptGroupChange: modifyMemberProfileKey.presentation was missing' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  modifyMemberProfileKey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // addPendingMembers?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.AddMemberPendingProfileKeyAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  actions . addPendingMembers  =  compact ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ( actions . addPendingMembers  ||  [ ] ) . map ( addPendingMember  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      if  ( addPendingMember . added )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        const  decrypted  =  decryptMemberPendingProfileKey ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								          clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          addPendingMember . added , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          logId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! decrypted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addPendingMember . added  =  decrypted ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  addPendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'decryptGroupChange: addPendingMember was missing added field!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // deletePendingMembers?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.DeleteMemberPendingProfileKeyAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  actions . deletePendingMembers  =  compact ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ( actions . deletePendingMembers  ||  [ ] ) . map ( deletePendingMember  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      if  ( hasData ( deletePendingMember . deletedUserId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          deletePendingMember . deletedUserId  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            deletePendingMember . deletedUserId . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` decryptGroupChange/ ${ logId } : Unable to decrypt deletePendingMembers.deletedUserId. Dropping member. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'decryptGroupChange: deletePendingMembers.deletedUserId was missing' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . normalizeUuids ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        deletePendingMember , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        [ 'deletedUserId' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        'groups.decryptGroupChange' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      if  ( ! window . isValidGuid ( deletePendingMember . deletedUserId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ` decryptGroupChange/ ${ logId } : Dropping deletePendingMember due to invalid deletedUserId ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  deletePendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // promotePendingMembers?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.PromoteMemberPendingProfileKeyAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  actions . promotePendingMembers  =  compact ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    ( actions . promotePendingMembers  ||  [ ] ) . map ( promotePendingMember  = >  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      if  ( hasData ( promotePendingMember . presentation ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  {  profileKey ,  uuid  }  =  decryptProfileKeyCredentialPresentation ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          promotePendingMember . presentation . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        promotePendingMember . profileKey  =  profileKey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        promotePendingMember . uuid  =  uuid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! promotePendingMember . uuid  ||  ! promotePendingMember . profileKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'decryptGroupChange: uuid or profileKey missing after promotePendingMember decryption!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! window . isValidGuid ( promotePendingMember . uuid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` decryptGroupChange/ ${ logId } : Dropping modifyMemberProfileKey due to invalid userId ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! isValidProfileKey ( promotePendingMember . profileKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'decryptGroupChange: modifyMemberProfileKey had invalid profileKey' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'decryptGroupChange: promotePendingMember.presentation was missing' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  promotePendingMember ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyTitle?: GroupChangeClass.Actions.ModifyTitleAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( actions . modifyTitle  &&  hasData ( actions . modifyTitle . title ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . modifyTitle . title  =  window . textsecure . protobuf . GroupAttributeBlob . decode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        decryptGroupBlob ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          actions . modifyTitle . title . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptGroupChange/ ${ logId } : Unable to decrypt modifyTitle.title ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . modifyTitle . title  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  if  ( actions . modifyTitle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyTitle . title  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyAvatar?: GroupChangeClass.Actions.ModifyAvatarAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Note: decryption happens during application of the change, on download of the avatar
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // modifyDisappearingMessagesTimer?:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // GroupChangeClass.Actions.ModifyDisappearingMessagesTimerAction;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyDisappearingMessagesTimer  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    hasData ( actions . modifyDisappearingMessagesTimer . timer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . modifyDisappearingMessagesTimer . timer  =  window . textsecure . protobuf . GroupAttributeBlob . decode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        decryptGroupBlob ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          actions . modifyDisappearingMessagesTimer . timer . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptGroupChange/ ${ logId } : Unable to decrypt modifyDisappearingMessagesTimer.timer ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . modifyDisappearingMessagesTimer . timer  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  if  ( actions . modifyDisappearingMessagesTimer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyDisappearingMessagesTimer . timer  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-11 12:37:01 -07:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // modifyAttributesAccess?:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // GroupChangeClass.Actions.ModifyAttributesAccessControlAction;
 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyAttributesAccess  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ! isValidAccess ( actions . modifyAttributesAccess . attributesAccess ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ` decryptGroupChange: modifyAttributesAccess.attributesAccess was not valid:  ${ actions . modifyAttributesAccess . attributesAccess } ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyMemberAccess?: GroupChangeClass.Actions.ModifyMembersAccessControlAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyMemberAccess  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ! isValidAccess ( actions . modifyMemberAccess . membersAccess ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ` decryptGroupChange: modifyMemberAccess.membersAccess was not valid:  ${ actions . modifyMemberAccess . membersAccess } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyAddFromInviteLinkAccess?:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.ModifyAddFromInviteLinkAccessControlAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyAddFromInviteLinkAccess  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ! isValidLinkAccess ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      actions . modifyAddFromInviteLinkAccess . addFromInviteLinkAccess 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` decryptGroupChange: modifyAddFromInviteLinkAccess.addFromInviteLinkAccess was not valid:  ${ actions . modifyAddFromInviteLinkAccess . addFromInviteLinkAccess } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // addMemberPendingAdminApprovals?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.AddMemberPendingAdminApprovalAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . addMemberPendingAdminApprovals  =  compact ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( actions . addMemberPendingAdminApprovals  ||  [ ] ) . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      addPendingAdminApproval  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( addPendingAdminApproval . added )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          const  decrypted  =  decryptMemberPendingAdminApproval ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            addPendingAdminApproval . added , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            logId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          if  ( ! decrypted )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              ` decryptGroupChange/ ${ logId } : Unable to decrypt addPendingAdminApproval.added. Dropping member. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          addPendingAdminApproval . added  =  decrypted ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  addPendingAdminApproval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'decryptGroupChange: addPendingAdminApproval was missing added field!' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // deleteMemberPendingAdminApprovals?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.DeleteMemberPendingAdminApprovalAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . deleteMemberPendingAdminApprovals  =  compact ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( actions . deleteMemberPendingAdminApprovals  ||  [ ] ) . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      deletePendingApproval  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( hasData ( deletePendingApproval . deletedUserId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            deletePendingApproval . deletedUserId  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              deletePendingApproval . deletedUserId . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              ` decryptGroupChange/ ${ logId } : Unable to decrypt deletePendingApproval.deletedUserId. Dropping member. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'decryptGroupChange: deletePendingApproval.deletedUserId was missing' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        window . normalizeUuids ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          deletePendingApproval , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          [ 'deletedUserId' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          'groups.decryptGroupChange' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! window . isValidGuid ( deletePendingApproval . deletedUserId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` decryptGroupChange/ ${ logId } : Dropping deletePendingApproval due to invalid deletedUserId ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  deletePendingApproval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // promoteMemberPendingAdminApprovals?: Array<
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  //   GroupChangeClass.Actions.PromoteMemberPendingAdminApprovalAction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // >;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  actions . promoteMemberPendingAdminApprovals  =  compact ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ( actions . promoteMemberPendingAdminApprovals  ||  [ ] ) . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      promoteAdminApproval  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( hasData ( promoteAdminApproval . userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            promoteAdminApproval . userId  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              promoteAdminApproval . userId . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              ` decryptGroupChange/ ${ logId } : Unable to decrypt promoteAdminApproval.userId. Dropping member. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								              error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            'decryptGroupChange: promoteAdminApproval.userId was missing' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! isValidRole ( promoteAdminApproval . role ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ` decryptGroupChange: promoteAdminApproval had invalid role  ${ promoteAdminApproval . role } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  promoteAdminApproval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // modifyInviteLinkPassword?: GroupChangeClass.Actions.ModifyInviteLinkPasswordAction;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyInviteLinkPassword  && 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    hasData ( actions . modifyInviteLinkPassword . inviteLinkPassword ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyInviteLinkPassword . inviteLinkPassword  =  actions . modifyInviteLinkPassword . inviteLinkPassword . toString ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'base64' 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    actions . modifyInviteLinkPassword  =  undefined ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  actions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-01-29 14:16:48 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  decryptGroupTitle ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  title : ProtoBinaryType , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  secretParams : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  string  |  undefined  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( title ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  blob  =  window . textsecure . protobuf . GroupAttributeBlob . decode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      decryptGroupBlob ( clientZkGroupCipher ,  title . toArrayBuffer ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( blob  &&  blob . content  ===  'title' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  blob . title ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								function  decryptGroupState ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  groupState : GroupClass , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  groupSecretParams : string , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  logId : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  GroupClass  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( groupSecretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // title
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( groupState . title ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState . title  =  window . textsecure . protobuf . GroupAttributeBlob . decode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        decryptGroupBlob ( clientZkGroupCipher ,  groupState . title . toArrayBuffer ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptGroupState/ ${ logId } : Unable to decrypt title. Clearing it. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState . title  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState . title  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // avatar
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // Note: decryption happens during application of the change, on download of the avatar
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // disappearing message timer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( groupState . disappearingMessagesTimer ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState . disappearingMessagesTimer  =  window . textsecure . protobuf . GroupAttributeBlob . decode ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        decryptGroupBlob ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          groupState . disappearingMessagesTimer . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptGroupState/ ${ logId } : Unable to decrypt disappearing message timer. Clearing it. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState . disappearingMessagesTimer  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState . disappearingMessagesTimer  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // accessControl
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( ! isValidAccess ( groupState . accessControl ? . attributes ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ` decryptGroupState: Access control for attributes is invalid:  ${ groupState . accessControl ? . attributes } ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  if  ( ! isValidAccess ( groupState . accessControl ? . members ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` decryptGroupState: Access control for members is invalid:  ${ groupState . accessControl ? . members } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isValidLinkAccess ( groupState . accessControl ? . addFromInviteLink ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ` decryptGroupState: Access control for invite link is invalid:  ${ groupState . accessControl ? . addFromInviteLink } ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // version
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isNumber ( groupState . version ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` decryptGroupState: Expected version to be a number; it was  ${ groupState . version } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // members
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( groupState . members )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState . members  =  compact ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState . members . map ( ( member : MemberClass )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        decryptMember ( clientZkGroupCipher ,  member ,  logId ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // membersPendingProfileKey
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( groupState . membersPendingProfileKey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState . membersPendingProfileKey  =  compact ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState . membersPendingProfileKey . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( member : MemberPendingProfileKeyClass )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          decryptMemberPendingProfileKey ( clientZkGroupCipher ,  member ,  logId ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // membersPendingAdminApproval
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( groupState . membersPendingAdminApproval )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState . membersPendingAdminApproval  =  compact ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      groupState . membersPendingAdminApproval . map ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( member : MemberPendingAdminApprovalClass )  = > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								          decryptMemberPendingAdminApproval ( clientZkGroupCipher ,  member ,  logId ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  // inviteLinkPassword
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( groupState . inviteLinkPassword ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState . inviteLinkPassword  =  groupState . inviteLinkPassword . toString ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'base64' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    groupState . inviteLinkPassword  =  undefined ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  return  groupState ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								function  decryptMember ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  clientZkGroupCipher : ClientZkGroupCipher , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  member : MemberClass , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  logId : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								)  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // userId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( member . userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . userId  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        member . userId . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptMember/ ${ logId } : Unable to decrypt member userid. Dropping member. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . normalizeUuids ( member ,  [ 'userId' ] ,  'groups.decryptMember' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! window . isValidGuid ( member . userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptMember/ ${ logId } : Dropping member due to invalid userId ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'decryptMember: Member had missing userId' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // profileKey
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( member . profileKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    member . profileKey  =  decryptProfileKey ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . profileKey . toArrayBuffer ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . userId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! isValidProfileKey ( member . profileKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 'decryptMember: Member had invalid profileKey' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'decryptMember: Member had missing profileKey' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // role
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isValidRole ( member . role ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    throw  new  Error ( ` decryptMember: Member had invalid role  ${ member . role } ` ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function  decryptMemberPendingProfileKey ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  clientZkGroupCipher : ClientZkGroupCipher , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  member : MemberPendingProfileKeyClass , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  logId : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								)  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // addedByUserId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( member . addedByUserId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . addedByUserId  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        member . addedByUserId . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingProfileKey/ ${ logId } : Unable to decrypt pending member addedByUserId. Dropping member. ` , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . normalizeUuids ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      [ 'addedByUserId' ] , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      'groups.decryptMemberPendingProfileKey' 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! window . isValidGuid ( member . addedByUserId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingProfileKey/ ${ logId } : Dropping pending member due to invalid addedByUserId ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'decryptMemberPendingProfileKey: Member had missing addedByUserId' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // timestamp
 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  member . timestamp  =  normalizeTimestamp ( member . timestamp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! member . member )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . log . warn ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      ` decryptMemberPendingProfileKey/ ${ logId } : Dropping pending member due to missing member details ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  userId ,  profileKey ,  role  }  =  member . member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // userId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . member . userId  =  decryptUuid ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        userId . toArrayBuffer ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingProfileKey/ ${ logId } : Unable to decrypt pending member userId. Dropping member. ` , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . normalizeUuids ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . member , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      [ 'userId' ] , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      'groups.decryptMemberPendingProfileKey' 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! window . isValidGuid ( member . member . userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingProfileKey/ ${ logId } : Dropping pending member due to invalid member.userId ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'decryptMemberPendingProfileKey: Member had missing member.userId' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // profileKey
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( profileKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . member . profileKey  =  decryptProfileKey ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        profileKey . toArrayBuffer ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        member . member . userId 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingProfileKey/ ${ logId } : Unable to decrypt pending member profileKey. Dropping profileKey. ` , 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . member . profileKey  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! isValidProfileKey ( member . member . profileKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingProfileKey/ ${ logId } : Dropping profileKey, since it was invalid ` 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . member . profileKey  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // role
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! isValidRole ( role ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ` decryptMemberPendingProfileKey: Member had invalid role  ${ role } ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-09-08 19:25:05 -07:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2020-11-13 13:57:55 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-12-18 11:27:43 -08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								function  decryptMemberPendingAdminApproval ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  clientZkGroupCipher : ClientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  member : MemberPendingAdminApprovalClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  logId : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								)  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // timestamp
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  member . timestamp  =  normalizeTimestamp ( member . timestamp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  {  userId ,  profileKey  }  =  member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // userId
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . userId  =  decryptUuid ( clientZkGroupCipher ,  userId . toArrayBuffer ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingAdminApproval/ ${ logId } : Unable to decrypt pending member userId. Dropping member. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    window . normalizeUuids ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      [ 'userId' ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      'groups.decryptMemberPendingAdminApproval' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! window . isValidGuid ( member . userId ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingAdminApproval/ ${ logId } : Invalid userId. Dropping member. ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      return  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'decryptMemberPendingAdminApproval: Missing userId' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  // profileKey
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( hasData ( profileKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    try  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . profileKey  =  decryptProfileKey ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        clientZkGroupCipher , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        profileKey . toArrayBuffer ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        member . userId 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  catch  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingAdminApproval/ ${ logId } : Unable to decrypt profileKey. Dropping profileKey. ` , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        error  &&  error . stack  ?  error.stack  : error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . profileKey  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! isValidProfileKey ( member . profileKey ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      window . log . warn ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ` decryptMemberPendingAdminApproval/ ${ logId } : Dropping profileKey, since it was invalid ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      member . profileKey  =  null ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  member ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-11-13 13:57:55 -06:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								export  function  getMembershipList ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  conversationId : string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								) :  Array < {  uuid : string ;  uuidCiphertext : ArrayBuffer  } >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  conversation  =  window . ConversationController . get ( conversationId ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! conversation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'getMembershipList: cannot find conversation' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  secretParams  =  conversation . get ( 'secretParams' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  if  ( ! secretParams )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    throw  new  Error ( 'getMembershipList: no secretParams' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  const  clientZkGroupCipher  =  getClientZkGroupCipher ( secretParams ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  return  conversation . getMembers ( ) . map ( member  = >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  uuid  =  member . get ( 'uuid' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! uuid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      throw  new  Error ( 'getMembershipList: member has no UUID' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  uuidCiphertext  =  encryptUuid ( clientZkGroupCipher ,  uuid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  {  uuid ,  uuidCiphertext  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}