Skip to content

Commit

Permalink
Improve handling of DOE sync messages for stories
Browse files Browse the repository at this point in the history
Co-authored-by: Fedor Indutny <79877362+indutny-signal@users.noreply.github.com>
  • Loading branch information
automated-signal and indutny-signal committed Nov 30, 2022
1 parent 4a85790 commit 88a2c3e
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 10 deletions.
5 changes: 5 additions & 0 deletions ts/models/messages.ts
Expand Up @@ -3559,7 +3559,12 @@ export class MessageModel extends window.Backbone.Model<MessageAttributesType> {
del: DeleteModel,
shouldPersist = true
): Promise<void> {
if (this.deletingForEveryone || this.get('deletedForEveryone')) {
return;
}

log.info('Handling DOE.', {
messageId: this.id,
fromId: del.get('fromId'),
targetSentTimestamp: del.get('targetSentTimestamp'),
messageServerTimestamp: this.get('serverTimestamp'),
Expand Down
17 changes: 13 additions & 4 deletions ts/util/deleteForEveryone.ts
Expand Up @@ -5,18 +5,27 @@ import type { DeleteModel } from '../messageModifiers/Deletes';
import type { MessageModel } from '../models/messages';
import * as log from '../logging/log';
import { DAY } from './durations';
import { isMe } from './whatTypeOfConversation';
import { getContactId } from '../messages/helpers';
import { isStory } from '../state/selectors/message';

export async function deleteForEveryone(
message: MessageModel,
doe: DeleteModel,
shouldPersist = true
): Promise<void> {
if (message.deletingForEveryone || message.get('deletedForEveryone')) {
return;
}

if (isDeletionByMe(message, doe)) {
const conversation = message.getConversation();

// Our 1:1 stories are deleted through ts/util/onStoryRecipientUpdate.ts
if (
isStory(message.attributes) &&
conversation &&
isMe(conversation.attributes)
) {
return;
}

await message.handleDeleteForEveryone(doe, shouldPersist);
return;
}
Expand Down
28 changes: 22 additions & 6 deletions ts/util/onStoryRecipientUpdate.ts
Expand Up @@ -5,13 +5,13 @@ import { isEqual } from 'lodash';
import type { DeleteAttributesType } from '../messageModifiers/Deletes';
import type { StoryRecipientUpdateEvent } from '../textsecure/messageReceiverEvents';
import * as log from '../logging/log';
import { Deletes } from '../messageModifiers/Deletes';
import { DeleteModel } from '../messageModifiers/Deletes';
import { SendStatus } from '../messages/MessageSendState';
import { deleteForEveryone } from './deleteForEveryone';
import { getConversationIdForLogging } from './idForLogging';
import { isStory } from '../state/selectors/message';
import { normalizeUuid } from './normalizeUuid';
import { queueUpdateMessage } from './messageBatcher';
import { isMe } from './whatTypeOfConversation';

export async function onStoryRecipientUpdate(
event: StoryRecipientUpdateEvent
Expand All @@ -25,7 +25,12 @@ export async function onStoryRecipientUpdate(
const logId = `onStoryRecipientUpdate(${destinationUuid}, ${timestamp})`;

if (!conversation) {
log.info(`${logId}: no conversation`);
log.warn(`${logId}: no conversation`);
return;
}

if (!isMe(conversation.attributes)) {
log.warn(`${logId}: story recipient update on invalid conversation`);
return;
}

Expand All @@ -47,7 +52,13 @@ export async function onStoryRecipientUpdate(
const isAllowedToReply = new Map<string, boolean>();
const distributionListIdToConversationIds = new Map<string, Set<string>>();
data.storyMessageRecipients.forEach(item => {
const convo = window.ConversationController.get(item.destinationUuid);
if (!item.destinationUuid) {
return;
}

const convo = window.ConversationController.get(
normalizeUuid(item.destinationUuid, `${logId}.destinationUuid`)
);

if (!convo || !item.distributionListIds) {
return;
Expand Down Expand Up @@ -161,11 +172,16 @@ export async function onStoryRecipientUpdate(
serverTimestamp: Number(item.serverTimestamp),
targetSentTimestamp: item.timestamp,
};
const doe = Deletes.getSingleton().add(delAttributes);
const doe = new DeleteModel(delAttributes);

// There are no longer any remaining members for this message so lets
// run it through deleteForEveryone which marks the message as
// deletedForEveryone locally.
deleteForEveryone(message, doe);
//
// NOTE: We don't call `Deletes.onDelete()` so the message lookup by
// sent timestamp doesn't happen (it would return all copies of the
// story, not just the one we want to delete).
message.handleDeleteForEveryone(doe);
} else {
message.set({
sendStateByConversationId: nextSendStateByConversationId,
Expand Down

0 comments on commit 88a2c3e

Please sign in to comment.