Merge pull request #2468 from Bilb/drop-messages-no-visible-content

fix: drop .group from incoming messages & exclude it from visible check
This commit is contained in:
Audric Ackermann 2022-09-05 15:08:29 +10:00 committed by GitHub
commit 89dfe6e49d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 45 deletions

View file

@ -285,20 +285,22 @@ async function decrypt(envelope: EnvelopePlus, ciphertext: ArrayBuffer): Promise
}
}
function shouldDropBlockedUserMessage(content: SignalService.Content): boolean {
function shouldDropBlockedUserMessage(
content: SignalService.Content,
groupPubkey: string
): boolean {
// Even if the user is blocked, we should allow the 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)
if (!content?.dataMessage?.group?.id) {
if (!groupPubkey) {
return true;
}
const groupId = toHex(content.dataMessage.group.id);
const groupConvo = getConversationController().get(groupId);
if (!groupConvo) {
const groupConvo = getConversationController().get(groupPubkey);
if (!groupConvo || !groupConvo.isClosedGroup()) {
return true;
}
@ -317,7 +319,7 @@ function shouldDropBlockedUserMessage(content: SignalService.Content): boolean {
if (!isMessageDataMessageOnly) {
return true;
}
const data = content.dataMessage;
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 &&
@ -343,11 +345,21 @@ export async function innerHandleSwarmContentMessage(
const content = SignalService.Content.decode(new Uint8Array(plaintext));
perfEnd(`SignalService.Content.decode-${envelope.id}`, 'SignalService.Content.decode');
const blocked = await isBlocked(envelope.source);
/**
* senderIdentity is set ONLY if that message is a closed group message.
* If the current message is a closed group message,
* envelope.source is going to be the real sender of that message.
*
* When receiving a message from a user which we blocked, we need to make let
* a control message through (if the associated closed group is not blocked)
*/
const blocked = await isBlocked(envelope.senderIdentity || envelope.source);
perfEnd(`isBlocked-${envelope.id}`, 'isBlocked');
if (blocked) {
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)) {
if (shouldDropBlockedUserMessage(content, envelopeSource)) {
window?.log?.info('Dropping blocked user message');
return;
} else {

View file

@ -37,14 +37,13 @@ function cleanAttachment(attachment: any) {
}
function cleanAttachments(decrypted: SignalService.DataMessage) {
const { quote, group } = decrypted;
const { quote } = decrypted;
// Here we go from binary to string/base64 in all AttachmentPointer digest/key fields
// we do not care about group.avatar on Session
if (group && group.avatar !== null) {
group.avatar = null;
}
// we do not care about group on Session
decrypted.group = null;
decrypted.attachments = (decrypted.attachments || []).map(cleanAttachment);
decrypted.preview = (decrypted.preview || []).map((item: any) => {
@ -80,33 +79,17 @@ function cleanAttachments(decrypted: SignalService.DataMessage) {
}
}
/**
* We separate the isMessageEmpty and the isMessageEmptyExceptReaction, because we
* - sometimes want to drop a message only when it is completely empty,
* - and sometimes only when the message is empty but have a reaction
*/
function isMessageEmpty(message: SignalService.DataMessage) {
const { reaction } = message;
return isMessageEmptyExceptReaction(message) && isEmpty(reaction);
}
/**
* We separate the isMessageEmpty and the isMessageEmptyExceptReaction, because we
* - sometimes want to drop a message only when it is completely empty,
* - and sometimes only when the message is empty but have a reaction
*/
export function isMessageEmptyExceptReaction(message: SignalService.DataMessage) {
const { flags, body, attachments, group, quote, preview, openGroupInvitation } = message;
export function messageHasVisibleContent(message: SignalService.DataMessage) {
const { flags, body, attachments, quote, preview, openGroupInvitation, reaction } = message;
return (
!flags &&
isEmpty(body) &&
isEmpty(attachments) &&
isEmpty(group) &&
isEmpty(quote) &&
isEmpty(preview) &&
isEmpty(openGroupInvitation)
!!flags ||
!isEmpty(body) ||
!isEmpty(attachments) ||
!isEmpty(quote) ||
!isEmpty(preview) ||
!isEmpty(openGroupInvitation) ||
!isEmpty(reaction)
);
}
@ -232,7 +215,7 @@ export async function handleSwarmDataMessage(
);
}
if (isMessageEmpty(cleanDataMessage)) {
if (!messageHasVisibleContent(cleanDataMessage)) {
window?.log?.warn(`Message ${getEnvelopeId(envelope)} ignored; it was empty`);
return removeFromCache(envelope);
}

View file

@ -12,7 +12,7 @@ import { removeMessagePadding } from '../session/crypto/BufferPadding';
import { UserUtils } from '../session/utils';
import { perfEnd, perfStart } from '../session/utils/Performance';
import { fromBase64ToArray } from '../session/utils/String';
import { cleanIncomingDataMessage, isMessageEmptyExceptReaction } from './dataMessage';
import { cleanIncomingDataMessage, messageHasVisibleContent } from './dataMessage';
import { handleMessageJob, toRegularMessage } from './queuedJob';
export const handleOpenGroupV4Message = async (
@ -63,11 +63,8 @@ const handleOpenGroupMessage = async (
return;
}
if (isMessageEmptyExceptReaction(idataMessage as SignalService.DataMessage)) {
// empty message, drop it
if (!idataMessage.reaction) {
window.log.info('received an empty message for sogs');
}
if (!messageHasVisibleContent(idataMessage as SignalService.DataMessage)) {
window.log.info('received an empty message for sogs');
return;
}