Merge contacts when we discover split or duplicated contacts

This commit is contained in:
Scott Nonnenberg 2020-07-10 11:28:49 -07:00
parent 68e432188b
commit 901179440f
32 changed files with 1199 additions and 824 deletions

View file

@ -19,12 +19,15 @@ import { arrayBufferToBase64, base64ToArrayBuffer } from '../Crypto';
import { CURRENT_SCHEMA_VERSION } from '../../js/modules/types/message';
import { createBatcher } from '../util/batcher';
import {
ConversationModelCollectionType,
ConversationModelType,
MessageModelCollectionType,
MessageModelType,
} from '../model-types.d';
import {
AttachmentDownloadJobType,
BackboneConversationCollectionType,
BackboneConversationModelType,
BackboneMessageCollectionType,
BackboneMessageModelType,
ClientInterface,
ClientJobType,
ConversationType,
@ -153,6 +156,7 @@ const dataInterface: ClientInterface = {
getOlderMessagesByConversation,
getNewerMessagesByConversation,
getMessageMetricsForConversation,
migrateConversationMessages,
getUnprocessedCount,
getAllUnprocessed,
@ -719,7 +723,7 @@ async function saveConversations(array: Array<ConversationType>) {
async function getConversationById(
id: string,
{ Conversation }: { Conversation: BackboneConversationModelType }
{ Conversation }: { Conversation: typeof ConversationModelType }
) {
const data = await channels.getConversationById(id);
@ -749,7 +753,7 @@ async function updateConversations(array: Array<ConversationType>) {
async function removeConversation(
id: string,
{ Conversation }: { Conversation: BackboneConversationModelType }
{ Conversation }: { Conversation: typeof ConversationModelType }
) {
const existing = await getConversationById(id, { Conversation });
@ -769,8 +773,8 @@ async function _removeConversations(ids: Array<string>) {
async function getAllConversations({
ConversationCollection,
}: {
ConversationCollection: BackboneConversationCollectionType;
}) {
ConversationCollection: typeof ConversationModelCollectionType;
}): Promise<ConversationModelCollectionType> {
const conversations = await channels.getAllConversations();
const collection = new ConversationCollection();
@ -788,7 +792,7 @@ async function getAllConversationIds() {
async function getAllPrivateConversations({
ConversationCollection,
}: {
ConversationCollection: BackboneConversationCollectionType;
ConversationCollection: typeof ConversationModelCollectionType;
}) {
const conversations = await channels.getAllPrivateConversations();
@ -803,7 +807,7 @@ async function getAllGroupsInvolvingId(
{
ConversationCollection,
}: {
ConversationCollection: BackboneConversationCollectionType;
ConversationCollection: typeof ConversationModelCollectionType;
}
) {
const conversations = await channels.getAllGroupsInvolvingId(id);
@ -861,7 +865,7 @@ async function saveMessage(
{
forceSave,
Message,
}: { forceSave?: boolean; Message: BackboneMessageModelType }
}: { forceSave?: boolean; Message: typeof MessageModelType }
) {
const id = await channels.saveMessage(_cleanData(data), { forceSave });
Message.updateTimers();
@ -878,7 +882,7 @@ async function saveMessages(
async function removeMessage(
id: string,
{ Message }: { Message: BackboneMessageModelType }
{ Message }: { Message: typeof MessageModelType }
) {
const message = await getMessageById(id, { Message });
@ -897,7 +901,7 @@ async function _removeMessages(ids: Array<string>) {
async function getMessageById(
id: string,
{ Message }: { Message: BackboneMessageModelType }
{ Message }: { Message: typeof MessageModelType }
) {
const message = await channels.getMessageById(id);
if (!message) {
@ -911,7 +915,7 @@ async function getMessageById(
async function _getAllMessages({
MessageCollection,
}: {
MessageCollection: BackboneMessageCollectionType;
MessageCollection: typeof MessageModelCollectionType;
}) {
const messages = await channels._getAllMessages();
@ -936,7 +940,7 @@ async function getMessageBySender(
sourceDevice: string;
sent_at: number;
},
{ Message }: { Message: BackboneMessageModelType }
{ Message }: { Message: typeof MessageModelType }
) {
const messages = await channels.getMessageBySender({
source,
@ -953,7 +957,9 @@ async function getMessageBySender(
async function getUnreadByConversation(
conversationId: string,
{ MessageCollection }: { MessageCollection: BackboneMessageCollectionType }
{
MessageCollection,
}: { MessageCollection: typeof MessageModelCollectionType }
) {
const messages = await channels.getUnreadByConversation(conversationId);
@ -975,7 +981,7 @@ async function getOlderMessagesByConversation(
limit?: number;
receivedAt?: number;
messageId?: string;
MessageCollection: BackboneMessageCollectionType;
MessageCollection: typeof MessageModelCollectionType;
}
) {
const messages = await channels.getOlderMessagesByConversation(
@ -998,7 +1004,7 @@ async function getNewerMessagesByConversation(
}: {
limit?: number;
receivedAt?: number;
MessageCollection: BackboneMessageCollectionType;
MessageCollection: typeof MessageModelCollectionType;
}
) {
const messages = await channels.getNewerMessagesByConversation(
@ -1018,10 +1024,18 @@ async function getMessageMetricsForConversation(conversationId: string) {
return result;
}
async function migrateConversationMessages(
obsoleteId: string,
currentId: string
) {
await channels.migrateConversationMessages(obsoleteId, currentId);
}
async function removeAllMessagesInConversation(
conversationId: string,
{ MessageCollection }: { MessageCollection: BackboneMessageCollectionType }
{
MessageCollection,
}: { MessageCollection: typeof MessageModelCollectionType }
) {
let messages;
do {
@ -1036,12 +1050,12 @@ async function removeAllMessagesInConversation(
return;
}
const ids = messages.map((message: BackboneMessageModelType) => message.id);
const ids = messages.map((message: MessageModelType) => message.id);
// Note: It's very important that these models are fully hydrated because
// we need to delete all associated on-disk files along with the database delete.
await Promise.all(
messages.map((message: BackboneMessageModelType) => message.cleanup())
messages.map(async (message: MessageModelType) => message.cleanup())
);
await channels.removeMessage(ids);
@ -1050,7 +1064,9 @@ async function removeAllMessagesInConversation(
async function getMessagesBySentAt(
sentAt: number,
{ MessageCollection }: { MessageCollection: BackboneMessageCollectionType }
{
MessageCollection,
}: { MessageCollection: typeof MessageModelCollectionType }
) {
const messages = await channels.getMessagesBySentAt(sentAt);
@ -1060,7 +1076,7 @@ async function getMessagesBySentAt(
async function getExpiredMessages({
MessageCollection,
}: {
MessageCollection: BackboneMessageCollectionType;
MessageCollection: typeof MessageModelCollectionType;
}) {
const messages = await channels.getExpiredMessages();
@ -1070,7 +1086,7 @@ async function getExpiredMessages({
async function getOutgoingWithoutExpiresAt({
MessageCollection,
}: {
MessageCollection: BackboneMessageCollectionType;
MessageCollection: typeof MessageModelCollectionType;
}) {
const messages = await channels.getOutgoingWithoutExpiresAt();
@ -1080,7 +1096,7 @@ async function getOutgoingWithoutExpiresAt({
async function getNextExpiringMessage({
Message,
}: {
Message: BackboneMessageModelType;
Message: typeof MessageModelType;
}) {
const message = await channels.getNextExpiringMessage();
@ -1094,7 +1110,7 @@ async function getNextExpiringMessage({
async function getNextTapToViewMessageToAgeOut({
Message,
}: {
Message: BackboneMessageModelType;
Message: typeof MessageModelType;
}) {
const message = await channels.getNextTapToViewMessageToAgeOut();
if (!message) {
@ -1106,7 +1122,7 @@ async function getNextTapToViewMessageToAgeOut({
async function getTapToViewMessagesNeedingErase({
MessageCollection,
}: {
MessageCollection: BackboneMessageCollectionType;
MessageCollection: typeof MessageModelCollectionType;
}) {
const messages = await channels.getTapToViewMessagesNeedingErase();