Fix call migration for unregistered conversations without serviceId
This commit is contained in:
parent
2d62569984
commit
0273e1ac1d
2 changed files with 52 additions and 23 deletions
|
@ -21,7 +21,6 @@ import { CallMode } from '../../types/Calling';
|
||||||
import type { MessageType, ConversationType } from '../Interface';
|
import type { MessageType, ConversationType } from '../Interface';
|
||||||
import { strictAssert } from '../../util/assert';
|
import { strictAssert } from '../../util/assert';
|
||||||
import { missingCaseError } from '../../util/missingCaseError';
|
import { missingCaseError } from '../../util/missingCaseError';
|
||||||
import type { ServiceIdString } from '../../types/ServiceId';
|
|
||||||
import { isAciString } from '../../types/ServiceId';
|
import { isAciString } from '../../types/ServiceId';
|
||||||
|
|
||||||
// Legacy type for calls that never had a call id
|
// Legacy type for calls that never had a call id
|
||||||
|
@ -87,9 +86,16 @@ function upcastCallHistoryDetailsFromDiskType(
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPeerIdFromConversation(
|
function getPeerIdFromConversation(
|
||||||
conversation: Pick<ConversationType, 'type' | 'serviceId' | 'groupId'>
|
conversation: ConversationType,
|
||||||
|
logger: LoggerType
|
||||||
): string {
|
): string {
|
||||||
if (conversation.type === 'private') {
|
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(
|
strictAssert(
|
||||||
isAciString(conversation.serviceId),
|
isAciString(conversation.serviceId),
|
||||||
'ACI must exist for direct chat'
|
'ACI must exist for direct chat'
|
||||||
|
@ -228,9 +234,7 @@ export default function updateToSchemaVersion89(
|
||||||
const [selectQuery] = sql`
|
const [selectQuery] = sql`
|
||||||
SELECT
|
SELECT
|
||||||
messages.json AS messageJson,
|
messages.json AS messageJson,
|
||||||
conversations.type AS conversationType,
|
conversations.json AS conversationJson
|
||||||
conversations.serviceId AS conversationServiceId,
|
|
||||||
conversations.groupId AS conversationGroupId
|
|
||||||
FROM messages
|
FROM messages
|
||||||
LEFT JOIN conversations ON conversations.id = messages.conversationId
|
LEFT JOIN conversations ON conversations.id = messages.conversationId
|
||||||
WHERE messages.type = 'call-history'
|
WHERE messages.type = 'call-history'
|
||||||
|
@ -243,28 +247,19 @@ export default function updateToSchemaVersion89(
|
||||||
// Must match query above
|
// Must match query above
|
||||||
type CallHistoryRow = {
|
type CallHistoryRow = {
|
||||||
messageJson: string;
|
messageJson: string;
|
||||||
conversationType: ConversationType['type'];
|
conversationJson: string;
|
||||||
conversationServiceId: ServiceIdString | undefined;
|
|
||||||
conversationGroupId: string | undefined;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const rows: Array<CallHistoryRow> = db.prepare(selectQuery).all();
|
const rows: Array<CallHistoryRow> = db.prepare(selectQuery).all();
|
||||||
|
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
const {
|
const { messageJson, conversationJson } = row;
|
||||||
messageJson,
|
|
||||||
conversationType,
|
|
||||||
conversationServiceId,
|
|
||||||
conversationGroupId,
|
|
||||||
} = row;
|
|
||||||
const message = jsonToObject<MessageWithCallHistoryDetails>(messageJson);
|
const message = jsonToObject<MessageWithCallHistoryDetails>(messageJson);
|
||||||
|
const conversation = jsonToObject<ConversationType>(conversationJson);
|
||||||
|
|
||||||
const details = message.callHistoryDetails;
|
const details = message.callHistoryDetails;
|
||||||
|
|
||||||
const peerId = getPeerIdFromConversation({
|
const peerId = getPeerIdFromConversation(conversation, logger);
|
||||||
type: conversationType,
|
|
||||||
serviceId: conversationServiceId,
|
|
||||||
groupId: conversationGroupId,
|
|
||||||
});
|
|
||||||
|
|
||||||
const callHistory = convertLegacyCallDetails(
|
const callHistory = convertLegacyCallDetails(
|
||||||
ourUuid,
|
ourUuid,
|
||||||
|
|
|
@ -99,16 +99,31 @@ describe('SQL/updateToSchemaVersion89', () => {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createConversation(type: 'private' | 'group') {
|
function createConversation(
|
||||||
|
type: 'private' | 'group',
|
||||||
|
discoveredUnregisteredAt?: number
|
||||||
|
) {
|
||||||
const id = generateGuid();
|
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 groupId = type === 'group' ? generateGuid() : null;
|
||||||
|
|
||||||
|
const json = JSON.stringify({
|
||||||
|
type,
|
||||||
|
id,
|
||||||
|
serviceId,
|
||||||
|
groupId,
|
||||||
|
discoveredUnregisteredAt,
|
||||||
|
});
|
||||||
|
|
||||||
const [query, params] = sql`
|
const [query, params] = sql`
|
||||||
INSERT INTO conversations
|
INSERT INTO conversations
|
||||||
(id, type, serviceId, groupId)
|
(id, type, serviceId, groupId, json)
|
||||||
VALUES
|
VALUES
|
||||||
(${id}, ${type}, ${serviceId}, ${groupId});
|
(${id}, ${type}, ${serviceId}, ${groupId}, ${json});
|
||||||
`;
|
`;
|
||||||
|
|
||||||
db.prepare(query).run(params);
|
db.prepare(query).run(params);
|
||||||
|
@ -266,6 +281,25 @@ describe('SQL/updateToSchemaVersion89', () => {
|
||||||
assert.strictEqual(callHistory[1].peerId, conversation2.groupId);
|
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', () => {
|
describe('clients with schema version 87', () => {
|
||||||
function createCallHistoryTable() {
|
function createCallHistoryTable() {
|
||||||
const [query] = sql`
|
const [query] = sql`
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue