diff --git a/src/app.ts b/src/app.ts index 021b575..0c8336a 100644 --- a/src/app.ts +++ b/src/app.ts @@ -22,10 +22,12 @@ const JSON_BODY_LIMIT = 1 * 1024 * 1024; // 1 MB export function createApp(ctx: StackContext, config: Config, logger: Logger): Hono { const app = new Hono(); - // Assign a unique request ID to every request for log correlation. + // Assign a unique request ID to every request and expose it on the response. app.use(async (c, next) => { - c.set('requestId', crypto.randomUUID()); + const id = crypto.randomUUID(); + c.set('requestId', id); await next(); + c.header('X-Request-Id', id); }); app.use( diff --git a/src/config.ts b/src/config.ts index af47bd7..5a982a4 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,5 +1,7 @@ import { existsSync } from 'node:fs'; +const DEFAULT_MAX_ATTACHMENT_BYTES = 50 * 1024 * 1024; // 50 MB + function required(name: string): string { const val = process.env[name]; if (!val) throw new Error(`Missing required environment variable: ${name}`); @@ -35,8 +37,21 @@ export function loadConfig(): Config { ); } + const port = parseInt(optional('PORT', '3000'), 10); + if (isNaN(port) || port < 1 || port > 65535) { + throw new Error(`Invalid PORT: ${process.env['PORT']}`); + } + + const maxAttachmentBytes = parseInt( + optional('MAX_ATTACHMENT_BYTES', String(DEFAULT_MAX_ATTACHMENT_BYTES)), + 10, + ); + if (isNaN(maxAttachmentBytes) || maxAttachmentBytes < 1) { + throw new Error(`Invalid MAX_ATTACHMENT_BYTES: ${process.env['MAX_ATTACHMENT_BYTES']}`); + } + return { - port: parseInt(optional('PORT', '3000'), 10), + port, dbPath, entityId, timezone, @@ -44,6 +59,6 @@ export function loadConfig(): Config { corsOrigins: optional('CORS_ORIGINS', ''), baseUrl: process.env['BASE_URL'] ?? null, isNewDb, - maxAttachmentBytes: parseInt(optional('MAX_ATTACHMENT_BYTES', String(50 * 1024 * 1024)), 10), + maxAttachmentBytes, }; }