From c4e9aab66c1e3ac03f21250327f05a10542570a1 Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Wed, 10 Jul 2024 16:57:19 +1000 Subject: [PATCH] fix: remove invite/promote to group message once processed --- ts/receiver/callMessage.ts | 3 ++- ts/receiver/dataMessage.ts | 1 + ts/receiver/groupv2/handleGroupV2Message.ts | 18 ++++++++++++++++-- .../libsession/handleLibSessionMessage.ts | 5 ++--- ts/session/crypto/index.ts | 4 ++++ ts/session/types/with.ts | 7 +++---- ts/session/utils/calling/CallManager.ts | 2 +- ts/state/ducks/metaGroups.ts | 16 ++++++++-------- .../browser/libsession_worker_interface.ts | 7 +++++++ 9 files changed, 44 insertions(+), 19 deletions(-) diff --git a/ts/receiver/callMessage.ts b/ts/receiver/callMessage.ts index 9a9d86dda..d54d41a2a 100644 --- a/ts/receiver/callMessage.ts +++ b/ts/receiver/callMessage.ts @@ -3,9 +3,10 @@ import { SignalService } from '../protobuf'; import { GetNetworkTime } from '../session/apis/snode_api/getNetworkTime'; import { TTL_DEFAULT } from '../session/constants'; import { CallManager, UserUtils } from '../session/utils'; -import { WithMessageHash, WithOptExpireUpdate } from '../session/utils/calling/CallManager'; +import { WithOptExpireUpdate } from '../session/utils/calling/CallManager'; import { IncomingMessageCache } from './cache'; import { EnvelopePlus } from './types'; +import { WithMessageHash } from '../session/types/with'; // messageHash & messageHash are only needed for actions adding a callMessage to the database (so they expire) export async function handleCallMessage( diff --git a/ts/receiver/dataMessage.ts b/ts/receiver/dataMessage.ts index 42bf4cb64..e653210a6 100644 --- a/ts/receiver/dataMessage.ts +++ b/ts/receiver/dataMessage.ts @@ -173,6 +173,7 @@ export async function handleSwarmDataMessage({ source: envelope.source, senderIdentity: envelope.senderIdentity, expireUpdate, + messageHash, }); // Groups update should always be able to be decrypted as we get the keys before trying to decrypt them. // If decryption failed once, it will keep failing, so no need to keep it in the cache. diff --git a/ts/receiver/groupv2/handleGroupV2Message.ts b/ts/receiver/groupv2/handleGroupV2Message.ts index 89274f7eb..537f241b7 100644 --- a/ts/receiver/groupv2/handleGroupV2Message.ts +++ b/ts/receiver/groupv2/handleGroupV2Message.ts @@ -29,6 +29,7 @@ import { MetaGroupWrapperActions, UserGroupsWrapperActions, } from '../../webworker/workers/browser/libsession_worker_interface'; +import { WithMessageHash } from '../../session/types/with'; type WithSignatureTimestamp = { signatureTimestamp: number }; type WithAuthor = { author: PubkeyType }; @@ -535,7 +536,8 @@ async function handle1o1GroupUpdateMessage( details: GroupUpdateDetails & WithUncheckedSource & WithUncheckedSenderIdentity & - WithDisappearingMessageUpdate + WithDisappearingMessageUpdate & + WithMessageHash ) { // the message types below are received from our own swarm, so source is the sender, and senderIdentity is empty @@ -558,6 +560,17 @@ async function handle1o1GroupUpdateMessage( author: details.source, }); } + if (details.messageHash && !isEmpty(details.messageHash)) { + const deleted = await deleteMessagesFromSwarmOnly( + [details.messageHash], + UserUtils.getOurPubKeyStrFromCache() + ); + if (!deleted) { + window.log.warn( + `failed to delete invite/promote while processing it in handle1o1GroupUpdateMessage. hash:${details.messageHash}` + ); + } + } // returns true for all cases where this message was expected to be a 1o1 message, even if not processed return true; @@ -570,7 +583,8 @@ async function handleGroupUpdateMessage( details: GroupUpdateDetails & WithUncheckedSource & WithUncheckedSenderIdentity & - WithDisappearingMessageUpdate + WithDisappearingMessageUpdate & + WithMessageHash ) { const was1o1Message = await handle1o1GroupUpdateMessage(details); if (was1o1Message) { diff --git a/ts/receiver/libsession/handleLibSessionMessage.ts b/ts/receiver/libsession/handleLibSessionMessage.ts index 4e862f968..ba537e8a3 100644 --- a/ts/receiver/libsession/handleLibSessionMessage.ts +++ b/ts/receiver/libsession/handleLibSessionMessage.ts @@ -1,9 +1,8 @@ import { EncryptionDomain, GroupPubkeyType, PubkeyType } from 'libsession_util_nodejs'; import { isNumber, toNumber } from 'lodash'; import { ConvoHub } from '../../session/conversations'; -import { LibSodiumWrappers } from '../../session/crypto'; +import { LibSodiumWrappers, WithLibSodiumWrappers } from '../../session/crypto'; import { PubKey } from '../../session/types'; -import { WithLibSodiuMWrappers } from '../../session/types/with'; import { DecryptionFailed, InvalidMessage } from '../../session/utils/errors'; import { assertUnreachable } from '../../types/sqlSharedTypes'; import { @@ -67,7 +66,7 @@ async function handleLibSessionMessage( domain: EncryptionDomain; ourPk: PubkeyType; groupPk: GroupPubkeyType; - } & WithLibSodiuMWrappers + } & WithLibSodiumWrappers ) { switch (opts.domain) { case 'SessionGroupKickedMessage': diff --git a/ts/session/crypto/index.ts b/ts/session/crypto/index.ts index 287d630db..be2d461f0 100644 --- a/ts/session/crypto/index.ts +++ b/ts/session/crypto/index.ts @@ -6,6 +6,10 @@ import { toHex } from '../utils/String'; export type LibSodiumWrappers = typeof libsodiumwrappers; +export type WithLibSodiumWrappers = { + sodium: LibSodiumWrappers; +}; + export async function getSodiumRenderer(): Promise { await libsodiumwrappers.ready; return libsodiumwrappers; diff --git a/ts/session/types/with.ts b/ts/session/types/with.ts index 2b17bb54c..e0c805293 100644 --- a/ts/session/types/with.ts +++ b/ts/session/types/with.ts @@ -1,5 +1,4 @@ -import { LibSodiumWrappers } from '../crypto'; -export type WithLibSodiuMWrappers = { - sodium: LibSodiumWrappers; -}; + + +export type WithMessageHash = { messageHash: string }; \ No newline at end of file diff --git a/ts/session/utils/calling/CallManager.ts b/ts/session/utils/calling/CallManager.ts index 2cb83f1bc..a281e5064 100644 --- a/ts/session/utils/calling/CallManager.ts +++ b/ts/session/utils/calling/CallManager.ts @@ -35,13 +35,13 @@ import { MessageSender } from '../../sending'; import { getIsRinging } from '../RingingManager'; import { getBlackSilenceMediaStream } from './Silence'; import { ed25519Str } from '../String'; +import { WithMessageHash } from '../../types/with'; export type InputItem = { deviceId: string; label: string }; export const callTimeoutMs = 60000; export type WithOptExpireUpdate = { expireDetails: ReadyToDisappearMsgUpdate | undefined }; -export type WithMessageHash = { messageHash: string }; /** * This uuid is set only once we accepted a call or started one. diff --git a/ts/state/ducks/metaGroups.ts b/ts/state/ducks/metaGroups.ts index e1604105e..6dfc12cc3 100644 --- a/ts/state/ducks/metaGroups.ts +++ b/ts/state/ducks/metaGroups.ts @@ -151,11 +151,11 @@ const initNewGroupInWrapper = createAsyncThunk( for (let index = 0; index < uniqMembers.length; index++) { const member = uniqMembers[index]; - const created = await MetaGroupWrapperActions.memberGetOrConstruct(groupPk, member); - if (created.pubkeyHex === us) { - await MetaGroupWrapperActions.memberSetAdmin(groupPk, created.pubkeyHex); + await MetaGroupWrapperActions.memberConstructAndSet(groupPk, member); + if (member === us) { + await MetaGroupWrapperActions.memberSetAdmin(groupPk, member); } else { - await MetaGroupWrapperActions.memberSetInvited(groupPk, created.pubkeyHex, false); + await MetaGroupWrapperActions.memberSetInvited(groupPk, member, false); } } @@ -493,8 +493,8 @@ async function handleWithHistoryMembers({ }) { for (let index = 0; index < withHistory.length; index++) { const member = withHistory[index]; - const created = await MetaGroupWrapperActions.memberGetOrConstruct(groupPk, member); - await MetaGroupWrapperActions.memberSetInvited(groupPk, created.pubkeyHex, false); + await MetaGroupWrapperActions.memberConstructAndSet(groupPk, member); + await MetaGroupWrapperActions.memberSetInvited(groupPk, member, false); } const encryptedSupplementKeys = withHistory.length ? await MetaGroupWrapperActions.generateSupplementKeys(groupPk, withHistory) @@ -512,8 +512,8 @@ async function handleWithoutHistoryMembers({ }: WithGroupPubkey & WithAddWithoutHistoryMembers) { for (let index = 0; index < withoutHistory.length; index++) { const member = withoutHistory[index]; - const created = await MetaGroupWrapperActions.memberGetOrConstruct(groupPk, member); - await MetaGroupWrapperActions.memberSetInvited(groupPk, created.pubkeyHex, false); + await MetaGroupWrapperActions.memberConstructAndSet(groupPk, member); + await MetaGroupWrapperActions.memberSetInvited(groupPk, member, false); } if (!isEmpty(withoutHistory)) { diff --git a/ts/webworker/workers/browser/libsession_worker_interface.ts b/ts/webworker/workers/browser/libsession_worker_interface.ts index 349dc41ab..886c27835 100644 --- a/ts/webworker/workers/browser/libsession_worker_interface.ts +++ b/ts/webworker/workers/browser/libsession_worker_interface.ts @@ -514,6 +514,13 @@ export const MetaGroupWrapperActions: MetaGroupWrapperActionsCalls = { 'memberGetOrConstruct', pubkeyHex, ]) as Promise>, + memberConstructAndSet: async (groupPk: GroupPubkeyType, pubkeyHex: PubkeyType) => + callLibSessionWorker([ + `MetaGroupConfig-${groupPk}`, + 'memberConstructAndSet', + pubkeyHex, + ]) as Promise>, + memberGetAll: async (groupPk: GroupPubkeyType) => callLibSessionWorker([`MetaGroupConfig-${groupPk}`, 'memberGetAll']) as Promise< ReturnType