Fix call migration for unregistered conversations without serviceId

This commit is contained in:
Jamie Kyle 2023-08-17 15:29:02 -07:00 committed by Jamie Kyle
parent 2d62569984
commit 0273e1ac1d
2 changed files with 52 additions and 23 deletions

View file

@ -21,7 +21,6 @@ import { CallMode } from '../../types/Calling';
import type { MessageType, ConversationType } from '../Interface';
import { strictAssert } from '../../util/assert';
import { missingCaseError } from '../../util/missingCaseError';
import type { ServiceIdString } from '../../types/ServiceId';
import { isAciString } from '../../types/ServiceId';
// Legacy type for calls that never had a call id
@ -87,9 +86,16 @@ function upcastCallHistoryDetailsFromDiskType(
}
function getPeerIdFromConversation(
conversation: Pick<ConversationType, 'type' | 'serviceId' | 'groupId'>
conversation: ConversationType,
logger: LoggerType
): string {
if (conversation.type === 'private') {
if (conversation.serviceId == null) {
logger.warn(
`updateToSchemaVersion89: Private conversation (${conversation.id}) was missing serviceId (discoveredUnregisteredAt: ${conversation.discoveredUnregisteredAt})`
);
return conversation.id;
}
strictAssert(
isAciString(conversation.serviceId),
'ACI must exist for direct chat'
@ -228,9 +234,7 @@ export default function updateToSchemaVersion89(
const [selectQuery] = sql`
SELECT
messages.json AS messageJson,
conversations.type AS conversationType,
conversations.serviceId AS conversationServiceId,
conversations.groupId AS conversationGroupId
conversations.json AS conversationJson
FROM messages
LEFT JOIN conversations ON conversations.id = messages.conversationId
WHERE messages.type = 'call-history'
@ -243,28 +247,19 @@ export default function updateToSchemaVersion89(
// Must match query above
type CallHistoryRow = {
messageJson: string;
conversationType: ConversationType['type'];
conversationServiceId: ServiceIdString | undefined;
conversationGroupId: string | undefined;
conversationJson: string;
};
const rows: Array<CallHistoryRow> = db.prepare(selectQuery).all();
for (const row of rows) {
const {
messageJson,
conversationType,
conversationServiceId,
conversationGroupId,
} = row;
const { messageJson, conversationJson } = row;
const message = jsonToObject<MessageWithCallHistoryDetails>(messageJson);
const conversation = jsonToObject<ConversationType>(conversationJson);
const details = message.callHistoryDetails;
const peerId = getPeerIdFromConversation({
type: conversationType,
serviceId: conversationServiceId,
groupId: conversationGroupId,
});
const peerId = getPeerIdFromConversation(conversation, logger);
const callHistory = convertLegacyCallDetails(
ourUuid,

View file

@ -99,16 +99,31 @@ describe('SQL/updateToSchemaVersion89', () => {
return message;
}
function createConversation(type: 'private' | 'group') {
function createConversation(
type: 'private' | 'group',
discoveredUnregisteredAt?: number
) {
const id = generateGuid();
const serviceId = type === 'private' ? generateGuid() : null;
const serviceId =
// Emulate older unregistered conversations
type === 'private' && discoveredUnregisteredAt == null
? generateGuid()
: null;
const groupId = type === 'group' ? generateGuid() : null;
const json = JSON.stringify({
type,
id,
serviceId,
groupId,
discoveredUnregisteredAt,
});
const [query, params] = sql`
INSERT INTO conversations
(id, type, serviceId, groupId)
(id, type, serviceId, groupId, json)
VALUES
(${id}, ${type}, ${serviceId}, ${groupId});
(${id}, ${type}, ${serviceId}, ${groupId}, ${json});
`;
db.prepare(query).run(params);
@ -266,6 +281,25 @@ describe('SQL/updateToSchemaVersion89', () => {
assert.strictEqual(callHistory[1].peerId, conversation2.groupId);
});
it('migrates older unregistered conversations with no serviceId', () => {
updateToVersion(db, 88);
const conversation = createConversation('private', Date.now());
createCallHistoryMessage({
messageId: generateGuid(),
conversationId: conversation.id,
callHistoryDetails: getDirectCallHistoryDetails({
callId: '123',
}),
});
updateToVersion(db, 89);
const callHistory = getAllCallHistory();
assert.strictEqual(callHistory.length, 1);
assert.strictEqual(callHistory[0].peerId, conversation.id);
});
describe('clients with schema version 87', () => {
function createCallHistoryTable() {
const [query] = sql`