fix: don't drop groupUpdateMessages from a blocked user

because we still need to process some things even if he is blocked
(getting promoted, etc).
If the message needs to be dropped, we should not have that group at
all, so that message will be dropped nevertheless
pull/3052/head
Audric Ackermann 11 months ago
parent 1aa9091026
commit 8ce5f6f429

@ -33,7 +33,6 @@ const Container = styled.div`
display: flex;
flex-direction: row;
justify-content: center;
padding: var(--margins-lg);
background-color: var(--background-secondary-color);
`;

@ -1,5 +1,5 @@
import _, { difference } from 'lodash';
import React, { useMemo } from 'react';
import React, { useMemo, useState } from 'react';
import { useDispatch } from 'react-redux';
import useKey from 'react-use/lib/useKey';
import styled from 'styled-components';
@ -31,6 +31,8 @@ import { groupInfoActions } from '../../state/ducks/metaGroups';
import { useMemberGroupChangePending } from '../../state/selectors/groups';
import { useSelectedIsGroupV2 } from '../../state/selectors/selectedConversation';
import { SessionSpinner } from '../basic/SessionSpinner';
import { SessionToggle } from '../basic/SessionToggle';
import { isDevProd, isTestIntegration } from '../../shared/env_vars';
type Props = {
conversationId: string;
@ -193,6 +195,7 @@ export const UpdateGroupMembersDialog = (props: Props) => {
const displayName = useConversationUsername(conversationId);
const groupAdmins = useGroupAdmins(conversationId);
const isProcessingUIChange = useMemberGroupChangePending();
const [alsoRemoveMessages, setAlsoRemoveMessages] = useState(false);
const {
addTo,
@ -217,7 +220,7 @@ export const UpdateGroupMembersDialog = (props: Props) => {
addMembersWithHistory: [],
addMembersWithoutHistory: [],
removeMembers: difference(existingMembers, membersToKeepWithUpdate) as Array<PubkeyType>,
alsoRemoveMessages: false, // FIXME audric debugger we need this to be a toggle for QA
alsoRemoveMessages,
});
dispatch(groupv2Action as any);
@ -272,6 +275,17 @@ export const UpdateGroupMembersDialog = (props: Props) => {
return (
<SessionWrapperModal title={titleText} onClose={closeDialog}>
{isDevProd() || isTestIntegration() ? (
<>
Also remove messages:
<SessionToggle
active={alsoRemoveMessages}
onClick={() => {
setAlsoRemoveMessages(!alsoRemoveMessages);
}}
/>
</>
) : null}
<StyledClassicMemberList className="group-member-list__selection">
<ClassicMemberList
convoId={conversationId}

@ -2705,6 +2705,7 @@ async function commitConversationAndRefreshWrapper(id: string) {
const savedDetails = await Data.saveConversation(convo.attributes);
await convo.refreshInMemoryDetails(savedDetails);
// Performance impact on this is probably to be pretty bad. We might want to push for that DB refactor to be done sooner so we do not need to fetch info from the DB anymore
for (let index = 0; index < LibSessionUtil.requiredUserVariants.length; index++) {
const variant = LibSessionUtil.requiredUserVariants[index];

@ -360,47 +360,53 @@ async function shouldDropIncomingPrivateMessage(
function shouldDropBlockedUserMessage(
content: SignalService.Content,
groupPubkey: string
fromSwarmOf: string
): boolean {
// Even if the user is blocked, we should allow the message if:
// Even if the user is blocked, we should allow a group control message message if:
// - it is a group message AND
// - the group exists already on the db (to not join a closed group created by a blocked user) AND
// - the group is not blocked AND
// - the message is only control (no body/attachments/quote/groupInvitation/contact/preview)
// - the message is a LegacyControlMessage or GroupUpdateMessage
// In addition to the above, we also want to allow a groupUpdatePromote message (sent as a 1o1 message)
if (!groupPubkey) {
if (!fromSwarmOf) {
return true;
}
const groupConvo = ConvoHub.use().get(groupPubkey);
if (!groupConvo || !groupConvo.isClosedGroup()) {
const convo = ConvoHub.use().get(fromSwarmOf);
if (!convo || !content.dataMessage || isEmpty(content.dataMessage)) {
// returning true means that we drop that message
return true;
}
if (groupConvo.isBlocked()) {
if (convo.isClosedGroup() && convo.isBlocked()) {
// when we especially blocked a group, we don't want to process anything from it
return true;
}
// first check that dataMessage is the only field set in the Content
let msgWithoutDataMessage = pickBy(
content,
(_value, key) => key !== 'dataMessage' && key !== 'toJSON'
const data = content.dataMessage as SignalService.DataMessage; // forcing it as we do know this field is set based on last line
if (convo.isPrivate()) {
const isGroupV2PromoteMessage = !isEmpty(
content.dataMessage?.groupUpdateMessage?.promoteMessage
);
msgWithoutDataMessage = pickBy(msgWithoutDataMessage, identity);
if (isGroupV2PromoteMessage) {
// we want to allow a group v2 promote message sent by a blocked user (because that user is an admin of a group)
return false;
}
}
const isMessageDataMessageOnly = isEmpty(msgWithoutDataMessage);
if (!isMessageDataMessageOnly) {
if (!convo.isClosedGroup()) {
// 1o1 messages are handled above.
// if we get here and it's not part a closed group, we should drop that message.
// it might be a message sent to a community from a user we've blocked
return true;
}
const data = content.dataMessage as SignalService.DataMessage; // forcing it as we do know this field is set based on last line
const isControlDataMessageOnly =
!data.body &&
!data.preview?.length &&
!data.attachments?.length &&
!data.openGroupInvitation &&
!data.quote;
return !isControlDataMessageOnly;
const isLegacyGroupUpdateMessage = !isEmpty(data.closedGroupControlMessage);
const isGroupV2UpdateMessage = !isEmpty(data.groupUpdateMessage);
return !isLegacyGroupUpdateMessage && !isGroupV2UpdateMessage;
}
async function dropIncomingGroupMessage(envelope: EnvelopePlus, sentAtTimestamp: number) {
@ -466,10 +472,14 @@ export async function innerHandleSwarmContentMessage({
const envelopeSource = envelope.source;
// We want to allow a blocked user message if that's a control message for a known group and the group is not blocked
if (shouldDropBlockedUserMessage(content, envelopeSource)) {
window?.log?.info('Dropping blocked user message');
window?.log?.info(
`Dropping blocked user message ${ed25519Str(envelope.senderIdentity || envelope.source)}`
);
return;
}
window?.log?.info('Allowing group-control message only from blocked user');
window?.log?.info(
`Allowing control/update message only from blocked user ${ed25519Str(envelope.senderIdentity)} in group: ${ed25519Str(envelope.source)}`
);
}
if (await dropIncomingGroupMessage(envelope, sentAtTimestamp)) {
@ -513,12 +523,11 @@ export async function innerHandleSwarmContentMessage({
* For a private conversation message, this is just the conversation with that user
*/
if (!isPrivateConversationMessage) {
console.info('conversationModelForUIUpdate might need to be checked for groupv2 case'); // debugger
// this is a closed group message, we have a second conversation to make sure exists
conversationModelForUIUpdate = await ConvoHub.use().getOrCreateAndWait(
envelope.source,
ConversationTypeEnum.GROUP
);
// this is a group message,
// we have a second conversation to make sure exists: the group conversation
conversationModelForUIUpdate = PubKey.is03Pubkey(envelope.source)
? await ConvoHub.use().getOrCreateAndWait(envelope.source, ConversationTypeEnum.GROUPV2)
: await ConvoHub.use().getOrCreateAndWait(envelope.source, ConversationTypeEnum.GROUP);
}
const expireUpdate = await DisappearingMessages.checkForExpireUpdateInContentMessage(

@ -356,7 +356,6 @@ async function handleGroupMemberLeftMessage({
})
);
// TODO We should process this message type even if the sender is blocked
}
async function handleGroupUpdateMemberLeftNotificationMessage({
@ -469,7 +468,6 @@ async function handleGroupDeleteMemberContentMessage({
)
);
convo.updateLastMessage();
// TODO we should process this message type even if the sender is blocked
}
async function handleGroupUpdateInviteResponseMessage({
@ -494,7 +492,6 @@ async function handleGroupUpdateInviteResponseMessage({
window.inboxStore.dispatch(groupInfoActions.inviteResponseReceived({ groupPk, member: author }));
// TODO We should process this message type even if the sender is blocked
}
async function handleGroupUpdatePromoteMessage({
@ -535,7 +532,6 @@ async function handleGroupUpdatePromoteMessage({
})
);
// TODO we should process this even if the sender is blocked
}
async function handle1o1GroupUpdateMessage(

@ -69,7 +69,6 @@ export class ClosedGroupVisibleMessage extends ClosedGroupMessage {
type WithDestinationGroupPk = { destination: GroupPubkeyType };
// TODO audric debugger This will need to extend ExpirableMessage after Disappearing Messages V2 is merged and checkd still working
export class ClosedGroupV2VisibleMessage extends DataMessage {
private readonly chatMessage: VisibleMessage;
public readonly destination: GroupPubkeyType;

Loading…
Cancel
Save