Restructure upload validation env and colocate config types.
Move app config shapes under types/config, replace batch upload env vars with per-image bytes and JSON body padding, and extend IsBase64 for decoded limits.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { AppConfig } from '../types/AppConfig';
|
||||
import { AltchaConfig } from '../types/AltchaConfig';
|
||||
import { PostgresConfig } from '../types/PostgresConfig';
|
||||
import { AltchaConfig } from '../types/config/AltchaConfig';
|
||||
import { AppConfig } from '../types/config/AppConfig';
|
||||
import { NodeEnv } from '../types/NodeEnv';
|
||||
import { PostgresConfig } from '../types/config/PostgresConfig';
|
||||
|
||||
const env = (key: string): string => process.env[key] || '';
|
||||
|
||||
@@ -28,12 +28,19 @@ export const getAltchaConfig = (): AltchaConfig => {
|
||||
return {
|
||||
enabled: isEnabled('ALTCHA_ENABLED'),
|
||||
hmacKey: env('ALTCHA_HMAC_KEY'),
|
||||
maxNumber: envInt('ALTCHA_MAX_NUMBER')
|
||||
maxNumber: envInt('ALTCHA_MAX_NUMBER'),
|
||||
challengeTtlMs: envInt('ALTCHA_CHALLENGE_TTL_MS')
|
||||
};
|
||||
};
|
||||
|
||||
export const getAppConfig = (): AppConfig => {
|
||||
const aesGcmCiphertextOverheadBytes = 16;
|
||||
const jsonBase64ByteRatioNumerator = 4;
|
||||
const jsonBase64ByteRatioDenominator = 3;
|
||||
|
||||
const rawOrigins = env('CORS_ORIGINS');
|
||||
const maxImageBytes = envInt('VALIDATION_UPLOAD_MAX_IMAGE_BYTES');
|
||||
const jsonBodyPaddingBytes = envInt('VALIDATION_UPLOAD_JSON_BODY_PADDING_BYTES');
|
||||
|
||||
return {
|
||||
port: envInt('BACKEND_PORT'),
|
||||
@@ -51,8 +58,14 @@ export const getAppConfig = (): AppConfig => {
|
||||
limit: envInt('THROTTLE_UPLOAD_LIMIT')
|
||||
},
|
||||
validation: {
|
||||
maxImagesPerUpload: envInt('VALIDATION_UPLOAD_MAX_IMAGES_PER_UPLOAD'),
|
||||
uploadMaxViewsMax: envInt('VALIDATION_UPLOAD_MAX_VIEWS_MAX')
|
||||
upload: {
|
||||
maxViewsMax: envInt('VALIDATION_UPLOAD_MAX_VIEWS_MAX'),
|
||||
maxImageBytes,
|
||||
maxCiphertextBytes: maxImageBytes + aesGcmCiphertextOverheadBytes,
|
||||
maxRequestBodyBytes:
|
||||
Math.ceil((maxImageBytes * jsonBase64ByteRatioNumerator) / jsonBase64ByteRatioDenominator) +
|
||||
jsonBodyPaddingBytes
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -11,11 +11,12 @@ const validConfig = (overrides: Record<string, unknown> = {}): Record<string, un
|
||||
POSTGRES_PORT: 5432,
|
||||
POSTGRES_MIGRATIONS_RUN: 'false',
|
||||
CORS_ORIGINS: 'http://localhost:5173',
|
||||
VALIDATION_UPLOAD_MAX_IMAGES_PER_UPLOAD: 10,
|
||||
MULTER_MAX_FILE_BYTES: 10485760,
|
||||
VALIDATION_UPLOAD_MAX_IMAGE_BYTES: 10485760,
|
||||
VALIDATION_UPLOAD_JSON_BODY_PADDING_BYTES: 2_097_152,
|
||||
ALTCHA_ENABLED: 'true',
|
||||
ALTCHA_HMAC_KEY: 'secret',
|
||||
ALTCHA_MAX_NUMBER: 50000,
|
||||
ALTCHA_CHALLENGE_TTL_MS: 600_000,
|
||||
NEVER_MODE_INACTIVITY_DAYS: 365,
|
||||
THROTTLE_TTL_MS: 60000,
|
||||
THROTTLE_LIMIT: 1000,
|
||||
|
||||
@@ -45,12 +45,6 @@ class EnvironmentVariables {
|
||||
@IsString()
|
||||
CORS_ORIGINS: string;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
@Max(50 * 1024 * 1024)
|
||||
MULTER_MAX_FILE_BYTES: number;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsIn(BOOLEAN_STRING_VALUES)
|
||||
ALTCHA_ENABLED: BooleanStringValue;
|
||||
@@ -65,6 +59,12 @@ class EnvironmentVariables {
|
||||
@Max(1_000_000)
|
||||
ALTCHA_MAX_NUMBER: number;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@Min(60_000)
|
||||
@Max(3_600_000)
|
||||
ALTCHA_CHALLENGE_TTL_MS: number;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
@@ -98,14 +98,20 @@ class EnvironmentVariables {
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
@Max(100)
|
||||
VALIDATION_UPLOAD_MAX_IMAGES_PER_UPLOAD: number;
|
||||
@Max(10_000_000)
|
||||
VALIDATION_UPLOAD_MAX_VIEWS_MAX: number;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@Min(1)
|
||||
@Max(10_000_000)
|
||||
VALIDATION_UPLOAD_MAX_VIEWS_MAX: number;
|
||||
@Max(50 * 1024 * 1024) // 50MB
|
||||
VALIDATION_UPLOAD_MAX_IMAGE_BYTES: number;
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsNumber()
|
||||
@Min(256 * 1024) // 256KiB
|
||||
@Max(16 * 1024 * 1024) // 16MB
|
||||
VALIDATION_UPLOAD_JSON_BODY_PADDING_BYTES: number;
|
||||
}
|
||||
|
||||
export const validate = (config: Record<string, unknown>) => {
|
||||
|
||||
Reference in New Issue
Block a user