2023-04-21 07:17:24 +02:00
import { compact , isEmpty , toNumber } from 'lodash' ;
2023-02-01 05:03:58 +01:00
import { ConfigDumpData } from '../data/configDump/configDump' ;
2022-08-08 01:50:48 +02:00
import { Data , hasSyncedInitialConfigurationItem } from '../data/data' ;
2023-01-25 07:46:30 +01:00
import { ConversationInteraction } from '../interactions' ;
import { ConversationTypeEnum } from '../models/conversationAttributes' ;
import { SignalService } from '../protobuf' ;
2023-03-08 07:39:29 +01:00
import { ClosedGroup } from '../session' ;
2021-05-27 07:29:07 +02:00
import {
joinOpenGroupV2WithUIEvents ,
parseOpenGroupV2 ,
2021-12-14 05:15:12 +01:00
} from '../session/apis/open_group_api/opengroupV2/JoinOpenGroupV2' ;
2023-02-24 05:44:29 +01:00
import { getOpenGroupManager } from '../session/apis/open_group_api/opengroupV2/OpenGroupManagerV2' ;
import { OpenGroupUtils } from '../session/apis/open_group_api/utils' ;
2021-12-14 05:15:12 +01:00
import { getOpenGroupV2ConversationId } from '../session/apis/open_group_api/utils/OpenGroupUtils' ;
2023-04-21 07:17:24 +02:00
import { getSwarmPollingInstance } from '../session/apis/snode_api' ;
2021-06-24 07:10:38 +02:00
import { getConversationController } from '../session/conversations' ;
2023-01-25 07:46:30 +01:00
import { IncomingMessage } from '../session/messages/incoming/IncomingMessage' ;
2023-01-31 01:30:56 +01:00
import { ProfileManager } from '../session/profile_manager/ProfileManager' ;
2023-04-21 07:17:24 +02:00
import { PubKey } from '../session/types' ;
2021-03-02 01:27:20 +01:00
import { UserUtils } from '../session/utils' ;
2023-04-21 07:17:24 +02:00
import { toHex } from '../session/utils/String' ;
2023-02-01 05:03:58 +01:00
import { ConfigurationSync } from '../session/utils/job_runners/jobs/ConfigurationSyncJob' ;
2023-02-08 00:50:23 +01:00
import { IncomingConfResult , LibSessionUtil } from '../session/utils/libsession/libsession_utils' ;
2023-03-16 00:49:06 +01:00
import { SessionUtilConvoInfoVolatile } from '../session/utils/libsession/libsession_utils_convo_info_volatile' ;
2023-02-24 05:44:29 +01:00
import { SessionUtilUserGroups } from '../session/utils/libsession/libsession_utils_user_groups' ;
2021-03-02 01:27:20 +01:00
import { configurationMessageReceived , trigger } from '../shims/events' ;
2023-03-08 07:39:29 +01:00
import { assertUnreachable } from '../types/sqlSharedTypes' ;
2021-11-04 04:47:47 +01:00
import { BlockedNumberController } from '../util' ;
2023-03-31 02:33:30 +02:00
import { Registration } from '../util/registration' ;
2023-01-25 07:46:30 +01:00
import { getLastProfileUpdateTimestamp , setLastProfileUpdateTimestamp } from '../util/storage' ;
2023-03-08 07:39:29 +01:00
import { ConfigWrapperObjectTypes } from '../webworker/workers/browser/libsession_worker_functions' ;
2023-02-01 05:03:58 +01:00
import {
ContactsWrapperActions ,
2023-03-16 00:49:06 +01:00
ConvoInfoVolatileWrapperActions ,
2023-02-01 05:03:58 +01:00
GenericWrapperActions ,
UserConfigWrapperActions ,
2023-02-24 05:44:29 +01:00
UserGroupsWrapperActions ,
2023-02-01 05:03:58 +01:00
} from '../webworker/workers/browser/libsession_worker_interface' ;
2021-03-02 01:27:20 +01:00
import { removeFromCache } from './cache' ;
2023-03-08 07:39:29 +01:00
import { addKeyPairToCacheAndDBIfNeeded , handleNewClosedGroup } from './closedGroups' ;
import { HexKeyPair } from './keypairs' ;
2023-04-21 07:17:24 +02:00
import { queueAllCachedFromSource } from './receiver' ;
2021-03-02 01:27:20 +01:00
import { EnvelopePlus } from './types' ;
2023-04-21 08:17:14 +02:00
import { SettingsKey } from '../data/settings-key' ;
2021-03-02 01:27:20 +01:00
2023-03-08 07:39:29 +01:00
function groupByVariant (
incomingConfigs : Array < IncomingMessage < SignalService.ISharedConfigMessage > >
) {
const groupedByVariant : Map <
ConfigWrapperObjectTypes ,
Array < IncomingMessage < SignalService.ISharedConfigMessage > >
> = new Map ( ) ;
incomingConfigs . forEach ( incomingConfig = > {
const { kind } = incomingConfig . message ;
const wrapperId = LibSessionUtil . kindToVariant ( kind ) ;
if ( ! groupedByVariant . has ( wrapperId ) ) {
groupedByVariant . set ( wrapperId , [ ] ) ;
}
groupedByVariant . get ( wrapperId ) ? . push ( incomingConfig ) ;
} ) ;
return groupedByVariant ;
}
2023-01-25 05:26:28 +01:00
async function mergeConfigsWithIncomingUpdates (
2023-03-08 07:39:29 +01:00
incomingConfigs : Array < IncomingMessage < SignalService.ISharedConfigMessage > >
) : Promise < Map < ConfigWrapperObjectTypes , IncomingConfResult > > {
// first, group by variant so we do a single merge call
const groupedByVariant = groupByVariant ( incomingConfigs ) ;
const groupedResults : Map < ConfigWrapperObjectTypes , IncomingConfResult > = new Map ( ) ;
2023-03-30 05:59:14 +02:00
// TODOLATER currently we only poll for user config messages, so this can be hardcoded
2023-03-08 07:39:29 +01:00
const publicKey = UserUtils . getOurPubKeyStrFromCache ( ) ;
2023-01-25 05:26:28 +01:00
2023-02-20 05:11:04 +01:00
try {
2023-03-08 07:39:29 +01:00
for ( let index = 0 ; index < groupedByVariant . size ; index ++ ) {
const variant = [ . . . groupedByVariant . keys ( ) ] [ index ] ;
const sameVariant = groupedByVariant . get ( variant ) ;
if ( ! sameVariant ? . length ) {
continue ;
}
const toMerge = sameVariant . map ( msg = > ( {
data : msg.message.data ,
hash : msg.messageHash ,
} ) ) ;
await GenericWrapperActions . merge ( variant , toMerge ) ;
const needsPush = await GenericWrapperActions . needsPush ( variant ) ;
const needsDump = await GenericWrapperActions . needsDump ( variant ) ;
const latestEnvelopeTimestamp = Math . max ( . . . sameVariant . map ( m = > m . envelopeTimestamp ) ) ;
2023-04-21 07:17:24 +02:00
window . log . debug ( ` ${ variant } : " ${ publicKey } " needsPush: ${ needsPush } needsDump: ${ needsDump } ` ) ;
2023-03-30 05:59:14 +02:00
2023-03-08 07:39:29 +01:00
const incomingConfResult : IncomingConfResult = {
needsDump ,
needsPush ,
kind : LibSessionUtil.variantToKind ( variant ) ,
publicKey ,
latestEnvelopeTimestamp : latestEnvelopeTimestamp ? latestEnvelopeTimestamp : Date.now ( ) ,
} ;
groupedResults . set ( variant , incomingConfResult ) ;
}
2023-02-20 05:11:04 +01:00
2023-03-08 07:39:29 +01:00
return groupedResults ;
2023-02-20 05:11:04 +01:00
} catch ( e ) {
window . log . error ( 'mergeConfigsWithIncomingUpdates failed with' , e ) ;
throw e ;
}
2023-01-25 05:26:28 +01:00
}
2023-02-01 05:03:58 +01:00
async function handleUserProfileUpdate ( result : IncomingConfResult ) : Promise < IncomingConfResult > {
2023-02-08 00:50:23 +01:00
if ( ! result . needsDump ) {
2023-02-01 05:03:58 +01:00
return result ;
2023-01-25 05:26:28 +01:00
}
2023-04-21 07:17:24 +02:00
const updateUserInfo = await UserConfigWrapperActions . getUserInfo ( ) ;
if ( ! updateUserInfo ) {
return result ;
}
const picUpdate = ! isEmpty ( updateUserInfo . key ) && ! isEmpty ( updateUserInfo . url ) ;
2023-03-28 05:44:41 +02:00
await updateOurProfileLegacyOrViaLibSession (
result . latestEnvelopeTimestamp ,
2023-04-21 07:17:24 +02:00
updateUserInfo . name ,
picUpdate ? updateUserInfo.url : null ,
picUpdate ? updateUserInfo.key : null ,
updateUserInfo . priority
2023-01-25 05:26:28 +01:00
) ;
2023-04-21 07:17:24 +02:00
2023-02-01 05:03:58 +01:00
return result ;
2023-01-25 05:26:28 +01:00
}
2023-02-17 01:43:21 +01:00
// tslint:disable-next-line: cyclomatic-complexity
2023-02-01 05:03:58 +01:00
async function handleContactsUpdate ( result : IncomingConfResult ) : Promise < IncomingConfResult > {
2023-02-08 00:50:23 +01:00
if ( ! result . needsDump ) {
2023-02-01 05:03:58 +01:00
return result ;
2023-01-25 05:26:28 +01:00
}
2023-02-15 06:02:38 +01:00
const us = UserUtils . getOurPubKeyStrFromCache ( ) ;
2023-01-25 05:26:28 +01:00
2023-02-01 05:03:58 +01:00
const allContacts = await ContactsWrapperActions . getAll ( ) ;
2023-01-25 05:26:28 +01:00
for ( let index = 0 ; index < allContacts . length ; index ++ ) {
const wrapperConvo = allContacts [ index ] ;
2023-02-15 06:02:38 +01:00
if ( wrapperConvo . id === us ) {
// our profile update comes from our userProfile, not from the contacts wrapper.
continue ;
}
2023-03-24 06:48:50 +01:00
const contactConvo = await getConversationController ( ) . getOrCreateAndWait (
2023-02-15 06:02:38 +01:00
wrapperConvo . id ,
ConversationTypeEnum . PRIVATE
) ;
2023-03-24 06:48:50 +01:00
if ( wrapperConvo . id && contactConvo ) {
2023-01-25 05:26:28 +01:00
let changes = false ;
2023-02-20 05:11:04 +01:00
// the display name set is handled in `updateProfileOfContact`
2023-03-24 06:48:50 +01:00
if ( wrapperConvo . nickname !== contactConvo . getNickname ( ) ) {
await contactConvo . setNickname ( wrapperConvo . nickname || null , false ) ;
2023-01-25 05:26:28 +01:00
changes = true ;
}
2023-04-03 04:03:23 +02:00
if ( wrapperConvo . priority !== contactConvo . get ( 'priority' ) ) {
2023-04-03 07:08:37 +02:00
await contactConvo . setPriorityFromWrapper ( wrapperConvo . priority ) ;
2023-01-25 05:26:28 +01:00
changes = true ;
}
2023-04-03 09:51:39 +02:00
if ( Boolean ( wrapperConvo . approved ) !== contactConvo . isApproved ( ) ) {
2023-03-24 06:48:50 +01:00
await contactConvo . setIsApproved ( Boolean ( wrapperConvo . approved ) , false ) ;
2023-02-20 05:11:04 +01:00
changes = true ;
2023-01-25 05:26:28 +01:00
}
2023-04-03 09:51:39 +02:00
if ( Boolean ( wrapperConvo . approvedMe ) !== contactConvo . didApproveMe ( ) ) {
2023-03-24 06:48:50 +01:00
await contactConvo . setDidApproveMe ( Boolean ( wrapperConvo . approvedMe ) , false ) ;
2023-02-20 05:11:04 +01:00
changes = true ;
}
2023-04-03 07:08:37 +02:00
if ( wrapperConvo . expirationTimerSeconds !== contactConvo . get ( 'expireTimer' ) ) {
await contactConvo . updateExpireTimer ( wrapperConvo . expirationTimerSeconds ) ;
2023-01-25 05:26:28 +01:00
changes = true ;
}
2023-04-03 09:51:39 +02:00
// we want to set the active_at to the created_at timestamp if active_at is unset, so that it shows up in our list.
if ( ! contactConvo . get ( 'active_at' ) && wrapperConvo . createdAtSeconds ) {
contactConvo . set ( { active_at : wrapperConvo.createdAtSeconds * 1000 } ) ;
changes = true ;
}
2023-02-20 05:11:04 +01:00
const convoBlocked = wrapperConvo . blocked || false ;
await BlockedNumberController . setBlocked ( wrapperConvo . id , convoBlocked ) ;
2023-01-31 01:30:56 +01:00
// make sure to write the changes to the database now as the `AvatarDownloadJob` below might take some time before getting run
2023-01-25 05:26:28 +01:00
if ( changes ) {
2023-03-24 06:48:50 +01:00
await contactConvo . commit ( ) ;
2023-01-25 05:26:28 +01:00
}
2023-02-20 05:11:04 +01:00
// we still need to handle the `name` (synchronous) and the `profilePicture` (asynchronous)
2023-01-31 01:30:56 +01:00
await ProfileManager . updateProfileOfContact (
2023-03-24 06:48:50 +01:00
contactConvo . id ,
2023-01-31 01:30:56 +01:00
wrapperConvo . name ,
wrapperConvo . profilePicture ? . url || null ,
2023-01-25 05:26:28 +01:00
wrapperConvo . profilePicture ? . key || null
) ;
}
}
2023-02-01 05:03:58 +01:00
return result ;
2023-01-25 05:26:28 +01:00
}
2023-03-08 07:39:29 +01:00
async function handleCommunitiesUpdate() {
2023-02-24 05:44:29 +01:00
// first let's check which communities needs to be joined or left by doing a diff of what is in the wrapper and what is in the DB
2023-03-08 07:39:29 +01:00
2023-02-24 05:44:29 +01:00
const allCommunitiesInWrapper = await UserGroupsWrapperActions . getAllCommunities ( ) ;
2023-04-21 07:17:24 +02:00
window . log . debug (
'allCommunitiesInWrapper' ,
allCommunitiesInWrapper . map ( m = > m . fullUrl )
) ;
2023-02-24 05:44:29 +01:00
const allCommunitiesConversation = getConversationController ( )
. getConversations ( )
2023-03-08 07:39:29 +01:00
. filter ( SessionUtilUserGroups . isCommunityToStoreInWrapper ) ;
2023-02-24 05:44:29 +01:00
const allCommunitiesIdsInDB = allCommunitiesConversation . map ( m = > m . id as string ) ;
2023-04-21 07:17:24 +02:00
window . log . debug ( 'allCommunitiesIdsInDB' , allCommunitiesIdsInDB ) ;
2023-02-24 05:44:29 +01:00
const communitiesIdsInWrapper = compact (
allCommunitiesInWrapper . map ( m = > {
try {
const builtConvoId = OpenGroupUtils . getOpenGroupV2ConversationId (
m . baseUrl ,
m . roomCasePreserved
) ;
return builtConvoId ;
} catch ( e ) {
return null ;
}
} )
) ;
const communitiesToJoinInDB = compact (
allCommunitiesInWrapper . map ( m = > {
try {
const builtConvoId = OpenGroupUtils . getOpenGroupV2ConversationId (
m . baseUrl ,
m . roomCasePreserved
) ;
2023-03-08 07:39:29 +01:00
return allCommunitiesIdsInDB . includes ( builtConvoId ) ? null : m ;
2023-02-24 05:44:29 +01:00
} catch ( e ) {
return null ;
}
} )
) ;
const communitiesToLeaveInDB = compact (
allCommunitiesConversation . map ( m = > {
return communitiesIdsInWrapper . includes ( m . id ) ? null : m ;
} )
) ;
for ( let index = 0 ; index < communitiesToLeaveInDB . length ; index ++ ) {
const toLeave = communitiesToLeaveInDB [ index ] ;
console . warn ( 'leaving community with convoId ' , toLeave . id ) ;
2023-03-08 07:39:29 +01:00
await getConversationController ( ) . deleteContact ( toLeave . id , true ) ;
2023-02-24 05:44:29 +01:00
}
// this call can take quite a long time and should not cause issues to not be awaited
void Promise . all (
communitiesToJoinInDB . map ( async toJoin = > {
console . warn ( 'joining community with convoId ' , toJoin . fullUrl ) ;
return getOpenGroupManager ( ) . attemptConnectionV2OneAtATime (
toJoin . baseUrl ,
toJoin . roomCasePreserved ,
toJoin . pubkeyHex
) ;
} )
) ;
// if the convos already exists, make sure to update the fields if needed
for ( let index = 0 ; index < allCommunitiesInWrapper . length ; index ++ ) {
const fromWrapper = allCommunitiesInWrapper [ index ] ;
const convoId = OpenGroupUtils . getOpenGroupV2ConversationId (
fromWrapper . baseUrl ,
fromWrapper . roomCasePreserved
) ;
2023-03-24 06:48:50 +01:00
const communityConvo = getConversationController ( ) . get ( convoId ) ;
if ( fromWrapper && communityConvo ) {
2023-02-24 05:44:29 +01:00
let changes = false ;
2023-04-03 04:03:23 +02:00
changes =
( await communityConvo . setPriorityFromWrapper ( fromWrapper . priority , false ) ) || changes ;
2023-02-24 05:44:29 +01:00
// make sure to write the changes to the database now as the `AvatarDownloadJob` below might take some time before getting run
if ( changes ) {
2023-03-24 06:48:50 +01:00
await communityConvo . commit ( ) ;
2023-02-24 05:44:29 +01:00
}
}
}
}
2023-03-08 07:39:29 +01:00
async function handleLegacyGroupUpdate ( latestEnvelopeTimestamp : number ) {
// first let's check which closed groups needs to be joined or left by doing a diff of what is in the wrapper and what is in the DB
const allLegacyGroupsInWrapper = await UserGroupsWrapperActions . getAllLegacyGroups ( ) ;
const allLegacyGroupsInDb = getConversationController ( )
. getConversations ( )
2023-04-21 07:17:24 +02:00
. filter ( SessionUtilUserGroups . isLegacyGroupToRemoveFromDBIfNotInWrapper ) ;
2023-01-25 05:26:28 +01:00
2023-03-08 07:39:29 +01:00
const allLegacyGroupsIdsInDB = allLegacyGroupsInDb . map ( m = > m . id as string ) ;
const allLegacyGroupsIdsInWrapper = allLegacyGroupsInWrapper . map ( m = > m . pubkeyHex ) ;
const legacyGroupsToJoinInDB = allLegacyGroupsInWrapper . filter ( m = > {
return ! allLegacyGroupsIdsInDB . includes ( m . pubkeyHex ) ;
} ) ;
2023-04-21 07:17:24 +02:00
window . log . debug ( ` allLegacyGroupsInWrapper: ${ allLegacyGroupsInWrapper . map ( m = > m . pubkeyHex ) } ` ) ;
window . log . debug ( ` allLegacyGroupsIdsInDB: ${ allLegacyGroupsIdsInDB } ` ) ;
2023-03-08 07:39:29 +01:00
const legacyGroupsToLeaveInDB = allLegacyGroupsInDb . filter ( m = > {
return ! allLegacyGroupsIdsInWrapper . includes ( m . id ) ;
} ) ;
window . log . info (
` we have to join ${ legacyGroupsToJoinInDB . length } legacy groups in DB compared to what is in the wrapper `
) ;
window . log . info (
` we have to leave ${ legacyGroupsToLeaveInDB . length } legacy groups in DB compared to what is in the wrapper `
) ;
for ( let index = 0 ; index < legacyGroupsToLeaveInDB . length ; index ++ ) {
const toLeave = legacyGroupsToLeaveInDB [ index ] ;
console . warn ( 'leaving legacy group from configuration sync message with convoId ' , toLeave . id ) ;
await getConversationController ( ) . deleteContact ( toLeave . id , true ) ;
2023-02-01 05:03:58 +01:00
}
2023-01-25 05:26:28 +01:00
2023-03-08 07:39:29 +01:00
for ( let index = 0 ; index < legacyGroupsToJoinInDB . length ; index ++ ) {
const toJoin = legacyGroupsToJoinInDB [ index ] ;
console . warn (
'joining legacy group from configuration sync message with convoId ' ,
toJoin . pubkeyHex
) ;
2023-02-01 05:03:58 +01:00
2023-03-08 07:39:29 +01:00
// let's just create the required convo here, as we update the fields right below
await getConversationController ( ) . getOrCreateAndWait (
toJoin . pubkeyHex ,
ConversationTypeEnum . GROUP
) ;
}
for ( let index = 0 ; index < allLegacyGroupsInWrapper . length ; index ++ ) {
const fromWrapper = allLegacyGroupsInWrapper [ index ] ;
2023-03-24 06:48:50 +01:00
const legacyGroupConvo = getConversationController ( ) . get ( fromWrapper . pubkeyHex ) ;
if ( ! legacyGroupConvo ) {
2023-03-08 07:39:29 +01:00
// this should not happen as we made sure to create them before
window . log . warn (
'could not find legacy group which should already be there:' ,
fromWrapper . pubkeyHex
) ;
continue ;
}
const members = fromWrapper . members . map ( m = > m . pubkeyHex ) ;
const admins = fromWrapper . members . filter ( m = > m . isAdmin ) . map ( m = > m . pubkeyHex ) ;
// then for all the existing legacy group in the wrapper, we need to override the field of what we have in the DB with what is in the wrapper
// We only set group admins on group creation
const groupDetails : ClosedGroup.GroupInfo = {
id : fromWrapper.pubkeyHex ,
name : fromWrapper.name ,
members ,
admins ,
activeAt :
2023-03-24 06:48:50 +01:00
! ! legacyGroupConvo . get ( 'active_at' ) &&
legacyGroupConvo . get ( 'active_at' ) < latestEnvelopeTimestamp
? legacyGroupConvo . get ( 'active_at' )
2023-03-08 07:39:29 +01:00
: latestEnvelopeTimestamp ,
2023-03-30 05:59:14 +02:00
weWereJustAdded : false , // TODOLATER to remove once legacy groups support is dropped
2023-03-08 07:39:29 +01:00
} ;
await ClosedGroup . updateOrCreateClosedGroup ( groupDetails ) ;
2023-04-03 04:03:23 +02:00
let changes = await legacyGroupConvo . setPriorityFromWrapper ( fromWrapper . priority , false ) ;
if ( legacyGroupConvo . get ( 'priority' ) !== fromWrapper . priority ) {
legacyGroupConvo . set ( { priority : fromWrapper.priority } ) ;
2023-03-08 07:39:29 +01:00
changes = true ;
}
2023-04-03 09:51:39 +02:00
const existingTimestampMs = legacyGroupConvo . get ( 'lastJoinedTimestamp' ) ;
if ( Math . floor ( existingTimestampMs / 1000 ) !== fromWrapper . joinedAtSeconds ) {
legacyGroupConvo . set ( { lastJoinedTimestamp : fromWrapper.joinedAtSeconds * 1000 } ) ;
changes = true ;
}
2023-03-24 06:48:50 +01:00
if ( legacyGroupConvo . get ( 'expireTimer' ) !== fromWrapper . disappearingTimerSeconds ) {
await legacyGroupConvo . updateExpireTimer (
2023-03-08 07:39:29 +01:00
fromWrapper . disappearingTimerSeconds ,
undefined ,
latestEnvelopeTimestamp ,
{
fromSync : true ,
}
) ;
changes = true ;
}
2023-04-21 07:17:24 +02:00
// start polling for this new group
getSwarmPollingInstance ( ) . addGroupId ( PubKey . cast ( fromWrapper . pubkeyHex ) ) ;
// trigger decrypting of all this group messages we did not decrypt successfully yet.
await queueAllCachedFromSource ( fromWrapper . pubkeyHex ) ;
2023-03-08 07:39:29 +01:00
if ( changes ) {
2023-03-24 06:48:50 +01:00
await legacyGroupConvo . commit ( ) ;
2023-03-08 07:39:29 +01:00
}
// save the encryption keypair if needed
if ( ! isEmpty ( fromWrapper . encPubkey ) && ! isEmpty ( fromWrapper . encSeckey ) ) {
2023-03-24 06:48:50 +01:00
try {
const inWrapperKeypair : HexKeyPair = {
publicHex : toHex ( fromWrapper . encPubkey ) ,
privateHex : toHex ( fromWrapper . encSeckey ) ,
} ;
2023-03-08 07:39:29 +01:00
2023-03-24 06:48:50 +01:00
await addKeyPairToCacheAndDBIfNeeded ( fromWrapper . pubkeyHex , inWrapperKeypair ) ;
} catch ( e ) {
window . log . warn ( 'failed to save keypair for legacugroup' , fromWrapper . pubkeyHex ) ;
}
2023-03-08 07:39:29 +01:00
}
}
}
async function handleUserGroupsUpdate ( result : IncomingConfResult ) : Promise < IncomingConfResult > {
if ( ! result . needsDump ) {
return result ;
}
const toHandle = SessionUtilUserGroups . getUserGroupTypes ( ) ;
for ( let index = 0 ; index < toHandle . length ; index ++ ) {
const typeToHandle = toHandle [ index ] ;
switch ( typeToHandle ) {
case 'Community' :
await handleCommunitiesUpdate ( ) ;
2023-02-01 05:03:58 +01:00
break ;
2023-03-08 07:39:29 +01:00
case 'LegacyGroup' :
await handleLegacyGroupUpdate ( result . latestEnvelopeTimestamp ) ;
2023-02-24 05:44:29 +01:00
break ;
2023-03-08 07:39:29 +01:00
2023-02-01 05:03:58 +01:00
default :
2023-03-08 07:39:29 +01:00
assertUnreachable ( typeToHandle , ` handleUserGroupsUpdate unhandled type " ${ typeToHandle } " ` ) ;
2023-01-25 05:26:28 +01:00
}
2023-03-08 07:39:29 +01:00
}
2023-02-01 05:03:58 +01:00
2023-03-08 07:39:29 +01:00
return result ;
}
2023-02-01 05:03:58 +01:00
2023-03-24 04:39:30 +01:00
async function applyConvoVolatileUpdateFromWrapper (
convoId : string ,
forcedUnread : boolean ,
lastReadMessageTimestamp : number
) {
const foundConvo = getConversationController ( ) . get ( convoId ) ;
2023-04-03 07:08:37 +02:00
if ( ! foundConvo ) {
return ;
}
2023-03-24 04:39:30 +01:00
2023-04-03 07:08:37 +02:00
try {
window . log . debug (
` applyConvoVolatileUpdateFromWrapper: ${ convoId } : forcedUnread: ${ forcedUnread } , lastReadMessage: ${ lastReadMessageTimestamp } `
) ;
// this should mark all the messages sent before fromWrapper.lastRead as read and update the unreadCount
await foundConvo . markReadFromConfigMessage ( lastReadMessageTimestamp ) ;
// this commits to the DB, if needed
await foundConvo . markAsUnread ( forcedUnread , true ) ;
if ( SessionUtilConvoInfoVolatile . isConvoToStoreInWrapper ( foundConvo ) ) {
await SessionUtilConvoInfoVolatile . refreshConvoVolatileCached (
foundConvo . id ,
foundConvo . isClosedGroup ( ) ,
false
2023-03-24 04:39:30 +01:00
) ;
2023-04-03 07:08:37 +02:00
await foundConvo . refreshInMemoryDetails ( ) ;
2023-03-24 04:39:30 +01:00
}
2023-04-03 07:08:37 +02:00
} catch ( e ) {
window . log . warn (
` applyConvoVolatileUpdateFromWrapper of " ${ convoId } " failed with error ${ e . message } `
) ;
2023-03-24 04:39:30 +01:00
}
}
2023-03-09 07:12:59 +01:00
async function handleConvoInfoVolatileUpdate (
result : IncomingConfResult
) : Promise < IncomingConfResult > {
2023-03-30 05:15:59 +02:00
if ( ! result . needsDump ) {
return result ;
}
2023-03-09 07:12:59 +01:00
2023-03-16 00:49:06 +01:00
const types = SessionUtilConvoInfoVolatile . getConvoInfoVolatileTypes ( ) ;
for ( let typeIndex = 0 ; typeIndex < types . length ; typeIndex ++ ) {
const type = types [ typeIndex ] ;
switch ( type ) {
case '1o1' :
2023-03-24 04:39:30 +01:00
try {
// Note: "Note to Self" comes here too
const wrapper1o1s = await ConvoInfoVolatileWrapperActions . getAll1o1 ( ) ;
for ( let index = 0 ; index < wrapper1o1s . length ; index ++ ) {
const fromWrapper = wrapper1o1s [ index ] ;
await applyConvoVolatileUpdateFromWrapper (
fromWrapper . pubkeyHex ,
fromWrapper . unread ,
fromWrapper . lastRead
2023-03-16 00:49:06 +01:00
) ;
}
2023-03-24 04:39:30 +01:00
} catch ( e ) {
window . log . warn ( 'handleConvoInfoVolatileUpdate of "1o1" failed with error: ' , e . message ) ;
2023-03-16 00:49:06 +01:00
}
break ;
case 'Community' :
2023-03-24 04:39:30 +01:00
try {
const wrapperComms = await ConvoInfoVolatileWrapperActions . getAllCommunities ( ) ;
for ( let index = 0 ; index < wrapperComms . length ; index ++ ) {
const fromWrapper = wrapperComms [ index ] ;
const convoId = getOpenGroupV2ConversationId (
fromWrapper . baseUrl ,
fromWrapper . roomCasePreserved
) ;
await applyConvoVolatileUpdateFromWrapper (
convoId ,
fromWrapper . unread ,
fromWrapper . lastRead
) ;
}
} catch ( e ) {
window . log . warn (
'handleConvoInfoVolatileUpdate of "Community" failed with error: ' ,
e . message
) ;
}
2023-03-16 00:49:06 +01:00
break ;
2023-03-09 07:12:59 +01:00
2023-03-16 00:49:06 +01:00
case 'LegacyGroup' :
2023-03-24 04:39:30 +01:00
try {
const legacyGroups = await ConvoInfoVolatileWrapperActions . getAllLegacyGroups ( ) ;
for ( let index = 0 ; index < legacyGroups . length ; index ++ ) {
const fromWrapper = legacyGroups [ index ] ;
await applyConvoVolatileUpdateFromWrapper (
fromWrapper . pubkeyHex ,
fromWrapper . unread ,
fromWrapper . lastRead
) ;
}
} catch ( e ) {
window . log . warn (
'handleConvoInfoVolatileUpdate of "LegacyGroup" failed with error: ' ,
e . message
) ;
}
2023-03-16 00:49:06 +01:00
break ;
2023-03-09 07:12:59 +01:00
2023-03-16 00:49:06 +01:00
default :
assertUnreachable ( type , ` handleConvoInfoVolatileUpdate: unhandeld switch case: ${ type } ` ) ;
}
}
2023-03-09 07:12:59 +01:00
return result ;
}
2023-03-08 07:39:29 +01:00
async function processMergingResults ( results : Map < ConfigWrapperObjectTypes , IncomingConfResult > ) {
if ( ! results || ! results . size ) {
2023-02-01 05:03:58 +01:00
return ;
2023-01-25 05:26:28 +01:00
}
2023-02-01 05:03:58 +01:00
2023-03-08 07:39:29 +01:00
const keys = [ . . . results . keys ( ) ] ;
let anyNeedsPush = false ;
for ( let index = 0 ; index < keys . length ; index ++ ) {
const wrapperType = keys [ index ] ;
const incomingResult = results . get ( wrapperType ) ;
if ( ! incomingResult ) {
continue ;
}
try {
const { kind } = incomingResult ;
switch ( kind ) {
case SignalService . SharedConfigMessage . Kind . USER_PROFILE :
await handleUserProfileUpdate ( incomingResult ) ;
break ;
case SignalService . SharedConfigMessage . Kind . CONTACTS :
await handleContactsUpdate ( incomingResult ) ;
break ;
case SignalService . SharedConfigMessage . Kind . USER_GROUPS :
await handleUserGroupsUpdate ( incomingResult ) ;
break ;
2023-03-09 07:12:59 +01:00
case SignalService . SharedConfigMessage . Kind . CONVO_INFO_VOLATILE :
await handleConvoInfoVolatileUpdate ( incomingResult ) ;
break ;
2023-03-08 07:39:29 +01:00
default :
2023-03-09 07:12:59 +01:00
try {
2023-04-21 07:17:24 +02:00
// we catch errors here because an old client knowing about a new type of config coming from the network should not just crash
2023-03-09 07:12:59 +01:00
assertUnreachable ( kind , ` processMergingResults unsupported kind: " ${ kind } " ` ) ;
} catch ( e ) {
window . log . warn ( 'assertUnreachable failed' , e . message ) ;
}
2023-03-08 07:39:29 +01:00
}
const variant = LibSessionUtil . kindToVariant ( kind ) ;
if ( incomingResult . needsDump ) {
// The config data had changes so regenerate the dump and save it
const dump = await GenericWrapperActions . dump ( variant ) ;
await ConfigDumpData . saveConfigDump ( {
data : dump ,
publicKey : incomingResult.publicKey ,
variant ,
} ) ;
}
if ( incomingResult . needsPush ) {
anyNeedsPush = true ;
}
} catch ( e ) {
window . log . error ( ` processMergingResults failed with ${ e . message } ` ) ;
return ;
}
}
2023-02-01 05:03:58 +01:00
// Now that the local state has been updated, trigger a config sync (this will push any
// pending updates and properly update the state)
2023-03-08 07:39:29 +01:00
if ( anyNeedsPush ) {
2023-02-01 05:03:58 +01:00
await ConfigurationSync . queueNewJobIfNeeded ( ) ;
}
2023-01-25 05:26:28 +01:00
}
2023-03-08 07:39:29 +01:00
async function handleConfigMessagesViaLibSession (
configMessages : Array < IncomingMessage < SignalService.ISharedConfigMessage > >
2023-01-25 05:26:28 +01:00
) {
2023-01-25 07:46:30 +01:00
if ( ! window . sessionFeatureFlags . useSharedUtilForUserConfig ) {
2023-01-25 05:26:28 +01:00
return ;
2023-01-10 07:24:56 +01:00
}
2023-03-08 07:39:29 +01:00
if ( isEmpty ( configMessages ) ) {
2023-01-25 07:46:30 +01:00
return ;
}
2023-01-25 05:26:28 +01:00
2023-03-08 07:39:29 +01:00
window ? . log ? . info (
2023-04-21 07:17:24 +02:00
` Handling our sharedConfig message via libsession_util; count: ${ configMessages . length } `
2023-03-08 07:39:29 +01:00
) ;
2023-01-25 05:26:28 +01:00
2023-03-08 07:39:29 +01:00
const incomingMergeResult = await mergeConfigsWithIncomingUpdates ( configMessages ) ;
2023-01-25 05:26:28 +01:00
2023-03-08 07:39:29 +01:00
await processMergingResults ( incomingMergeResult ) ;
2023-01-10 07:24:56 +01:00
}
2023-03-28 05:44:41 +02:00
async function updateOurProfileLegacyOrViaLibSession (
sentAt : number ,
displayName : string ,
profileUrl : string | null ,
2023-04-21 07:17:24 +02:00
profileKey : Uint8Array | null ,
priority : number | null // passing null means to not update the priority at all (used for legacy config message for now)
2023-03-28 05:44:41 +02:00
) {
2023-04-21 07:17:24 +02:00
await ProfileManager . updateOurProfileSync ( displayName , profileUrl , profileKey , priority ) ;
2023-03-28 05:44:41 +02:00
await setLastProfileUpdateTimestamp ( toNumber ( sentAt ) ) ;
// do not trigger a signin by linking if the display name is empty
if ( ! isEmpty ( displayName ) ) {
trigger ( configurationMessageReceived , displayName ) ;
} else {
window ? . log ? . warn ( 'Got a configuration message but the display name is empty' ) ;
}
}
2023-02-15 06:02:38 +01:00
async function handleOurProfileUpdateLegacy (
2021-03-02 01:27:20 +01:00
sentAt : number | Long ,
2022-04-11 09:18:11 +02:00
configMessage : SignalService.ConfigurationMessage
2021-03-02 01:27:20 +01:00
) {
2023-03-31 02:33:30 +02:00
// we want to allow if we are not registered, as we might need to fetch an old config message (can be removed once we released for a weeks the libsession util)
if ( window . sessionFeatureFlags . useSharedUtilForUserConfig && Registration . isDone ( ) ) {
2023-01-25 05:26:28 +01:00
return ;
}
2022-03-23 05:57:11 +01:00
const latestProfileUpdateTimestamp = getLastProfileUpdateTimestamp ( ) ;
2021-03-02 01:27:20 +01:00
if ( ! latestProfileUpdateTimestamp || sentAt > latestProfileUpdateTimestamp ) {
window ? . log ? . info (
` Handling our profileUdpate ourLastUpdate: ${ latestProfileUpdateTimestamp } , envelope sent at: ${ sentAt } `
) ;
const { profileKey , profilePicture , displayName } = configMessage ;
2023-03-28 05:44:41 +02:00
await updateOurProfileLegacyOrViaLibSession (
toNumber ( sentAt ) ,
displayName ,
profilePicture ,
2023-04-21 07:17:24 +02:00
profileKey ,
null // passing null to say do not the prioroti, as we do not get one from the legacy config message
2023-03-28 05:44:41 +02:00
) ;
2021-03-02 01:27:20 +01:00
}
}
2023-02-15 06:02:38 +01:00
async function handleGroupsAndContactsFromConfigMessageLegacy (
2021-03-02 01:27:20 +01:00
envelope : EnvelopePlus ,
configMessage : SignalService.ConfigurationMessage
) {
2023-03-31 02:33:30 +02:00
if ( window . sessionFeatureFlags . useSharedUtilForUserConfig && Registration . isDone ( ) ) {
2023-02-15 06:02:38 +01:00
return ;
}
2023-03-28 05:44:41 +02:00
const envelopeTimestamp = toNumber ( envelope . timestamp ) ;
2022-08-08 01:50:48 +02:00
const lastConfigUpdate = await Data . getItemById ( hasSyncedInitialConfigurationItem ) ;
2022-02-23 05:35:31 +01:00
const lastConfigTimestamp = lastConfigUpdate ? . timestamp ;
2022-03-08 05:42:07 +01:00
const isNewerConfig =
2022-03-09 05:04:28 +01:00
! lastConfigTimestamp || ( lastConfigTimestamp && lastConfigTimestamp < envelopeTimestamp ) ;
2022-02-23 05:35:31 +01:00
2022-03-08 05:42:07 +01:00
if ( ! isNewerConfig ) {
2022-03-08 06:47:34 +01:00
window ? . log ? . info ( 'Received outdated configuration message... Dropping message.' ) ;
2022-03-08 05:42:07 +01:00
return ;
2021-11-23 23:32:07 +01:00
}
2022-08-08 01:50:48 +02:00
await Data . createOrUpdateItem ( {
2021-11-26 03:20:03 +01:00
id : 'hasSyncedInitialConfigurationItem' ,
value : true ,
2022-03-09 05:04:28 +01:00
timestamp : envelopeTimestamp ,
2021-11-26 03:20:03 +01:00
} ) ;
2022-03-09 05:04:28 +01:00
// we only want to apply changes to closed groups if we never got them
// new opengroups get added when we get a new closed group message from someone, or a sync'ed message from outself creating the group
if ( ! lastConfigTimestamp ) {
2023-02-15 06:02:38 +01:00
await handleClosedGroupsFromConfigLegacy ( configMessage . closedGroups , envelope ) ;
2022-03-09 05:04:28 +01:00
}
2021-03-02 01:27:20 +01:00
2022-03-08 06:11:54 +01:00
handleOpenGroupsFromConfig ( configMessage . openGroups ) ;
2022-03-08 05:42:07 +01:00
if ( configMessage . contacts ? . length ) {
2023-02-15 06:02:38 +01:00
await Promise . all (
configMessage . contacts . map ( async c = > handleContactFromConfigLegacy ( c , envelope ) )
) ;
2022-03-08 05:42:07 +01:00
}
}
2021-03-02 01:27:20 +01:00
2022-03-08 05:42:07 +01:00
/ * *
* Trigger a join for all open groups we are not already in .
* @param openGroups string array of open group urls
* /
2022-03-08 06:11:54 +01:00
const handleOpenGroupsFromConfig = ( openGroups : Array < string > ) = > {
2023-03-31 02:33:30 +02:00
if ( window . sessionFeatureFlags . useSharedUtilForUserConfig && Registration . isDone ( ) ) {
2023-02-15 06:02:38 +01:00
return ;
}
2022-03-08 05:42:07 +01:00
const numberOpenGroup = openGroups ? . length || 0 ;
2021-03-02 01:27:20 +01:00
for ( let i = 0 ; i < numberOpenGroup ; i ++ ) {
2022-03-08 05:42:07 +01:00
const currentOpenGroupUrl = openGroups [ i ] ;
2021-05-27 07:29:07 +02:00
const parsedRoom = parseOpenGroupV2 ( currentOpenGroupUrl ) ;
if ( ! parsedRoom ) {
continue ;
}
const roomConvoId = getOpenGroupV2ConversationId ( parsedRoom . serverUrl , parsedRoom . roomId ) ;
2021-06-24 07:10:38 +02:00
if ( ! getConversationController ( ) . get ( roomConvoId ) ) {
2021-05-27 07:29:07 +02:00
window ? . log ? . info (
` triggering join of public chat ' ${ currentOpenGroupUrl } ' from ConfigurationMessage `
) ;
void joinOpenGroupV2WithUIEvents ( currentOpenGroupUrl , false , true ) ;
2021-03-02 01:27:20 +01:00
}
}
2022-03-08 05:42:07 +01:00
} ;
2021-03-02 01:27:20 +01:00
2022-03-09 05:04:28 +01:00
/ * *
* Trigger a join for all closed groups which doesn ' t exist yet
* @param openGroups string array of open group urls
* /
2023-02-15 06:02:38 +01:00
const handleClosedGroupsFromConfigLegacy = async (
2022-03-09 05:04:28 +01:00
closedGroups : Array < SignalService.ConfigurationMessage.IClosedGroup > ,
envelope : EnvelopePlus
) = > {
2023-03-31 02:33:30 +02:00
if ( window . sessionFeatureFlags . useSharedUtilForUserConfig && Registration . isDone ( ) ) {
2023-02-15 06:02:38 +01:00
return ;
}
2022-03-09 05:04:28 +01:00
const numberClosedGroup = closedGroups ? . length || 0 ;
window ? . log ? . info (
` Received ${ numberClosedGroup } closed group on configuration. Creating them... `
) ;
await Promise . all (
closedGroups . map ( async c = > {
const groupUpdate = new SignalService . DataMessage . ClosedGroupControlMessage ( {
type : SignalService . DataMessage . ClosedGroupControlMessage . Type . NEW ,
encryptionKeyPair : c.encryptionKeyPair ,
name : c.name ,
admins : c.admins ,
members : c.members ,
publicKey : c.publicKey ,
} ) ;
try {
await handleNewClosedGroup ( envelope , groupUpdate ) ;
} catch ( e ) {
2023-03-30 05:15:59 +02:00
window ? . log ? . warn ( 'failed to handle a new closed group from configuration message' ) ;
2022-03-09 05:04:28 +01:00
}
} )
) ;
} ;
2022-03-08 05:42:07 +01:00
/ * *
* Handles adding of a contact and setting approval / block status
* @param contactReceived Contact to sync
* /
2023-02-15 06:02:38 +01:00
const handleContactFromConfigLegacy = async (
2021-11-04 04:47:47 +01:00
contactReceived : SignalService.ConfigurationMessage.IContact ,
envelope : EnvelopePlus
) = > {
2023-03-31 02:33:30 +02:00
if ( window . sessionFeatureFlags . useSharedUtilForUserConfig && Registration . isDone ( ) ) {
2023-02-15 06:02:38 +01:00
return ;
}
2021-11-04 04:47:47 +01:00
try {
2021-12-08 04:15:54 +01:00
if ( ! contactReceived . publicKey ? . length ) {
2021-11-04 04:47:47 +01:00
return ;
}
const contactConvo = await getConversationController ( ) . getOrCreateAndWait (
toHex ( contactReceived . publicKey ) ,
ConversationTypeEnum . PRIVATE
) ;
2022-08-08 01:50:48 +02:00
const profileInDataMessage : SignalService.DataMessage.ILokiProfile = {
2021-11-04 04:47:47 +01:00
displayName : contactReceived.name ,
2022-08-08 01:50:48 +02:00
profilePicture : contactReceived.profilePicture ,
2021-11-04 04:47:47 +01:00
} ;
2021-12-08 04:15:54 +01:00
const existingActiveAt = contactConvo . get ( 'active_at' ) ;
if ( ! existingActiveAt || existingActiveAt === 0 ) {
2023-03-28 05:44:41 +02:00
contactConvo . set ( 'active_at' , toNumber ( envelope . timestamp ) ) ;
2021-12-08 04:15:54 +01:00
}
2021-11-04 04:47:47 +01:00
2022-02-23 05:35:31 +01:00
// checking for existence of field on protobuf
2022-02-22 01:39:52 +01:00
if ( contactReceived . isApproved === true ) {
2022-02-23 04:08:34 +01:00
if ( ! contactConvo . isApproved ( ) ) {
2022-02-23 05:35:31 +01:00
await contactConvo . setIsApproved ( Boolean ( contactReceived . isApproved ) ) ;
2023-03-28 05:44:41 +02:00
await contactConvo . addOutgoingApprovalMessage ( toNumber ( envelope . timestamp ) ) ;
2022-02-23 04:08:34 +01:00
}
2022-02-22 00:08:51 +01:00
2022-02-22 01:39:52 +01:00
if ( contactReceived . didApproveMe === true ) {
// checking for existence of field on message
2022-02-22 00:08:51 +01:00
await contactConvo . setDidApproveMe ( Boolean ( contactReceived . didApproveMe ) ) ;
}
2022-02-17 12:05:13 +01:00
}
2021-11-16 04:40:52 +01:00
2023-02-16 01:02:45 +01:00
// only set for explicit true/false values in case outdated sender doesn't have the fields
2022-02-22 01:39:52 +01:00
if ( contactReceived . isBlocked === true ) {
2022-03-02 03:04:33 +01:00
if ( contactConvo . isIncomingRequest ( ) ) {
2022-02-23 10:19:47 +01:00
// handling case where restored device's declined message requests were getting restored
2022-02-24 01:40:25 +01:00
await ConversationInteraction . deleteAllMessagesByConvoIdNoConfirmation ( contactConvo . id ) ;
2022-02-23 10:19:47 +01:00
}
2022-02-17 12:05:13 +01:00
await BlockedNumberController . block ( contactConvo . id ) ;
2022-02-22 01:39:52 +01:00
} else if ( contactReceived . isBlocked === false ) {
2023-02-21 07:09:08 +01:00
await BlockedNumberController . unblockAll ( [ contactConvo . id ] ) ;
2021-11-04 04:47:47 +01:00
}
2023-01-31 01:30:56 +01:00
await ProfileManager . updateProfileOfContact (
2023-01-25 05:26:28 +01:00
contactConvo . id ,
2023-01-31 01:30:56 +01:00
profileInDataMessage . displayName || undefined ,
profileInDataMessage . profilePicture || null ,
contactReceived . profileKey || null
2022-08-08 01:50:48 +02:00
) ;
2021-11-04 04:47:47 +01:00
} catch ( e ) {
window ? . log ? . warn ( 'failed to handle a new closed group from configuration message' ) ;
}
} ;
2023-01-10 07:24:56 +01:00
/ * *
* This is the legacy way of handling incoming configuration message .
* Should not be used at all soon .
* /
2023-02-15 06:02:38 +01:00
async function handleConfigurationMessageLegacy (
2021-03-02 01:27:20 +01:00
envelope : EnvelopePlus ,
configurationMessage : SignalService.ConfigurationMessage
) : Promise < void > {
2023-03-31 02:33:30 +02:00
// when the useSharedUtilForUserConfig flag is ON, we want only allow a legacy config message if we are registering a new user.
// this is to allow users linking a device to find their config message if they do not have a shared config message yet.
// the process of those messages is always done after the process of the shared config messages, so that's only a fallback.
if ( window . sessionFeatureFlags . useSharedUtilForUserConfig && Registration . isDone ( ) ) {
2023-01-10 07:24:56 +01:00
window ? . log ? . info (
2023-02-15 06:02:38 +01:00
'useSharedUtilForUserConfig is set, not handling config messages with "handleConfigurationMessageLegacy()"'
2023-01-10 07:24:56 +01:00
) ;
2023-04-21 08:17:14 +02:00
window . setSettingValue ( SettingsKey . someDeviceOutdatedSyncing , true ) ;
2023-01-25 07:46:30 +01:00
await removeFromCache ( envelope ) ;
2023-01-10 07:24:56 +01:00
return ;
}
2021-11-12 03:29:35 +01:00
window ? . log ? . info ( 'Handling configuration message' ) ;
2021-03-02 01:27:20 +01:00
const ourPubkey = UserUtils . getOurPubKeyStrFromCache ( ) ;
if ( ! ourPubkey ) {
return ;
}
if ( envelope . source !== ourPubkey ) {
2021-04-22 10:03:58 +02:00
window ? . log ? . info ( 'Dropping configuration change from someone else than us.' ) ;
2021-03-02 01:27:20 +01:00
return removeFromCache ( envelope ) ;
}
2023-02-15 06:02:38 +01:00
await handleOurProfileUpdateLegacy ( envelope . timestamp , configurationMessage ) ;
2021-03-02 01:27:20 +01:00
2023-02-15 06:02:38 +01:00
await handleGroupsAndContactsFromConfigMessageLegacy ( envelope , configurationMessage ) ;
2021-03-02 01:27:20 +01:00
await removeFromCache ( envelope ) ;
}
2023-01-10 07:24:56 +01:00
export const ConfigMessageHandler = {
2023-02-15 06:02:38 +01:00
handleConfigurationMessageLegacy ,
2023-03-08 07:39:29 +01:00
handleConfigMessagesViaLibSession ,
2023-01-10 07:24:56 +01:00
} ;