Fix author id for e164-only 1:1 messages
This commit is contained in:
parent
da29c1501f
commit
6cb86277be
2 changed files with 77 additions and 21 deletions
|
@ -213,6 +213,17 @@ export class BackupExportStream extends Readable {
|
||||||
readonly #serviceIdToRecipientId = new Map<string, number>();
|
readonly #serviceIdToRecipientId = new Map<string, number>();
|
||||||
readonly #e164ToRecipientId = new Map<string, number>();
|
readonly #e164ToRecipientId = new Map<string, number>();
|
||||||
readonly #roomIdToRecipientId = new Map<string, number>();
|
readonly #roomIdToRecipientId = new Map<string, number>();
|
||||||
|
readonly #stats = {
|
||||||
|
adHocCalls: 0,
|
||||||
|
callLinks: 0,
|
||||||
|
conversations: 0,
|
||||||
|
chats: 0,
|
||||||
|
distributionLists: 0,
|
||||||
|
messages: 0,
|
||||||
|
skippedMessages: 0,
|
||||||
|
stickerPacks: 0,
|
||||||
|
fixedDirectMessages: 0,
|
||||||
|
};
|
||||||
#ourConversation?: ConversationAttributesType;
|
#ourConversation?: ConversationAttributesType;
|
||||||
#attachmentBackupJobs: Array<CoreAttachmentBackupJobType> = [];
|
#attachmentBackupJobs: Array<CoreAttachmentBackupJobType> = [];
|
||||||
#buffers = new Array<Uint8Array>();
|
#buffers = new Array<Uint8Array>();
|
||||||
|
@ -277,17 +288,6 @@ export class BackupExportStream extends Readable {
|
||||||
});
|
});
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
|
|
||||||
const stats = {
|
|
||||||
adHocCalls: 0,
|
|
||||||
callLinks: 0,
|
|
||||||
conversations: 0,
|
|
||||||
chats: 0,
|
|
||||||
distributionLists: 0,
|
|
||||||
messages: 0,
|
|
||||||
skippedMessages: 0,
|
|
||||||
stickerPacks: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
const identityKeys = await DataReader.getAllIdentityKeys();
|
const identityKeys = await DataReader.getAllIdentityKeys();
|
||||||
const identityKeysById = new Map(
|
const identityKeysById = new Map(
|
||||||
identityKeys.map(key => {
|
identityKeys.map(key => {
|
||||||
|
@ -318,7 +318,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
stats.conversations += 1;
|
this.#stats.conversations += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#pushFrame({
|
this.#pushFrame({
|
||||||
|
@ -375,7 +375,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
stats.distributionLists += 1;
|
this.#stats.distributionLists += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const callLinks = await DataReader.getAllCallLinks();
|
const callLinks = await DataReader.getAllCallLinks();
|
||||||
|
@ -417,7 +417,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
stats.callLinks += 1;
|
this.#stats.callLinks += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stickerPacks = await getStickerPacksForBackup();
|
const stickerPacks = await getStickerPacksForBackup();
|
||||||
|
@ -432,7 +432,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
stats.stickerPacks += 1;
|
this.#stats.stickerPacks += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const pinnedConversationIds =
|
const pinnedConversationIds =
|
||||||
|
@ -507,7 +507,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
stats.chats += 1;
|
this.#stats.chats += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const allCallHistoryItems = await DataReader.getAllCallHistory();
|
const allCallHistoryItems = await DataReader.getAllCallHistory();
|
||||||
|
@ -538,7 +538,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
stats.adHocCalls += 1;
|
this.#stats.adHocCalls += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
let cursor: PageMessagesCursorType | undefined;
|
let cursor: PageMessagesCursorType | undefined;
|
||||||
|
@ -575,7 +575,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
for (const chatItem of items) {
|
for (const chatItem of items) {
|
||||||
if (chatItem === undefined) {
|
if (chatItem === undefined) {
|
||||||
stats.skippedMessages += 1;
|
this.#stats.skippedMessages += 1;
|
||||||
// Can't be backed up.
|
// Can't be backed up.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -586,7 +586,7 @@ export class BackupExportStream extends Readable {
|
||||||
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
stats.messages += 1;
|
this.#stats.messages += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor = newCursor;
|
cursor = newCursor;
|
||||||
|
@ -600,7 +600,7 @@ export class BackupExportStream extends Readable {
|
||||||
await this.#flush();
|
await this.#flush();
|
||||||
|
|
||||||
log.warn('backups: final stats', {
|
log.warn('backups: final stats', {
|
||||||
...stats,
|
...this.#stats,
|
||||||
attachmentBackupJobs: this.#attachmentBackupJobs.length,
|
attachmentBackupJobs: this.#attachmentBackupJobs.length,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1030,6 +1030,23 @@ export class BackupExportStream extends Readable {
|
||||||
serviceId: message.sourceServiceId,
|
serviceId: message.sourceServiceId,
|
||||||
e164: message.source,
|
e164: message.source,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (
|
||||||
|
isIncoming &&
|
||||||
|
conversation &&
|
||||||
|
isDirectConversation(conversation.attributes)
|
||||||
|
) {
|
||||||
|
const convoAuthor = this.#getOrPushPrivateRecipient({
|
||||||
|
id: conversation.attributes.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fix conversation id for misattributed e164-only incoming 1:1
|
||||||
|
// messages.
|
||||||
|
if (authorId.neq(convoAuthor)) {
|
||||||
|
authorId = convoAuthor;
|
||||||
|
this.#stats.fixedDirectMessages += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
strictAssert(!isIncoming, 'Incoming message must have source');
|
strictAssert(!isIncoming, 'Incoming message must have source');
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import { MY_STORY_ID } from '../../types/Stories';
|
||||||
|
|
||||||
const CONTACT_A = generateAci();
|
const CONTACT_A = generateAci();
|
||||||
const CONTACT_B = generateAci();
|
const CONTACT_B = generateAci();
|
||||||
|
const CONTACT_B_E164 = '+12135550123';
|
||||||
const GV1_ID = Bytes.toBinary(getRandomBytes(ID_V1_LENGTH));
|
const GV1_ID = Bytes.toBinary(getRandomBytes(ID_V1_LENGTH));
|
||||||
|
|
||||||
const BADGE_RECEIPT =
|
const BADGE_RECEIPT =
|
||||||
|
@ -60,7 +61,7 @@ describe('backup/bubble messages', () => {
|
||||||
contactB = await window.ConversationController.getOrCreateAndWait(
|
contactB = await window.ConversationController.getOrCreateAndWait(
|
||||||
CONTACT_B,
|
CONTACT_B,
|
||||||
'private',
|
'private',
|
||||||
{ systemGivenName: 'CONTACT_B', active_at: 1 }
|
{ systemGivenName: 'CONTACT_B', e164: CONTACT_B_E164, active_at: 1 }
|
||||||
);
|
);
|
||||||
|
|
||||||
gv1 = await window.ConversationController.getOrCreateAndWait(
|
gv1 = await window.ConversationController.getOrCreateAndWait(
|
||||||
|
@ -233,6 +234,44 @@ describe('backup/bubble messages', () => {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('fixes e164-only incoming 1:1 messages', async () => {
|
||||||
|
await asymmetricRoundtripHarness(
|
||||||
|
[
|
||||||
|
{
|
||||||
|
conversationId: contactA.id,
|
||||||
|
id: generateGuid(),
|
||||||
|
type: 'incoming',
|
||||||
|
received_at: 3,
|
||||||
|
received_at_ms: 3,
|
||||||
|
sent_at: 3,
|
||||||
|
// Note: contact B e164 vs contact A conversationId
|
||||||
|
source: CONTACT_B_E164,
|
||||||
|
readStatus: ReadStatus.Unread,
|
||||||
|
seenStatus: SeenStatus.Unseen,
|
||||||
|
unidentifiedDeliveryReceived: true,
|
||||||
|
timestamp: 3,
|
||||||
|
body: 'hello',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
conversationId: contactA.id,
|
||||||
|
id: generateGuid(),
|
||||||
|
type: 'incoming',
|
||||||
|
received_at: 3,
|
||||||
|
received_at_ms: 3,
|
||||||
|
sent_at: 3,
|
||||||
|
sourceServiceId: CONTACT_A,
|
||||||
|
readStatus: ReadStatus.Unread,
|
||||||
|
seenStatus: SeenStatus.Unseen,
|
||||||
|
unidentifiedDeliveryReceived: true,
|
||||||
|
timestamp: 3,
|
||||||
|
body: 'hello',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
describe('quotes', () => {
|
describe('quotes', () => {
|
||||||
it('roundtrips gift badge quote', async () => {
|
it('roundtrips gift badge quote', async () => {
|
||||||
await symmetricRoundtripHarness([
|
await symmetricRoundtripHarness([
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue