feat: add CORS security configuration#3
Conversation
- Replace hardcoded * with ALLOWED_ORIGINS env var - Support comma-separated origins list - Add origin validation callback - Include account-id and X-Request-ID headers - Set 24h preflight cache (maxAge) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
- Extract CORS logic into cors.config.ts utility - Add getCorsOrigins() for parsing ALLOWED_ORIGINS env var - Add createCorsOriginCallback() for origin validation - Add corsOptions constant with default CORS settings - Refactor main.ts to use extracted utilities - Add 23 tests covering: - Wildcard vs specific origins parsing - Origin callback with allowed/rejected origins - Mobile/curl requests (no origin) - Security edge cases (similar domains, protocol, ports) - CORS options validation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
WalkthroughIntroduces CORS configuration management for the NestJS backend by creating environment-driven utilities to parse allowed origins and validate incoming cross-origin requests, with comprehensive test coverage and integration into the main application setup. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20–25 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
apps/backend/src/main.ts (1)
36-39: Add trailing comma per ES5 convention.According to the coding guidelines, trailing commas should be present in multiline constructs.
Apply this diff:
app.enableCors({ origin: createCorsOriginCallback(allowedOrigins), - ...corsOptions, + ...corsOptions, });apps/backend/src/config/cors.config.ts (1)
22-46: Add explicit return type annotation.Per coding guidelines, public functions should have explicit return types. While the returned function's signature is clear, adding the return type improves type safety and documentation.
As per coding guidelines, consider adding an explicit return type:
-export function createCorsOriginCallback(allowedOrigins: CorsOrigins) { +export function createCorsOriginCallback( + allowedOrigins: CorsOrigins, +): (origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void) => void { return ( origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void,Alternatively, define a type alias for better readability:
type CorsOriginCallback = ( origin: string | undefined, callback: (err: Error | null, allow?: boolean) => void, ) => void; export function createCorsOriginCallback(allowedOrigins: CorsOrigins): CorsOriginCallback { // ... }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
apps/backend/.env.example(1 hunks)apps/backend/src/config/cors.config.spec.ts(1 hunks)apps/backend/src/config/cors.config.ts(1 hunks)apps/backend/src/main.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{js,ts,tsx,jsx,css,scss,json,yaml,yml,md}
📄 CodeRabbit inference engine (.cursor/rules/cursor.json)
**/*.{js,ts,tsx,jsx,css,scss,json,yaml,yml,md}: Maximum line length should not exceed 100 characters
Trim trailing whitespace from all lines
Insert a final newline at the end of every file
Files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
**/*.{js,ts,tsx,jsx,css,scss,json,yaml,yml}
📄 CodeRabbit inference engine (.cursor/rules/cursor.json)
Use 2-space indentation for all files
Files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
**/*
📄 CodeRabbit inference engine (.cursor/rules/cursor.json)
**/*: Use LF (line feed) as end-of-line character
Use UTF-8 character encoding for all files
Files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (.cursor/rules/cursor.json)
**/*.{ts,tsx,js,jsx}: Use single quotes for string literals in TypeScript/JavaScript
Semicolons must be present at the end of statements in TypeScript/JavaScript
Use trailing commas in multiline constructs following ES5 convention
Enable bracket spacing in object literals (e.g., { foo: bar } instead of {foo: bar})
Omit parentheses around single arrow function parameters when possible
Files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
**/*.{ts,tsx,js,jsx,vue}
📄 CodeRabbit inference engine (.cursor/rules/etus-methodology.mdc)
**/*.{ts,tsx,js,jsx,vue}: All UI component imports must use@/components/ui/*from @ETUS Design System, fail with error if components are imported from outside this path
Do not create components outside @ETUS Design System
Files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
apps/backend/src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/project-context.mdc)
All operations must include account context (accountId) for account isolation
Files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
apps/**/*.{vue,ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/project-context.mdc)
Implement comprehensive error handling scenarios in Vue components and backend services
Files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
**/*.{ts,tsx,d.ts}
📄 CodeRabbit inference engine (.cursor/rules/typescript.mdc)
**/*.{ts,tsx,d.ts}: Prefer interfaces over types for object definitions
Use type for unions, intersections, and mapped types
Avoid usingany, preferunknownfor unknown types
Leverage TypeScript's built-in utility types
Use generics for reusable type patterns
Use PascalCase for type names and interfaces
Use camelCase for variables and functions
Use UPPER_CASE for constants
Use descriptive names with auxiliary verbs for boolean variables and functions (e.g., isLoading, hasError)
Prefix React component prop interfaces with 'Props' (e.g., ButtonProps)
Keep type definitions close to where they're used
Export types and interfaces from dedicated type files when shared
Use explicit return types for public functions
Use arrow functions for callbacks and methods
Implement proper error handling with custom error types
Use function overloads for complex type scenarios
Prefer async/await over Promises
Use readonly for immutable properties
Leverage discriminated unions for type safety
Use type guards for runtime type checking
Implement proper null checking
Avoid type assertions unless necessary
Create custom error types for domain-specific errors
Use Result types for operations that can fail
Use try-catch blocks with typed catch clauses
Handle Promise rejections properly
Files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
apps/backend/src/**/*.spec.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Include unit tests for all backend services using Jest
Files:
apps/backend/src/config/cors.config.spec.ts
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
Repo: etusdigital/boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T18:13:02.946Z
Learning: Applies to apps/backend/src/**/*.spec.ts : Include unit tests for all backend services using Jest
📚 Learning: 2025-11-28T18:13:02.946Z
Learnt from: CR
Repo: etusdigital/boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T18:13:02.946Z
Learning: Applies to apps/backend/src/modules/**/*.controller.ts : Include API documentation with Swagger decorators on all controllers
Applied to files:
apps/backend/src/main.tsapps/backend/src/config/cors.config.ts
📚 Learning: 2025-11-28T18:13:02.946Z
Learnt from: CR
Repo: etusdigital/boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T18:13:02.946Z
Learning: Applies to apps/frontend-{vue,react}/src/**/api/**/*.ts : Maintain account isolation with all API calls including account-id header via interceptors
Applied to files:
apps/backend/src/main.ts
📚 Learning: 2025-11-28T18:13:02.946Z
Learnt from: CR
Repo: etusdigital/boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-28T18:13:02.946Z
Learning: Applies to apps/backend/src/**/*.spec.ts : Include unit tests for all backend services using Jest
Applied to files:
apps/backend/src/config/cors.config.tsapps/backend/src/config/cors.config.spec.ts
🧬 Code graph analysis (2)
apps/backend/src/main.ts (1)
apps/backend/src/config/cors.config.ts (3)
getCorsOrigins(13-17)createCorsOriginCallback(22-46)corsOptions(51-57)
apps/backend/src/config/cors.config.spec.ts (1)
apps/backend/src/config/cors.config.ts (4)
getCorsOrigins(13-17)createCorsOriginCallback(22-46)CorsOrigins(7-7)corsOptions(51-57)
🔇 Additional comments (4)
apps/backend/.env.example (1)
21-23: LGTM! Clear CORS configuration documentation.The environment variable documentation is clear and provides appropriate development examples. The comment accurately describes the wildcard and comma-separated behavior.
apps/backend/src/main.ts (1)
6-10: Excellent CORS integration with testable utilities.The refactoring from hardcoded CORS configuration to environment-driven dynamic validation is well-implemented. The separation of concerns makes the CORS logic testable and maintainable.
Also applies to: 34-39
apps/backend/src/config/cors.config.spec.ts (1)
1-193: Excellent comprehensive test coverage!The test suite thoroughly covers all CORS utilities with 22 test cases including critical security edge cases:
- Wildcard vs. specific origin lists
- No-origin requests (mobile/server-to-server)
- Security scenarios: subdomain attacks, protocol mismatches, port variations
- Environment variable handling and precedence
- Whitespace trimming
- Empty origin arrays
The tests verify the
account-idheader is properly included inallowedHeaders, aligning with the coding guideline for account isolation.Based on learnings, the comprehensive Jest test coverage aligns with project standards for backend services.
apps/backend/src/config/cors.config.ts (1)
1-57: Well-designed CORS security implementation!The implementation correctly handles critical CORS security scenarios:
- Exact string matching prevents subdomain and protocol-based attacks
- Properly allows no-origin requests for mobile apps and server-to-server communication
- Includes
account-idheader inallowedHeaders, maintaining account isolation per coding guidelines- Clear, testable separation of concerns
- Sensible defaults with 24-hour preflight caching
The use of a type (rather than interface) for the union
CorsOriginscorrectly follows the guideline to use types for unions.
Summary
Test plan
npm test -- --testPathPattern=cors.config.specto verify all tests pass🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.