Support for server-configurable maximum attachment size

This commit is contained in:
Scott Nonnenberg 2022-04-13 10:47:39 -07:00 committed by GitHub
parent 677548f3a3
commit 37c44fb631
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 38 deletions

View File

@ -26,6 +26,7 @@ export type ConfigKeyType =
| 'desktop.showUserBadges2' | 'desktop.showUserBadges2'
| 'desktop.stories' | 'desktop.stories'
| 'desktop.usernames' | 'desktop.usernames'
| 'global.attachments.maxBytes'
| 'global.calling.maxGroupCallRingSize' | 'global.calling.maxGroupCallRingSize'
| 'global.groupsv2.groupSizeHardLimit' | 'global.groupsv2.groupSizeHardLimit'
| 'global.groupsv2.maxGroupSize'; | 'global.groupsv2.maxGroupSize';

View File

@ -859,8 +859,7 @@ export async function startApp(): Promise<void> {
); );
} catch (error) { } catch (error) {
log.warn( log.warn(
'Failed to parse integer out of desktop.retryReceiptLifespan feature flag', 'Failed to parse integer out of desktop.retryReceiptLifespan feature flag'
error && error.stack ? error.stack : error
); );
} }

View File

@ -13,31 +13,6 @@ import { fakeAttachment } from '../../test-both/helpers/fakeAttachment';
import { DAY } from '../../util/durations'; import { DAY } from '../../util/durations';
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.AttachmentType = fakeAttachment({ const input: Attachment.AttachmentType = fakeAttachment({

View File

@ -15,6 +15,7 @@ import { blobToArrayBuffer } from 'blob-util';
import type { LoggerType } from './Logging'; import type { LoggerType } from './Logging';
import * as MIME from './MIME'; import * as MIME from './MIME';
import * as log from '../logging/log';
import { toLogFormat } from './errors'; import { toLogFormat } from './errors';
import { SignalService } from '../protobuf'; import { SignalService } from '../protobuf';
import { import {
@ -25,6 +26,8 @@ import type { LocalizerType } from './Util';
import { ThemeType } from './Util'; import { ThemeType } from './Util';
import * as GoogleChrome from '../util/GoogleChrome'; import * as GoogleChrome from '../util/GoogleChrome';
import { scaleImageToLevel } from '../util/scaleImageToLevel'; import { scaleImageToLevel } from '../util/scaleImageToLevel';
import { parseIntOrThrow } from '../util/parseIntOrThrow';
import { getValue } from '../RemoteConfig';
const MAX_WIDTH = 300; const MAX_WIDTH = 300;
const MAX_HEIGHT = MAX_WIDTH * 1.5; const MAX_HEIGHT = MAX_WIDTH * 1.5;
@ -992,14 +995,21 @@ export const getFileExtension = (
} }
}; };
export const getUploadSizeLimitKb = (contentType: MIME.MIMEType): number => { const MEBIBYTE = 1024 * 1024;
if (MIME.isGif(contentType)) { const DEFAULT_MAX = 100 * MEBIBYTE;
return 25000;
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 => { export const defaultBlurHash = (theme: ThemeType = ThemeType.light): string => {

View File

@ -2,14 +2,14 @@
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import type { AttachmentType } from '../types/Attachment'; import type { AttachmentType } from '../types/Attachment';
import { getUploadSizeLimitKb } from '../types/Attachment'; import { getMaximumAttachmentSize } from '../types/Attachment';
import { showToast } from './showToast'; import { showToast } from './showToast';
import { ToastFileSize } from '../components/ToastFileSize'; import { ToastFileSize } from '../components/ToastFileSize';
export function isAttachmentSizeOkay( export function isAttachmentSizeOkay(
attachment: Readonly<AttachmentType> attachment: Readonly<AttachmentType>
): boolean { ): boolean {
const limitKb = getUploadSizeLimitKb(attachment.contentType); const limitKb = getMaximumAttachmentSize();
// 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

View File

@ -8,6 +8,7 @@ import type {
AttachmentDraftType, AttachmentDraftType,
InMemoryAttachmentDraftType, InMemoryAttachmentDraftType,
} from '../types/Attachment'; } from '../types/Attachment';
import { getMaximumAttachmentSize } from '../types/Attachment';
import { AttachmentToastType } from '../types/AttachmentToastType'; import { AttachmentToastType } from '../types/AttachmentToastType';
import { fileToBytes } from './fileToBytes'; import { fileToBytes } from './fileToBytes';
import { handleImageAttachment } from './handleImageAttachment'; import { handleImageAttachment } from './handleImageAttachment';
@ -44,8 +45,7 @@ export function preProcessAttachment(
return; return;
} }
const MB = 1000 * 1024; if (file.size > getMaximumAttachmentSize()) {
if (file.size > 100 * MB) {
return AttachmentToastType.ToastFileSize; return AttachmentToastType.ToastFileSize;
} }