From c2eb7513834eeb5adfa53fff897f585de87e4821 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Tue, 30 Dec 2025 22:08:47 +0900 Subject: feat(security): add rate limiting and CORS middleware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add rate limiting to login endpoint (5 requests/minute per IP) - Configure CORS middleware with environment-based origin control - Expose rate limit headers in CORS for client visibility - Update hono to 4.11.3 for rate limiter peer dependency 🤖 Generated with [Claude Code](https://claude.ai/claude-code) Co-Authored-By: Claude Opus 4.5 --- src/server/middleware/cors.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/server/middleware/cors.ts (limited to 'src/server/middleware/cors.ts') diff --git a/src/server/middleware/cors.ts b/src/server/middleware/cors.ts new file mode 100644 index 0000000..ce097ac --- /dev/null +++ b/src/server/middleware/cors.ts @@ -0,0 +1,42 @@ +import { cors } from "hono/cors"; + +/** + * CORS middleware configuration. + * Uses CORS_ORIGIN environment variable to configure allowed origins. + * If not set, defaults to same-origin only (no CORS headers). + * + * Examples: + * - CORS_ORIGIN=https://kioku.example.com (single origin) + * - CORS_ORIGIN=https://example.com,https://app.example.com (multiple origins) + */ +function getAllowedOrigins(): string[] { + const origins = process.env.CORS_ORIGIN; + if (!origins) { + return []; + } + return origins.split(",").map((o) => o.trim()); +} + +export function createCorsMiddleware() { + const allowedOrigins = getAllowedOrigins(); + + // If no origins configured, don't add CORS headers + if (allowedOrigins.length === 0) { + return cors({ + origin: () => "", + }); + } + + return cors({ + origin: allowedOrigins, + allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"], + allowHeaders: ["Content-Type", "Authorization"], + exposeHeaders: [ + "RateLimit-Limit", + "RateLimit-Remaining", + "RateLimit-Reset", + ], + maxAge: 86400, // 24 hours + credentials: true, + }); +} -- cgit v1.2.3-70-g09d2