Add downloadPath to attachments after import to support resumable download
Co-authored-by: trevor-signal <131492920+trevor-signal@users.noreply.github.com>
This commit is contained in:
		
					parent
					
						
							
								ca0468ec27
							
						
					
				
			
			
				commit
				
					
						f0c2abc30c
					
				
			
		
					 3 changed files with 52 additions and 6 deletions
				
			
		| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
// SPDX-License-Identifier: AGPL-3.0-only
 | 
					// SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
import Long from 'long';
 | 
					import Long from 'long';
 | 
				
			||||||
import { BackupLevel } from '@signalapp/libsignal-client/zkgroup';
 | 
					import { BackupLevel } from '@signalapp/libsignal-client/zkgroup';
 | 
				
			||||||
 | 
					import { omit } from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {
 | 
					import {
 | 
				
			||||||
  APPLICATION_OCTET_STREAM,
 | 
					  APPLICATION_OCTET_STREAM,
 | 
				
			||||||
| 
						 | 
					@ -39,9 +40,12 @@ import { redactGenericText } from '../../../util/privacy';
 | 
				
			||||||
import { missingCaseError } from '../../../util/missingCaseError';
 | 
					import { missingCaseError } from '../../../util/missingCaseError';
 | 
				
			||||||
import { toLogFormat } from '../../../types/errors';
 | 
					import { toLogFormat } from '../../../types/errors';
 | 
				
			||||||
import { bytesToUuid } from '../../../util/uuidToBytes';
 | 
					import { bytesToUuid } from '../../../util/uuidToBytes';
 | 
				
			||||||
 | 
					import { createName } from '../../../util/attachmentPath';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function convertFilePointerToAttachment(
 | 
					export function convertFilePointerToAttachment(
 | 
				
			||||||
  filePointer: Backups.FilePointer
 | 
					  filePointer: Backups.FilePointer,
 | 
				
			||||||
 | 
					  // Only for testing
 | 
				
			||||||
 | 
					  { _createName: doCreateName = createName } = {}
 | 
				
			||||||
): AttachmentType {
 | 
					): AttachmentType {
 | 
				
			||||||
  const {
 | 
					  const {
 | 
				
			||||||
    contentType,
 | 
					    contentType,
 | 
				
			||||||
| 
						 | 
					@ -70,6 +74,7 @@ export function convertFilePointerToAttachment(
 | 
				
			||||||
      ? Bytes.toBase64(incrementalMac)
 | 
					      ? Bytes.toBase64(incrementalMac)
 | 
				
			||||||
      : undefined,
 | 
					      : undefined,
 | 
				
			||||||
    incrementalMacChunkSize: incrementalMacChunkSize ?? undefined,
 | 
					    incrementalMacChunkSize: incrementalMacChunkSize ?? undefined,
 | 
				
			||||||
 | 
					    downloadPath: doCreateName(),
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (attachmentLocator) {
 | 
					  if (attachmentLocator) {
 | 
				
			||||||
| 
						 | 
					@ -117,7 +122,7 @@ export function convertFilePointerToAttachment(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (invalidAttachmentLocator) {
 | 
					  if (invalidAttachmentLocator) {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      ...commonProps,
 | 
					      ...omit(commonProps, 'downloadPath'),
 | 
				
			||||||
      error: true,
 | 
					      error: true,
 | 
				
			||||||
      size: 0,
 | 
					      size: 0,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,8 @@ describe('convertFilePointerToAttachment', () => {
 | 
				
			||||||
          digest: Bytes.fromString('digest'),
 | 
					          digest: Bytes.fromString('digest'),
 | 
				
			||||||
          uploadTimestamp: Long.fromNumber(1970),
 | 
					          uploadTimestamp: Long.fromNumber(1970),
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
      })
 | 
					      }),
 | 
				
			||||||
 | 
					      { _createName: () => 'downloadPath' }
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepStrictEqual(result, {
 | 
					    assert.deepStrictEqual(result, {
 | 
				
			||||||
| 
						 | 
					@ -58,6 +59,7 @@ describe('convertFilePointerToAttachment', () => {
 | 
				
			||||||
      uploadTimestamp: 1970,
 | 
					      uploadTimestamp: 1970,
 | 
				
			||||||
      incrementalMac: Bytes.toBase64(Bytes.fromString('incrementalMac')),
 | 
					      incrementalMac: Bytes.toBase64(Bytes.fromString('incrementalMac')),
 | 
				
			||||||
      incrementalMacChunkSize: 1000,
 | 
					      incrementalMacChunkSize: 1000,
 | 
				
			||||||
 | 
					      downloadPath: 'downloadPath',
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,7 +83,8 @@ describe('convertFilePointerToAttachment', () => {
 | 
				
			||||||
          transitCdnKey: 'transitCdnKey',
 | 
					          transitCdnKey: 'transitCdnKey',
 | 
				
			||||||
          transitCdnNumber: 2,
 | 
					          transitCdnNumber: 2,
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
      })
 | 
					      }),
 | 
				
			||||||
 | 
					      { _createName: () => 'downloadPath' }
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepStrictEqual(result, {
 | 
					    assert.deepStrictEqual(result, {
 | 
				
			||||||
| 
						 | 
					@ -102,6 +105,7 @@ describe('convertFilePointerToAttachment', () => {
 | 
				
			||||||
        mediaName: 'mediaName',
 | 
					        mediaName: 'mediaName',
 | 
				
			||||||
        cdnNumber: 3,
 | 
					        cdnNumber: 3,
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      downloadPath: 'downloadPath',
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,12 +143,14 @@ describe('convertFilePointerToAttachment', () => {
 | 
				
			||||||
    const result = convertFilePointerToAttachment(
 | 
					    const result = convertFilePointerToAttachment(
 | 
				
			||||||
      new Backups.FilePointer({
 | 
					      new Backups.FilePointer({
 | 
				
			||||||
        backupLocator: new Backups.FilePointer.BackupLocator(),
 | 
					        backupLocator: new Backups.FilePointer.BackupLocator(),
 | 
				
			||||||
      })
 | 
					      }),
 | 
				
			||||||
 | 
					      { _createName: () => 'downloadPath' }
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert.deepStrictEqual(result, {
 | 
					    assert.deepStrictEqual(result, {
 | 
				
			||||||
      contentType: APPLICATION_OCTET_STREAM,
 | 
					      contentType: APPLICATION_OCTET_STREAM,
 | 
				
			||||||
      size: 0,
 | 
					      size: 0,
 | 
				
			||||||
 | 
					      downloadPath: 'downloadPath',
 | 
				
			||||||
      width: undefined,
 | 
					      width: undefined,
 | 
				
			||||||
      height: undefined,
 | 
					      height: undefined,
 | 
				
			||||||
      blurHash: undefined,
 | 
					      blurHash: undefined,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,7 @@
 | 
				
			||||||
import { assert } from 'chai';
 | 
					import { assert } from 'chai';
 | 
				
			||||||
import path from 'path';
 | 
					import path from 'path';
 | 
				
			||||||
import { tmpdir } from 'os';
 | 
					import { tmpdir } from 'os';
 | 
				
			||||||
import { sortBy } from 'lodash';
 | 
					import { omit, sortBy } from 'lodash';
 | 
				
			||||||
import { createReadStream } from 'fs';
 | 
					import { createReadStream } from 'fs';
 | 
				
			||||||
import { mkdtemp, rm } from 'fs/promises';
 | 
					import { mkdtemp, rm } from 'fs/promises';
 | 
				
			||||||
import * as sinon from 'sinon';
 | 
					import * as sinon from 'sinon';
 | 
				
			||||||
| 
						 | 
					@ -65,6 +65,11 @@ function sortAndNormalize(
 | 
				
			||||||
      reactions,
 | 
					      reactions,
 | 
				
			||||||
      sendStateByConversationId,
 | 
					      sendStateByConversationId,
 | 
				
			||||||
      verifiedChanged,
 | 
					      verifiedChanged,
 | 
				
			||||||
 | 
					      attachments,
 | 
				
			||||||
 | 
					      preview,
 | 
				
			||||||
 | 
					      contact,
 | 
				
			||||||
 | 
					      quote,
 | 
				
			||||||
 | 
					      sticker,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // This is not in the backup
 | 
					      // This is not in the backup
 | 
				
			||||||
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | 
					      // 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
 | 
					        // Not an original property, but useful
 | 
				
			||||||
        isUnsupported: isUnsupportedMessage(message),
 | 
					        isUnsupported: isUnsupportedMessage(message),
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue