diff --git a/ts/types/Message2.ts b/ts/types/Message2.ts index 3105400085..9616eceffe 100644 --- a/ts/types/Message2.ts +++ b/ts/types/Message2.ts @@ -466,21 +466,26 @@ const toVersion12 = _withSchemaVersion({ const result = { ...message }; + const logId = `Message2.toVersion12(${message.sent_at})`; + if (attachments?.length) { result.attachments = await Promise.all( - attachments.map(async attachment => { - const copy = await encryptLegacyAttachment(attachment, context); + attachments.map(async (attachment, i) => { + const copy = await encryptLegacyAttachment(attachment, { + ...context, + logId: `${logId}.attachments[${i}]`, + }); if (copy.thumbnail) { - copy.thumbnail = await encryptLegacyAttachment( - copy.thumbnail, - context - ); + copy.thumbnail = await encryptLegacyAttachment(copy.thumbnail, { + ...context, + logId: `${logId}.attachments[${i}].thumbnail`, + }); } if (copy.screenshot) { - copy.screenshot = await encryptLegacyAttachment( - copy.screenshot, - context - ); + copy.screenshot = await encryptLegacyAttachment(copy.screenshot, { + ...context, + logId: `${logId}.attachments[${i}].screenshot`, + }); } return copy; }) @@ -488,31 +493,27 @@ const toVersion12 = _withSchemaVersion({ } if (quote && quote.attachments?.length) { - try { - result.quote = { - ...quote, - attachments: await Promise.all( - quote.attachments.map(async quoteAttachment => { - return { - ...quoteAttachment, - thumbnail: - quoteAttachment.thumbnail && - (await encryptLegacyAttachment( - quoteAttachment.thumbnail, - context - )), - }; - }) - ), - }; - } catch (error) { - context.logger.error(`Failed to migrate quote for ${message.id}`); - } + result.quote = { + ...quote, + attachments: await Promise.all( + quote.attachments.map(async (quoteAttachment, i) => { + return { + ...quoteAttachment, + thumbnail: + quoteAttachment.thumbnail && + (await encryptLegacyAttachment(quoteAttachment.thumbnail, { + ...context, + logId: `${logId}.quote[${i}].thumbnail`, + })), + }; + }) + ), + }; } if (contact?.length) { result.contact = await Promise.all( - contact.map(async c => { + contact.map(async (c, i) => { if (!c.avatar?.avatar) { return c; } @@ -521,7 +522,10 @@ const toVersion12 = _withSchemaVersion({ ...c, avatar: { ...c.avatar, - avatar: await encryptLegacyAttachment(c.avatar.avatar, context), + avatar: await encryptLegacyAttachment(c.avatar.avatar, { + ...context, + logId: `${logId}.contact[${i}].avatar`, + }), }, }; }) @@ -530,14 +534,17 @@ const toVersion12 = _withSchemaVersion({ if (preview?.length) { result.preview = await Promise.all( - preview.map(async p => { + preview.map(async (p, i) => { if (!p.image) { return p; } return { ...p, - image: await encryptLegacyAttachment(p.image, context), + image: await encryptLegacyAttachment(p.image, { + ...context, + logId: `${logId}.preview[${i}].image`, + }), }; }) ); @@ -547,10 +554,16 @@ const toVersion12 = _withSchemaVersion({ result.sticker = { ...sticker, data: sticker.data && { - ...(await encryptLegacyAttachment(sticker.data, context)), + ...(await encryptLegacyAttachment(sticker.data, { + ...context, + logId: `${logId}.sticker.data`, + })), thumbnail: sticker.data.thumbnail && - (await encryptLegacyAttachment(sticker.data.thumbnail, context)), + (await encryptLegacyAttachment(sticker.data.thumbnail, { + ...context, + logId: `${logId}.sticker.thumbnail`, + })), }, }; } diff --git a/ts/types/Stickers.ts b/ts/types/Stickers.ts index 8a01bf273e..8599e2c425 100644 --- a/ts/types/Stickers.ts +++ b/ts/types/Stickers.ts @@ -1009,6 +1009,7 @@ async function encryptLegacySticker( window.Signal.Migrations; const updated = await encryptLegacyAttachment(sticker, { + logId: 'sticker', readAttachmentData: readStickerData, writeNewAttachmentData: writeNewStickerData, disposition: AttachmentDisposition.Sticker, diff --git a/ts/util/encryptConversationAttachments.ts b/ts/util/encryptConversationAttachments.ts index 46cfc5a211..c48c7b7d14 100644 --- a/ts/util/encryptConversationAttachments.ts +++ b/ts/util/encryptConversationAttachments.ts @@ -10,6 +10,7 @@ import { encryptLegacyAttachment } from './encryptLegacyAttachment'; import { AttachmentDisposition } from './getLocalAttachmentUrl'; import { isNotNil } from './isNotNil'; import { isSignalConversation } from './isSignalConversation'; +import { getConversationIdForLogging } from './idForLogging'; const CONCURRENCY = 32; @@ -66,6 +67,7 @@ async function encryptOne(attributes: ConversationAttributesType): Promise< return undefined; } + const logId = getConversationIdForLogging(attributes); const result = { ...attributes }; const { @@ -86,6 +88,7 @@ async function encryptOne(attributes: ConversationAttributesType): Promise< result.profileAvatar = await encryptLegacyAttachment( attributes.profileAvatar, { + logId: `${logId}.profileAvatar`, readAttachmentData, writeNewAttachmentData, disposition: AttachmentDisposition.Attachment, @@ -99,6 +102,7 @@ async function encryptOne(attributes: ConversationAttributesType): Promise< if (attributes.avatar?.path) { result.avatar = await encryptLegacyAttachment(attributes.avatar, { + logId: `${logId}.avatar`, readAttachmentData, writeNewAttachmentData, disposition: AttachmentDisposition.Attachment, @@ -111,7 +115,7 @@ async function encryptOne(attributes: ConversationAttributesType): Promise< if (attributes.avatars?.length) { result.avatars = await Promise.all( - attributes.avatars.map(async avatar => { + attributes.avatars.map(async (avatar, i) => { if (avatar.version === 2 || !avatar.imagePath) { return avatar; } @@ -121,6 +125,7 @@ async function encryptOne(attributes: ConversationAttributesType): Promise< path: avatar.imagePath, }, { + logId: `${logId}.avatars[${i}]`, readAttachmentData: readAvatarData, writeNewAttachmentData: writeNewAvatarData, disposition: AttachmentDisposition.AvatarData, @@ -141,8 +146,9 @@ async function encryptOne(attributes: ConversationAttributesType): Promise< if (attributes.draftAttachments?.length) { result.draftAttachments = await Promise.all( - attributes.draftAttachments.map(async draft => { + attributes.draftAttachments.map(async (draft, i) => { const updated = await encryptLegacyAttachment(draft, { + logId: `${logId}.draft[${i}]`, readAttachmentData: readDraftData, writeNewAttachmentData: writeNewDraftData, disposition: AttachmentDisposition.Draft, diff --git a/ts/util/encryptLegacyAttachment.ts b/ts/util/encryptLegacyAttachment.ts index 7231704396..8b3e6fe7c0 100644 --- a/ts/util/encryptLegacyAttachment.ts +++ b/ts/util/encryptLegacyAttachment.ts @@ -2,10 +2,12 @@ // SPDX-License-Identifier: AGPL-3.0-only import LRU from 'lru-cache'; + import type { AddressableAttachmentType, LocalAttachmentV2Type, } from '../types/Attachment'; +import * as log from '../logging/log'; import { AttachmentDisposition } from './getLocalAttachmentUrl'; let setCheck = false; @@ -15,6 +17,7 @@ const lru = new LRU>({ }); export type EncryptLegacyAttachmentOptionsType = Readonly<{ + logId: string; disposition?: AttachmentDisposition; readAttachmentData: ( attachment: Partial @@ -43,12 +46,18 @@ export async function encryptLegacyAttachment< promise = doEncrypt(attachment, options); lru.set(cacheKey, promise); } - const modern = await promise; + try { + const modern = await promise; - return { - ...attachment, - ...modern, - }; + return { + ...attachment, + ...modern, + }; + } catch (error) { + const { logId } = options; + log.error(`${logId}: migration failed, falling back to original`, error); + return attachment; + } } async function doEncrypt>(