From 96bd4fd01a0f85d16a553d6a57868ef64fc5afc0 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 02:30:19 +0000 Subject: [PATCH 1/2] fix: write X-Request-Id to responses and validate PORT/MAX_ATTACHMENT_BYTES Set X-Request-Id on every response so clients and log aggregators can correlate requests using the same ID that appears in server logs. Add range checks for PORT (1-65535) and MAX_ATTACHMENT_BYTES (>= 1) in loadConfig() so invalid values produce a clear startup error rather than a silent bind failure or a broken upload limit. Closes #17 Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01E2tdGyLhqTN2baMpaWDet3 --- src/app.ts | 6 ++++-- src/config.ts | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) 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..2dd4fef 100644 --- a/src/config.ts +++ b/src/config.ts @@ -35,8 +35,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(50 * 1024 * 1024)), + 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 +57,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, }; } From 41275bd6b98453499bf849e937e7d7800e397fcb Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 02:32:51 +0000 Subject: [PATCH 2/2] refactor: extract DEFAULT_MAX_ATTACHMENT_BYTES const to top of config Co-Authored-By: Claude Sonnet 4.6 Claude-Session: https://claude.ai/code/session_01E2tdGyLhqTN2baMpaWDet3 --- src/config.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/config.ts b/src/config.ts index 2dd4fef..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}`); @@ -41,7 +43,7 @@ export function loadConfig(): Config { } const maxAttachmentBytes = parseInt( - optional('MAX_ATTACHMENT_BYTES', String(50 * 1024 * 1024)), + optional('MAX_ATTACHMENT_BYTES', String(DEFAULT_MAX_ATTACHMENT_BYTES)), 10, ); if (isNaN(maxAttachmentBytes) || maxAttachmentBytes < 1) {