From f0c2abc30c7ec20ff0b9b306df9f1f2b7047dbb1 Mon Sep 17 00:00:00 2001 From: automated-signal <37887102+automated-signal@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:59:44 -0500 Subject: [PATCH] Add downloadPath to attachments after import to support resumable download Co-authored-by: trevor-signal <131492920+trevor-signal@users.noreply.github.com> --- ts/services/backups/util/filePointers.ts | 9 +++-- ts/test-electron/backup/filePointer_test.ts | 12 +++++-- ts/test-electron/backup/helpers.ts | 37 ++++++++++++++++++++- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/ts/services/backups/util/filePointers.ts b/ts/services/backups/util/filePointers.ts index a85787779117..1ce305b2cc55 100644 --- a/ts/services/backups/util/filePointers.ts +++ b/ts/services/backups/util/filePointers.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: AGPL-3.0-only import Long from 'long'; import { BackupLevel } from '@signalapp/libsignal-client/zkgroup'; +import { omit } from 'lodash'; import { APPLICATION_OCTET_STREAM, @@ -39,9 +40,12 @@ import { redactGenericText } from '../../../util/privacy'; import { missingCaseError } from '../../../util/missingCaseError'; import { toLogFormat } from '../../../types/errors'; import { bytesToUuid } from '../../../util/uuidToBytes'; +import { createName } from '../../../util/attachmentPath'; export function convertFilePointerToAttachment( - filePointer: Backups.FilePointer + filePointer: Backups.FilePointer, + // Only for testing + { _createName: doCreateName = createName } = {} ): AttachmentType { const { contentType, @@ -70,6 +74,7 @@ export function convertFilePointerToAttachment( ? Bytes.toBase64(incrementalMac) : undefined, incrementalMacChunkSize: incrementalMacChunkSize ?? undefined, + downloadPath: doCreateName(), }; if (attachmentLocator) { @@ -117,7 +122,7 @@ export function convertFilePointerToAttachment( if (invalidAttachmentLocator) { return { - ...commonProps, + ...omit(commonProps, 'downloadPath'), error: true, size: 0, }; diff --git a/ts/test-electron/backup/filePointer_test.ts b/ts/test-electron/backup/filePointer_test.ts index 2e8d8c8a7b3a..849057245498 100644 --- a/ts/test-electron/backup/filePointer_test.ts +++ b/ts/test-electron/backup/filePointer_test.ts @@ -40,7 +40,8 @@ describe('convertFilePointerToAttachment', () => { digest: Bytes.fromString('digest'), uploadTimestamp: Long.fromNumber(1970), }), - }) + }), + { _createName: () => 'downloadPath' } ); assert.deepStrictEqual(result, { @@ -58,6 +59,7 @@ describe('convertFilePointerToAttachment', () => { uploadTimestamp: 1970, incrementalMac: Bytes.toBase64(Bytes.fromString('incrementalMac')), incrementalMacChunkSize: 1000, + downloadPath: 'downloadPath', }); }); @@ -81,7 +83,8 @@ describe('convertFilePointerToAttachment', () => { transitCdnKey: 'transitCdnKey', transitCdnNumber: 2, }), - }) + }), + { _createName: () => 'downloadPath' } ); assert.deepStrictEqual(result, { @@ -102,6 +105,7 @@ describe('convertFilePointerToAttachment', () => { mediaName: 'mediaName', cdnNumber: 3, }, + downloadPath: 'downloadPath', }); }); @@ -139,12 +143,14 @@ describe('convertFilePointerToAttachment', () => { const result = convertFilePointerToAttachment( new Backups.FilePointer({ backupLocator: new Backups.FilePointer.BackupLocator(), - }) + }), + { _createName: () => 'downloadPath' } ); assert.deepStrictEqual(result, { contentType: APPLICATION_OCTET_STREAM, size: 0, + downloadPath: 'downloadPath', width: undefined, height: undefined, blurHash: undefined, diff --git a/ts/test-electron/backup/helpers.ts b/ts/test-electron/backup/helpers.ts index a791e931c1a3..f578ed21f945 100644 --- a/ts/test-electron/backup/helpers.ts +++ b/ts/test-electron/backup/helpers.ts @@ -4,7 +4,7 @@ import { assert } from 'chai'; import path from 'path'; import { tmpdir } from 'os'; -import { sortBy } from 'lodash'; +import { omit, sortBy } from 'lodash'; import { createReadStream } from 'fs'; import { mkdtemp, rm } from 'fs/promises'; import * as sinon from 'sinon'; @@ -65,6 +65,11 @@ function sortAndNormalize( reactions, sendStateByConversationId, verifiedChanged, + attachments, + preview, + contact, + quote, + sticker, // This is not in the backup // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -122,6 +127,36 @@ function sortAndNormalize( }; }), + attachments: attachments?.map(attachment => + omit(attachment, 'downloadPath') + ), + preview: preview?.map(previewItem => ({ + ...previewItem, + image: omit(previewItem.image, 'downloadPath'), + })), + contact: contact?.map(contactItem => ({ + ...contactItem, + avatar: { + ...contactItem.avatar, + avatar: omit(contactItem.avatar?.avatar, 'downloadPath'), + }, + })), + quote: quote + ? { + ...quote, + attachments: quote?.attachments.map(quotedAttachment => ({ + ...quotedAttachment, + thumbnail: omit(quotedAttachment.thumbnail, 'downloadPath'), + })), + } + : undefined, + sticker: sticker + ? { + ...sticker, + data: omit(sticker.data, 'downloadPath'), + } + : undefined, + // Not an original property, but useful isUnsupported: isUnsupportedMessage(message), })