feat: allow configuring attachment upload limit (#12835)
## Summary - add a configurable MAXIMUM_FILE_UPLOAD_SIZE installation setting and surface it through super admin and global config payloads - apply the configurable limit to attachment validations and shared upload helpers on dashboard and widget - introduce a reusable helper with unit tests for parsing the limit and extend attachment specs for configurability ------ [Codex Task](https://chatgpt.com/codex/tasks/task_e_6912644786b08326bc8dee9401af6d0a) --------- Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Co-authored-by: iamsivin <iamsivin@gmail.com>
This commit is contained in:
@@ -34,9 +34,6 @@ export const CONVERSATION_PRIORITY_ORDER = {
|
||||
low: 1,
|
||||
};
|
||||
|
||||
// Size in mega bytes
|
||||
export const MAXIMUM_FILE_UPLOAD_SIZE = 40;
|
||||
|
||||
export const ALLOWED_FILE_TYPES =
|
||||
'image/*,' +
|
||||
'audio/*,' +
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
export const DEFAULT_MAXIMUM_FILE_UPLOAD_SIZE = 40;
|
||||
|
||||
export const formatBytes = (bytes, decimals = 2) => {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
|
||||
@@ -19,3 +21,13 @@ export const checkFileSizeLimit = (file, maximumUploadLimit) => {
|
||||
const fileSizeInMB = fileSizeInMegaBytes(fileSize);
|
||||
return fileSizeInMB <= maximumUploadLimit;
|
||||
};
|
||||
|
||||
export const resolveMaximumFileUploadSize = value => {
|
||||
const parsedValue = Number(value);
|
||||
|
||||
if (!Number.isFinite(parsedValue) || parsedValue <= 0) {
|
||||
return DEFAULT_MAXIMUM_FILE_UPLOAD_SIZE;
|
||||
}
|
||||
|
||||
return parsedValue;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import {
|
||||
DEFAULT_MAXIMUM_FILE_UPLOAD_SIZE,
|
||||
formatBytes,
|
||||
fileSizeInMegaBytes,
|
||||
checkFileSizeLimit,
|
||||
resolveMaximumFileUploadSize,
|
||||
} from '../FileHelper';
|
||||
|
||||
describe('#File Helpers', () => {
|
||||
@@ -19,6 +21,7 @@ describe('#File Helpers', () => {
|
||||
expect(formatBytes(10000000)).toBe('9.54 MB');
|
||||
});
|
||||
});
|
||||
|
||||
describe('fileSizeInMegaBytes', () => {
|
||||
it('should return zero if 0 is passed', () => {
|
||||
expect(fileSizeInMegaBytes(0)).toBe(0);
|
||||
@@ -27,6 +30,7 @@ describe('#File Helpers', () => {
|
||||
expect(fileSizeInMegaBytes(20000000)).toBeCloseTo(19.07, 2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkFileSizeLimit', () => {
|
||||
it('should return false if file with size 62208194 and file size limit 40 are passed', () => {
|
||||
expect(checkFileSizeLimit({ file: { size: 62208194 } }, 40)).toBe(false);
|
||||
@@ -35,4 +39,26 @@ describe('#File Helpers', () => {
|
||||
expect(checkFileSizeLimit({ file: { size: 199154 } }, 40)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('resolveMaximumFileUploadSize', () => {
|
||||
it('should return default when value is undefined', () => {
|
||||
expect(resolveMaximumFileUploadSize(undefined)).toBe(
|
||||
DEFAULT_MAXIMUM_FILE_UPLOAD_SIZE
|
||||
);
|
||||
});
|
||||
|
||||
it('should return default when value is not a positive number', () => {
|
||||
expect(resolveMaximumFileUploadSize('not-a-number')).toBe(
|
||||
DEFAULT_MAXIMUM_FILE_UPLOAD_SIZE
|
||||
);
|
||||
expect(resolveMaximumFileUploadSize(-5)).toBe(
|
||||
DEFAULT_MAXIMUM_FILE_UPLOAD_SIZE
|
||||
);
|
||||
});
|
||||
|
||||
it('should parse numeric strings and numbers', () => {
|
||||
expect(resolveMaximumFileUploadSize('50')).toBe(50);
|
||||
expect(resolveMaximumFileUploadSize(75)).toBe(75);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { parseBoolean } from '@chatwoot/utils';
|
||||
import { resolveMaximumFileUploadSize } from 'shared/helpers/FileHelper';
|
||||
|
||||
const {
|
||||
API_CHANNEL_NAME: apiChannelName,
|
||||
@@ -11,6 +12,7 @@ const {
|
||||
DIRECT_UPLOADS_ENABLED: directUploadsEnabled,
|
||||
DISPLAY_MANIFEST: displayManifest,
|
||||
GIT_SHA: gitSha,
|
||||
MAXIMUM_FILE_UPLOAD_SIZE: maximumFileUploadSize,
|
||||
HCAPTCHA_SITE_KEY: hCaptchaSiteKey,
|
||||
INSTALLATION_NAME: installationName,
|
||||
LOGO_THUMBNAIL: logoThumbnail,
|
||||
@@ -37,6 +39,7 @@ const state = {
|
||||
disableUserProfileUpdate: parseBoolean(disableUserProfileUpdate),
|
||||
displayManifest,
|
||||
gitSha,
|
||||
maximumFileUploadSize: resolveMaximumFileUploadSize(maximumFileUploadSize),
|
||||
hCaptchaSiteKey,
|
||||
installationName,
|
||||
logo,
|
||||
|
||||
Reference in New Issue
Block a user