diff --git a/ts/RemoteConfig.ts b/ts/RemoteConfig.ts index 910c43bb7..cec031fc3 100644 --- a/ts/RemoteConfig.ts +++ b/ts/RemoteConfig.ts @@ -26,6 +26,7 @@ export type ConfigKeyType = | 'desktop.showUserBadges2' | 'desktop.stories' | 'desktop.usernames' + | 'global.attachments.maxBytes' | 'global.calling.maxGroupCallRingSize' | 'global.groupsv2.groupSizeHardLimit' | 'global.groupsv2.maxGroupSize'; diff --git a/ts/background.ts b/ts/background.ts index 635208ca5..725275301 100644 --- a/ts/background.ts +++ b/ts/background.ts @@ -859,8 +859,7 @@ export async function startApp(): Promise { ); } catch (error) { log.warn( - 'Failed to parse integer out of desktop.retryReceiptLifespan feature flag', - error && error.stack ? error.stack : error + 'Failed to parse integer out of desktop.retryReceiptLifespan feature flag' ); } diff --git a/ts/test-node/types/Attachment_test.ts b/ts/test-node/types/Attachment_test.ts index 999b2e7af..005d0485a 100644 --- a/ts/test-node/types/Attachment_test.ts +++ b/ts/test-node/types/Attachment_test.ts @@ -13,31 +13,6 @@ import { fakeAttachment } from '../../test-both/helpers/fakeAttachment'; import { DAY } from '../../util/durations'; 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', () => { it('should return file extension from content type', () => { const input: Attachment.AttachmentType = fakeAttachment({ diff --git a/ts/types/Attachment.ts b/ts/types/Attachment.ts index 41e2bb2c4..8a5d001ee 100644 --- a/ts/types/Attachment.ts +++ b/ts/types/Attachment.ts @@ -15,6 +15,7 @@ import { blobToArrayBuffer } from 'blob-util'; import type { LoggerType } from './Logging'; import * as MIME from './MIME'; +import * as log from '../logging/log'; import { toLogFormat } from './errors'; import { SignalService } from '../protobuf'; import { @@ -25,6 +26,8 @@ import type { LocalizerType } from './Util'; import { ThemeType } from './Util'; import * as GoogleChrome from '../util/GoogleChrome'; import { scaleImageToLevel } from '../util/scaleImageToLevel'; +import { parseIntOrThrow } from '../util/parseIntOrThrow'; +import { getValue } from '../RemoteConfig'; const MAX_WIDTH = 300; const MAX_HEIGHT = MAX_WIDTH * 1.5; @@ -992,14 +995,21 @@ export const getFileExtension = ( } }; -export const getUploadSizeLimitKb = (contentType: MIME.MIMEType): number => { - if (MIME.isGif(contentType)) { - return 25000; +const MEBIBYTE = 1024 * 1024; +const DEFAULT_MAX = 100 * MEBIBYTE; + +export const getMaximumAttachmentSize = (): number => { + try { + return parseIntOrThrow( + getValue('global.attachments.maxBytes'), + 'preProcessAttachment/maxAttachmentSize' + ); + } catch (error) { + log.warn( + 'Failed to parse integer out of global.attachments.maxBytes feature flag' + ); + return DEFAULT_MAX; } - if (isImageTypeSupported(contentType)) { - return 6000; - } - return 100000; }; export const defaultBlurHash = (theme: ThemeType = ThemeType.light): string => { diff --git a/ts/util/isAttachmentSizeOkay.ts b/ts/util/isAttachmentSizeOkay.ts index cc3296401..e2cde5257 100644 --- a/ts/util/isAttachmentSizeOkay.ts +++ b/ts/util/isAttachmentSizeOkay.ts @@ -2,14 +2,14 @@ // SPDX-License-Identifier: AGPL-3.0-only import type { AttachmentType } from '../types/Attachment'; -import { getUploadSizeLimitKb } from '../types/Attachment'; +import { getMaximumAttachmentSize } from '../types/Attachment'; import { showToast } from './showToast'; import { ToastFileSize } from '../components/ToastFileSize'; export function isAttachmentSizeOkay( attachment: Readonly ): boolean { - const limitKb = getUploadSizeLimitKb(attachment.contentType); + const limitKb = getMaximumAttachmentSize(); // this needs to be cast properly // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore diff --git a/ts/util/processAttachment.ts b/ts/util/processAttachment.ts index b85a63b16..5b687222c 100644 --- a/ts/util/processAttachment.ts +++ b/ts/util/processAttachment.ts @@ -8,6 +8,7 @@ import type { AttachmentDraftType, InMemoryAttachmentDraftType, } from '../types/Attachment'; +import { getMaximumAttachmentSize } from '../types/Attachment'; import { AttachmentToastType } from '../types/AttachmentToastType'; import { fileToBytes } from './fileToBytes'; import { handleImageAttachment } from './handleImageAttachment'; @@ -44,8 +45,7 @@ export function preProcessAttachment( return; } - const MB = 1000 * 1024; - if (file.size > 100 * MB) { + if (file.size > getMaximumAttachmentSize()) { return AttachmentToastType.ToastFileSize; }