// Copyright 2023 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import { isFunction, isTypedArray, isUndefined, omit } from 'lodash'; import type { AttachmentType } from '../../types/Attachment'; import type { LoggerType } from '../../types/Logging'; import { getPlaintextHashForInMemoryAttachment } from '../../AttachmentCrypto'; export async function migrateDataToFileSystem( attachment: AttachmentType, { writeNewAttachmentData, logger, }: { writeNewAttachmentData: (data: Uint8Array) => Promise; logger: LoggerType; } ): Promise { if (!isFunction(writeNewAttachmentData)) { throw new TypeError("'writeNewAttachmentData' must be a function"); } const { data } = attachment; const attachmentHasData = !isUndefined(data); const shouldSkipSchemaUpgrade = !attachmentHasData; if (shouldSkipSchemaUpgrade) { return attachment; } // This attachment was already broken by a roundtrip to the database - repair it now if (!isTypedArray(data)) { logger.warn( 'migrateDataToFileSystem: Attachment had non-array `data` field; deleting.' ); return omit({ ...attachment }, ['data']); } const plaintextHash = getPlaintextHashForInMemoryAttachment(data); const path = await writeNewAttachmentData(data); const attachmentWithoutData = omit({ ...attachment, path, plaintextHash }, [ 'data', ]); return attachmentWithoutData; }