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: // Even if the user is blocked, we should allow the message if:
// - it is a group message AND // - 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 exists already on the db (to not join a closed group created by a blocked user) AND
// - the group is not blocked AND // - the group is not blocked AND
// - the message is only control (no body/attachments/quote/groupInvitation/contact/preview) // - the message is only control (no body/attachments/quote/groupInvitation/contact/preview)
if (!content?.dataMessage?.group?.id) { if (!groupPubkey) {
return true; return true;
} }
const groupId = toHex(content.dataMessage.group.id);
const groupConvo = getConversationController().get(groupId); const groupConvo = getConversationController().get(groupPubkey);
if (!groupConvo) { if (!groupConvo || !groupConvo.isClosedGroup()) {
return true; return true;
} }
@ -317,7 +319,7 @@ function shouldDropBlockedUserMessage(content: SignalService.Content): boolean {
if (!isMessageDataMessageOnly) { if (!isMessageDataMessageOnly) {
return true; 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 = const isControlDataMessageOnly =
!data.body && !data.body &&
!data.preview?.length && !data.preview?.length &&
@ -343,11 +345,21 @@ export async function innerHandleSwarmContentMessage(
const content = SignalService.Content.decode(new Uint8Array(plaintext)); const content = SignalService.Content.decode(new Uint8Array(plaintext));
perfEnd(`SignalService.Content.decode-${envelope.id}`, 'SignalService.Content.decode'); 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'); perfEnd(`isBlocked-${envelope.id}`, 'isBlocked');
if (blocked) { 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 // 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'); window?.log?.info('Dropping blocked user message');
return; return;
} else { } else {

View file

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

View file

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