fix(settings): refresh upload limits and default to 4 GB

Share the saved upload limit with validation so changes apply without a page reload.
Seed new installations with a 4096 MB limit while preserving existing values.

Fixes #1733
This commit is contained in:
neon
2026-10-10 17:30:22 +00:00
parent 3c6dd48b5b
commit e6c0275fdf
6 changed files with 127 additions and 7 deletions
@@ -1,4 +1,4 @@
export const DEFAULT_MAX_UPLOAD_SIZE_MB = 500;
export const DEFAULT_MAX_UPLOAD_SIZE_MB = 4_096;
export const HARD_MAX_UPLOAD_SIZE_MB = 4_096;
export const HARD_MAX_UPLOAD_BYTES = HARD_MAX_UPLOAD_SIZE_MB * 1_024 * 1_024;
export const UPLOAD_CHUNK_SIZE_BYTES = 16 * 1_024 * 1_024;
@@ -620,9 +620,9 @@ describe('AppSettingsService', () => {
});
describe('getMaxUploadSizeMb', () => {
it('returns 500 by default when setting is absent', async () => {
it('returns 4096 by default when setting is absent', async () => {
repo.findByKey.mockResolvedValue(undefined);
expect(await service.getMaxUploadSizeMb()).toBe(500);
expect(await service.getMaxUploadSizeMb()).toBe(4096);
});
it('returns parsed integer value when valid', async () => {
@@ -630,10 +630,15 @@ describe('AppSettingsService', () => {
expect(await service.getMaxUploadSizeMb()).toBe(1024);
});
it('returns 500 when value is invalid or <= 0', async () => {
repo.findByKey.mockResolvedValue({ key: 'max_upload_size_mb', value: '-50' } as never);
it('preserves an existing 500 MB limit', async () => {
repo.findByKey.mockResolvedValue({ key: 'max_upload_size_mb', value: '500' } as never);
expect(await service.getMaxUploadSizeMb()).toBe(500);
});
it('returns 4096 when value is invalid or <= 0', async () => {
repo.findByKey.mockResolvedValue({ key: 'max_upload_size_mb', value: '-50' } as never);
expect(await service.getMaxUploadSizeMb()).toBe(4096);
});
});
describe('update max_upload_size_mb validation', () => {
@@ -52,6 +52,7 @@ describe('SeedService', () => {
expect(insertedRows).toContainEqual({ key: APP_SETTING_KEYS.ALLOW_REGISTRATION, value: 'false' });
expect(insertedRows).toContainEqual({ key: APP_SETTING_KEYS.OPDS_ENABLED, value: 'true' });
expect(insertedRows).toContainEqual({ key: APP_SETTING_KEYS.CROSS_PLATFORM_PATH_SANITIZATION_ENABLED, value: 'true' });
expect(insertedRows).toContainEqual({ key: APP_SETTING_KEYS.MAX_UPLOAD_SIZE_MB, value: '4096' });
const oidcRow = insertedRows.find((row) => row.key === APP_SETTING_KEYS.OIDC_CONFIG);
expect(oidcRow).toBeDefined();
+2 -1
View File
@@ -8,6 +8,7 @@ import {
DEFAULT_AUTHOR_ENRICHMENT_CONFIG,
DEFAULT_OIDC_CONFIG,
} from '../../common/constants/app-settings.constants';
import { DEFAULT_MAX_UPLOAD_SIZE_MB } from '../../common/constants/upload.constants';
import { DB } from '../../db';
import * as schema from '../../db/schema';
import { getSanitizedErrorInfo } from './seed-log.util';
@@ -41,7 +42,7 @@ const DEFAULT_APP_SETTINGS: Array<typeof schema.appSettings.$inferInsert> = [
{ key: APP_SETTING_KEYS.OIDC_CONFIG, value: JSON.stringify(DEFAULT_OIDC_CONFIG) },
{ key: APP_SETTING_KEYS.UPDATE_CHECK_ENABLED, value: 'true' },
{ key: APP_SETTING_KEYS.CROSS_PLATFORM_PATH_SANITIZATION_ENABLED, value: 'true' },
{ key: APP_SETTING_KEYS.MAX_UPLOAD_SIZE_MB, value: '500' },
{ key: APP_SETTING_KEYS.MAX_UPLOAD_SIZE_MB, value: String(DEFAULT_MAX_UPLOAD_SIZE_MB) },
];
@Injectable()