diff --git a/ts/jobs/helpers/sendNormalMessage.ts b/ts/jobs/helpers/sendNormalMessage.ts index f455e93cbb38..1d3a85c30a21 100644 --- a/ts/jobs/helpers/sendNormalMessage.ts +++ b/ts/jobs/helpers/sendNormalMessage.ts @@ -31,6 +31,7 @@ import type { UploadedAttachmentType, AttachmentWithHydratedData, } from '../../types/Attachment'; +import { copyCdnFields } from '../../util/attachments'; import { LONG_MESSAGE, MIMETypeToString } from '../../types/MIME'; import type { RawBodyRange } from '../../types/BodyRange'; import type { @@ -628,7 +629,10 @@ async function uploadSingleAttachment( ); const newAttachments = [...oldAttachments]; - newAttachments[index].digest = Bytes.toBase64(uploaded.digest); + newAttachments[index] = { + ...newAttachments[index], + ...copyCdnFields(uploaded), + }; message.set('attachments', newAttachments); @@ -698,14 +702,11 @@ async function uploadMessageQuote( const attachmentAfterThumbnailUpload = attachmentsAfterThumbnailUpload[index]; - const digest = attachmentAfterThumbnailUpload.thumbnail - ? Bytes.toBase64(attachmentAfterThumbnailUpload.thumbnail.digest) - : undefined; return { ...attachment, thumbnail: { ...attachment.thumbnail, - digest, + ...copyCdnFields(attachmentAfterThumbnailUpload.thumbnail), }, }; }), @@ -783,7 +784,7 @@ async function uploadMessagePreviews( ...preview, image: { ...preview.image, - digest: Bytes.toBase64(uploaded.image.digest), + ...copyCdnFields(uploaded.image), }, }; }); @@ -829,7 +830,7 @@ async function uploadMessageSticker( ...existingSticker, data: { ...existingSticker.data, - digest: Bytes.toBase64(uploaded.digest), + ...copyCdnFields(uploaded), }, }); @@ -917,7 +918,7 @@ async function uploadMessageContacts( ...contact.avatar, avatar: { ...contact.avatar.avatar, - digest: Bytes.toBase64(uploaded.avatar.avatar.digest), + ...copyCdnFields(uploaded.avatar.avatar), }, }, }; diff --git a/ts/models/messages.ts b/ts/models/messages.ts index f3e375c5fbbf..c55a2f7d9f42 100644 --- a/ts/models/messages.ts +++ b/ts/models/messages.ts @@ -42,6 +42,7 @@ import { SendMessageProtoError } from '../textsecure/Errors'; import * as expirationTimer from '../util/expirationTimer'; import { getUserLanguages } from '../util/userLanguages'; import { getMessageSentTimestamp } from '../util/getMessageSentTimestamp'; +import { copyCdnFields } from '../util/attachments'; import type { ReactionType } from '../types/Reactions'; import type { ServiceIdString } from '../types/ServiceId'; @@ -2007,6 +2008,7 @@ export class MessageModel extends window.Backbone.Model { ): Promise { const { attachments } = quote; const firstAttachment = attachments ? attachments[0] : undefined; + const firstThumbnailCdnFields = copyCdnFields(firstAttachment?.thumbnail); if (messageHasPaymentEvent(originalMessage.attributes)) { // eslint-disable-next-line no-param-reassign @@ -2100,6 +2102,7 @@ export class MessageModel extends window.Backbone.Model { if (thumbnail && thumbnail.path) { firstAttachment.thumbnail = { + ...firstThumbnailCdnFields, ...thumbnail, copied: true, }; @@ -2113,6 +2116,7 @@ export class MessageModel extends window.Backbone.Model { if (image && image.path) { firstAttachment.thumbnail = { + ...firstThumbnailCdnFields, ...image, copied: true, }; @@ -2122,6 +2126,7 @@ export class MessageModel extends window.Backbone.Model { const sticker = originalMessage.get('sticker'); if (sticker && sticker.data && sticker.data.path) { firstAttachment.thumbnail = { + ...firstThumbnailCdnFields, ...sticker.data, copied: true, }; diff --git a/ts/textsecure/downloadAttachment.ts b/ts/textsecure/downloadAttachment.ts index dcfec3d2612e..4587d4b827bb 100644 --- a/ts/textsecure/downloadAttachment.ts +++ b/ts/textsecure/downloadAttachment.ts @@ -1,7 +1,7 @@ // Copyright 2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only -import { isNumber, omit } from 'lodash'; +import { isNumber } from 'lodash'; import { strictAssert } from '../util/assert'; import { dropNull } from '../util/dropNull'; @@ -58,7 +58,7 @@ export async function downloadAttachment( const data = getFirstBytes(paddedData, size); return { - ...omit(attachment, 'key'), + ...attachment, size, contentType: contentType diff --git a/ts/types/Attachment.ts b/ts/types/Attachment.ts index 53d38f132823..c95ae4546a22 100644 --- a/ts/types/Attachment.ts +++ b/ts/types/Attachment.ts @@ -72,6 +72,7 @@ export type AttachmentType = { cdnNumber?: number; cdnId?: string; cdnKey?: string; + key?: string; data?: Uint8Array; textAttachment?: TextAttachmentType; @@ -80,9 +81,6 @@ export type AttachmentType = { /** Legacy field, used long ago for migrating attachments to disk. */ schemaVersion?: number; - - /** Removed once we download the attachment */ - key?: string; }; export type UploadedAttachmentType = Proto.IAttachmentPointer & diff --git a/ts/util/attachments.ts b/ts/util/attachments.ts index 17236f778804..cb65fc6ea199 100644 --- a/ts/util/attachments.ts +++ b/ts/util/attachments.ts @@ -4,11 +4,16 @@ import { blobToArrayBuffer } from 'blob-util'; import { scaleImageToLevel } from './scaleImageToLevel'; -import type { AttachmentType } from '../types/Attachment'; +import { dropNull } from './dropNull'; +import type { + AttachmentType, + UploadedAttachmentType, +} from '../types/Attachment'; import { canBeTranscoded } from '../types/Attachment'; import type { LoggerType } from '../types/Logging'; import * as MIME from '../types/MIME'; import * as Errors from '../types/errors'; +import * as Bytes from '../Bytes'; // Upgrade steps // NOTE: This step strips all EXIF metadata from JPEG images as @@ -74,3 +79,23 @@ export async function autoOrientJPEG( return attachment; } } + +export type CdnFieldsType = Pick< + AttachmentType, + 'cdnId' | 'cdnKey' | 'cdnNumber' | 'key' | 'digest' +>; + +export function copyCdnFields( + uploaded?: UploadedAttachmentType +): CdnFieldsType { + if (!uploaded) { + return {}; + } + return { + cdnId: dropNull(uploaded.cdnId)?.toString(), + cdnKey: uploaded.cdnKey, + cdnNumber: dropNull(uploaded.cdnNumber), + key: Bytes.toBase64(uploaded.key), + digest: Bytes.toBase64(uploaded.digest), + }; +}