2023-03-27 23:48:57 +00:00
|
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
|
|
|
|
import type { MessageAttributesType } from '../model-types.d';
|
|
|
|
import type { MessageModel } from '../models/messages';
|
|
|
|
import * as Errors from '../types/errors';
|
|
|
|
import * as log from '../logging/log';
|
|
|
|
import { drop } from '../util/drop';
|
|
|
|
import { filter, size } from '../util/iterables';
|
|
|
|
import { getContactId } from '../messages/helpers';
|
|
|
|
import { handleEditMessage } from '../util/handleEditMessage';
|
2023-05-16 17:37:12 +00:00
|
|
|
import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp';
|
2023-03-27 23:48:57 +00:00
|
|
|
|
|
|
|
export type EditAttributesType = {
|
2023-04-20 16:31:59 +00:00
|
|
|
conversationId: string;
|
2023-03-27 23:48:57 +00:00
|
|
|
fromId: string;
|
2023-05-31 18:14:38 +00:00
|
|
|
fromDevice: number;
|
2023-03-27 23:48:57 +00:00
|
|
|
message: MessageAttributesType;
|
|
|
|
targetSentTimestamp: number;
|
|
|
|
};
|
|
|
|
|
|
|
|
const edits = new Set<EditAttributesType>();
|
|
|
|
|
|
|
|
export function forMessage(message: MessageModel): Array<EditAttributesType> {
|
2023-05-16 17:37:12 +00:00
|
|
|
const sentAt = getMessageSentTimestamp(message.attributes, { log });
|
2023-03-27 23:48:57 +00:00
|
|
|
const matchingEdits = filter(edits, item => {
|
|
|
|
return (
|
2023-05-16 17:37:12 +00:00
|
|
|
item.targetSentTimestamp === sentAt &&
|
2023-03-27 23:48:57 +00:00
|
|
|
item.fromId === getContactId(message.attributes)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (size(matchingEdits) > 0) {
|
2023-04-20 16:31:59 +00:00
|
|
|
const result = Array.from(matchingEdits);
|
|
|
|
const editsLogIds = result.map(x => x.message.sent_at);
|
|
|
|
log.info(
|
|
|
|
`Edits.forMessage(${message.get('sent_at')}): ` +
|
|
|
|
`Found early edits for message ${editsLogIds.join(', ')}`
|
|
|
|
);
|
2023-03-27 23:48:57 +00:00
|
|
|
filter(matchingEdits, item => edits.delete(item));
|
2023-04-20 16:31:59 +00:00
|
|
|
return result;
|
2023-03-27 23:48:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
export async function onEdit(edit: EditAttributesType): Promise<void> {
|
|
|
|
edits.add(edit);
|
|
|
|
|
2023-07-05 22:38:37 +00:00
|
|
|
const logId = `Edits.onEdit(timestamp=${edit.message.timestamp};target=${edit.targetSentTimestamp})`;
|
|
|
|
|
2023-03-27 23:48:57 +00:00
|
|
|
try {
|
2023-03-29 21:58:16 +00:00
|
|
|
// The conversation the edited message was in; we have to find it in the database
|
2023-03-27 23:48:57 +00:00
|
|
|
// to to figure that out.
|
|
|
|
const targetConversation =
|
|
|
|
await window.ConversationController.getConversationForTargetMessage(
|
|
|
|
edit.fromId,
|
|
|
|
edit.targetSentTimestamp
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!targetConversation) {
|
2023-07-05 22:38:37 +00:00
|
|
|
log.info(`${logId}: No target conversation`);
|
2023-03-27 23:48:57 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do not await, since this can deadlock the queue
|
|
|
|
drop(
|
|
|
|
targetConversation.queueJob('Edits.onEdit', async () => {
|
2023-07-05 22:38:37 +00:00
|
|
|
log.info(`${logId}: Handling edit`);
|
2023-03-27 23:48:57 +00:00
|
|
|
|
|
|
|
const messages = await window.Signal.Data.getMessagesBySentAt(
|
|
|
|
edit.targetSentTimestamp
|
|
|
|
);
|
|
|
|
|
|
|
|
// Verify authorship
|
|
|
|
const targetMessage = messages.find(
|
|
|
|
m =>
|
2023-04-20 16:31:59 +00:00
|
|
|
edit.conversationId === m.conversationId &&
|
2023-03-27 23:48:57 +00:00
|
|
|
edit.fromId === getContactId(m)
|
|
|
|
);
|
|
|
|
|
|
|
|
if (!targetMessage) {
|
2023-07-05 22:38:37 +00:00
|
|
|
log.info(`${logId}: No message`);
|
2023-03-27 23:48:57 +00:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const message = window.MessageController.register(
|
|
|
|
targetMessage.id,
|
|
|
|
targetMessage
|
|
|
|
);
|
|
|
|
|
|
|
|
await handleEditMessage(message.attributes, edit);
|
|
|
|
|
|
|
|
edits.delete(edit);
|
|
|
|
})
|
|
|
|
);
|
|
|
|
} catch (error) {
|
2023-07-05 22:38:37 +00:00
|
|
|
log.error(`${logId} error:`, Errors.toLogFormat(error));
|
2023-03-27 23:48:57 +00:00
|
|
|
}
|
|
|
|
}
|