Improve message content cleanup behavior

Co-authored-by: trevor-signal <131492920+trevor-signal@users.noreply.github.com>
This commit is contained in:
automated-signal
2025-12-09 09:41:50 -06:00
committed by GitHub
parent 4cd4e7a604
commit 981fd638f9
11 changed files with 239 additions and 42 deletions

View File

@@ -1,9 +1,12 @@
// Copyright 2018 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { MessageAttributesType } from '../model-types.js';
import { strictAssert } from '../util/assert.std.js';
import type { DurationInSeconds } from '../util/durations/index.std.js';
import type { AttachmentType } from './Attachment.std.js';
import type { EmbeddedContactType } from './EmbeddedContact.std.js';
import type { ErrorIfOverlapping, ExactKeys } from './Util.std.js';
export function getMentionsRegex(): RegExp {
return /\uFFFC/g;
@@ -92,3 +95,115 @@ export type MessageSchemaVersion6 = Partial<
contact: Array<EmbeddedContactType>;
}>
>;
// NB: see `eraseMessageContents` for all scenarios in which message content can be erased
export const messageAttrsToPreserveAfterErase = [
// TS required fields
'id',
'timestamp',
'conversationId',
'type',
'sent_at',
'received_at',
// all other, non-TS-required fields to preserve
'canReplyToStory',
'deletedForEveryone',
'deletedForEveryoneFailed',
'deletedForEveryoneSendStatus',
'deletedForEveryoneTimestamp',
'editMessageReceivedAt',
'editMessageReceivedAtMs',
'editMessageTimestamp',
'errors',
'expirationStartTimestamp',
'expireTimer',
'isErased',
'isTapToViewInvalid',
'isViewOnce',
'readAt',
'readStatus',
'received_at_ms',
'requiredProtocolVersion',
'schemaMigrationAttempts',
'schemaVersion',
'seenStatus',
'sendStateByConversationId',
'serverGuid',
'serverTimestamp',
'source',
'sourceDevice',
'sourceServiceId',
'storyId',
'synced',
'unidentifiedDeliveries',
] as const;
const messageAttrsToErase = [
'attachments',
'body',
'bodyAttachment',
'bodyRanges',
'callId',
'changedId',
'contact',
'conversationMerge',
'dataMessage',
'decrypted_at',
'droppedGV2MemberIds',
'editHistory',
'expirationTimerUpdate',
'flags',
'giftBadge',
'group_update',
'groupMigration',
'groupV2Change',
'hasUnreadPollVotes',
'invitedGV2Members',
'unidentifiedDeliveryReceived',
'key_changed',
'local',
'logger',
'mentionsMe',
'message',
'messageRequestResponseEvent',
'messageTimer',
'payment',
'phoneNumberDiscovery',
'pinnedMessageId',
'poll',
'pollTerminateNotification',
'preview',
'profileChange',
'quote',
'reactions',
'sendHQImages',
'sms',
'sticker',
'storyDistributionListId',
'storyReaction',
'storyRecipientsVersion',
'storyReplyContext',
'supportedVersionAtReceive',
'titleTransition',
'verified',
'verifiedChanged',
] as const;
const allKeys = [
...messageAttrsToPreserveAfterErase,
...messageAttrsToErase,
] as const;
// Note: if this errors, it's likely that the keys of MessageAttributesType have changed
// and you need to update messageAttrsToPreserveAfterErase or
// messageAttributesToEraseIfMessageContentsAreErased as needed
const _enforceTypeCheck: ExactKeys<MessageAttributesType, typeof allKeys> =
{} as MessageAttributesType;
strictAssert(_enforceTypeCheck != null, 'type check');
const _checkKeys: ErrorIfOverlapping<
typeof messageAttrsToPreserveAfterErase,
typeof messageAttrsToErase
> = undefined;
strictAssert(_checkKeys === undefined, 'type check');