Allow PSD uploads over 6MB
You can't currently upload PSD files over 6MB. This is because its mimetype is `image/vnd.adobe.photoshop`. We think this is an image, and non-GIF images have a limit of 6MB. To fix this, we could do one of two things: 1. Add a special case for PSD files 2. Increase the size limit for unsupported image types such as this I went with the second option. Tested this by: - adding automated tests - uploading a ~9 MB PSD file - uploading a ~1 MB PNG - uploading a ~27 MB PNG (which worked because it's converted to a smaller JPEG) - uploading a ~50 MB text file - trying to upload a ~500 MB text file (which failed, as expected) Addresses [DESKTOP-1168][]. [DESKTOP-1168]: https://signalmessenger.atlassian.net/browse/DESKTOP-1168
This commit is contained in:
		
					parent
					
						
							
								92e5ccd764
							
						
					
				
			
			
				commit
				
					
						4519aa4abf
					
				
			
		
					 7 changed files with 64 additions and 25 deletions
				
			
		| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
// Copyright 2018-2020 Signal Messenger, LLC
 | 
					// Copyright 2018-2021 Signal Messenger, LLC
 | 
				
			||||||
// SPDX-License-Identifier: AGPL-3.0-only
 | 
					// SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const is = require('@sindresorhus/is');
 | 
					const is = require('@sindresorhus/is');
 | 
				
			||||||
| 
						 | 
					@ -217,6 +217,7 @@ exports.isImage = AttachmentTS.isImage;
 | 
				
			||||||
exports.isVideo = AttachmentTS.isVideo;
 | 
					exports.isVideo = AttachmentTS.isVideo;
 | 
				
			||||||
exports.isAudio = AttachmentTS.isAudio;
 | 
					exports.isAudio = AttachmentTS.isAudio;
 | 
				
			||||||
exports.isVoiceMessage = AttachmentTS.isVoiceMessage;
 | 
					exports.isVoiceMessage = AttachmentTS.isVoiceMessage;
 | 
				
			||||||
 | 
					exports.getUploadSizeLimitKb = AttachmentTS.getUploadSizeLimitKb;
 | 
				
			||||||
exports.save = AttachmentTS.save;
 | 
					exports.save = AttachmentTS.save;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const THUMBNAIL_SIZE = 150;
 | 
					const THUMBNAIL_SIZE = 150;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
// Copyright 2018-2020 Signal Messenger, LLC
 | 
					// Copyright 2018-2021 Signal Messenger, LLC
 | 
				
			||||||
// SPDX-License-Identifier: AGPL-3.0-only
 | 
					// SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { assert } from 'chai';
 | 
					import { assert } from 'chai';
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,31 @@ import { SignalService } from '../../protobuf';
 | 
				
			||||||
import { stringToArrayBuffer } from '../../../js/modules/string_to_array_buffer';
 | 
					import { stringToArrayBuffer } from '../../../js/modules/string_to_array_buffer';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('Attachment', () => {
 | 
					describe('Attachment', () => {
 | 
				
			||||||
 | 
					  describe('getUploadSizeLimitKb', () => {
 | 
				
			||||||
 | 
					    const { getUploadSizeLimitKb } = Attachment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('returns 6000 kilobytes for supported non-GIF images', () => {
 | 
				
			||||||
 | 
					      assert.strictEqual(getUploadSizeLimitKb(MIME.IMAGE_JPEG), 6000);
 | 
				
			||||||
 | 
					      assert.strictEqual(getUploadSizeLimitKb(MIME.IMAGE_PNG), 6000);
 | 
				
			||||||
 | 
					      assert.strictEqual(getUploadSizeLimitKb(MIME.IMAGE_WEBP), 6000);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('returns 25000 kilobytes for GIFs', () => {
 | 
				
			||||||
 | 
					      assert.strictEqual(getUploadSizeLimitKb(MIME.IMAGE_GIF), 25000);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('returns 100000 for other file types', () => {
 | 
				
			||||||
 | 
					      assert.strictEqual(getUploadSizeLimitKb(MIME.APPLICATION_JSON), 100000);
 | 
				
			||||||
 | 
					      assert.strictEqual(getUploadSizeLimitKb(MIME.AUDIO_AAC), 100000);
 | 
				
			||||||
 | 
					      assert.strictEqual(getUploadSizeLimitKb(MIME.AUDIO_MP3), 100000);
 | 
				
			||||||
 | 
					      assert.strictEqual(getUploadSizeLimitKb(MIME.VIDEO_MP4), 100000);
 | 
				
			||||||
 | 
					      assert.strictEqual(
 | 
				
			||||||
 | 
					        getUploadSizeLimitKb('image/vnd.adobe.photoshop' as MIME.MIMEType),
 | 
				
			||||||
 | 
					        100000
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  describe('getFileExtension', () => {
 | 
					  describe('getFileExtension', () => {
 | 
				
			||||||
    it('should return file extension from content type', () => {
 | 
					    it('should return file extension from content type', () => {
 | 
				
			||||||
      const input: Attachment.Attachment = {
 | 
					      const input: Attachment.Attachment = {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										19
									
								
								ts/test-node/types/MIME_test.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								ts/test-node/types/MIME_test.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					// Copyright 2021 Signal Messenger, LLC
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { assert } from 'chai';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import * as MIME from '../../types/MIME';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('MIME', () => {
 | 
				
			||||||
 | 
					  describe('isGif', () => {
 | 
				
			||||||
 | 
					    it('returns true for GIFs', () => {
 | 
				
			||||||
 | 
					      assert.isTrue(MIME.isGif('image/gif'));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('returns false for non-GIFs', () => {
 | 
				
			||||||
 | 
					      assert.isFalse(MIME.isGif('image/jpeg'));
 | 
				
			||||||
 | 
					      assert.isFalse(MIME.isGif('text/plain'));
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -431,3 +431,13 @@ export const getFileExtension = (
 | 
				
			||||||
      return attachment.contentType.split('/')[1];
 | 
					      return attachment.contentType.split('/')[1];
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const getUploadSizeLimitKb = (contentType: MIME.MIMEType): number => {
 | 
				
			||||||
 | 
					  if (MIME.isGif(contentType)) {
 | 
				
			||||||
 | 
					    return 25000;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (isImageTypeSupported(contentType)) {
 | 
				
			||||||
 | 
					    return 6000;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return 100000;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,8 @@ export const VIDEO_MP4 = 'video/mp4' as MIMEType;
 | 
				
			||||||
export const VIDEO_QUICKTIME = 'video/quicktime' as MIMEType;
 | 
					export const VIDEO_QUICKTIME = 'video/quicktime' as MIMEType;
 | 
				
			||||||
export const LONG_MESSAGE = 'text/x-signal-plain' as MIMEType;
 | 
					export const LONG_MESSAGE = 'text/x-signal-plain' as MIMEType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const isGif = (value: string): value is MIMEType =>
 | 
				
			||||||
 | 
					  value === 'image/gif';
 | 
				
			||||||
export const isJPEG = (value: string): value is MIMEType =>
 | 
					export const isJPEG = (value: string): value is MIMEType =>
 | 
				
			||||||
  value === 'image/jpeg';
 | 
					  value === 'image/jpeg';
 | 
				
			||||||
export const isImage = (value: string): value is MIMEType =>
 | 
					export const isImage = (value: string): value is MIMEType =>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1695,29 +1695,9 @@ Whisper.ConversationView = Whisper.View.extend({
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  isSizeOkay(attachment: any) {
 | 
					  isSizeOkay(attachment: any) {
 | 
				
			||||||
    let limitKb = 1000000;
 | 
					    const limitKb = window.Signal.Types.Attachment.getUploadSizeLimitKb(
 | 
				
			||||||
    const type =
 | 
					      attachment.contentType
 | 
				
			||||||
      attachment.contentType === 'image/gif'
 | 
					    );
 | 
				
			||||||
        ? 'gif'
 | 
					 | 
				
			||||||
        : attachment.contentType.split('/')[0];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    switch (type) {
 | 
					 | 
				
			||||||
      case 'image':
 | 
					 | 
				
			||||||
        limitKb = 6000;
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case 'gif':
 | 
					 | 
				
			||||||
        limitKb = 25000;
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case 'audio':
 | 
					 | 
				
			||||||
        limitKb = 100000;
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      case 'video':
 | 
					 | 
				
			||||||
        limitKb = 100000;
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
      default:
 | 
					 | 
				
			||||||
        limitKb = 100000;
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    // this needs to be cast properly
 | 
					    // this needs to be cast properly
 | 
				
			||||||
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 | 
					    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
 | 
				
			||||||
    // @ts-ignore
 | 
					    // @ts-ignore
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								ts/window.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								ts/window.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -358,6 +358,8 @@ declare global {
 | 
				
			||||||
          isImage: typeof Attachment.isImage;
 | 
					          isImage: typeof Attachment.isImage;
 | 
				
			||||||
          isVideo: typeof Attachment.isVideo;
 | 
					          isVideo: typeof Attachment.isVideo;
 | 
				
			||||||
          isAudio: typeof Attachment.isAudio;
 | 
					          isAudio: typeof Attachment.isAudio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          getUploadSizeLimitKb: typeof Attachment.getUploadSizeLimitKb;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        MIME: typeof MIME;
 | 
					        MIME: typeof MIME;
 | 
				
			||||||
        Contact: typeof Contact;
 | 
					        Contact: typeof Contact;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue