fix: enhance CORS configuration for production with Nginx proxy

- Add enhanced CORS headers for Swagger UI compatibility
- Add OPTIONS method support for preflight requests
- Add additional middleware for CORS preflight handling
- Add debug endpoint /api/cors-test for CORS troubleshooting
- Improve Swagger UI configuration for production deployment
This commit is contained in:
Michilis
2025-07-15 21:56:55 +00:00
parent 91259e98c6
commit bf1f368a24
2 changed files with 37 additions and 4 deletions

View File

@@ -17,21 +17,49 @@ const protocol = isProduction ? 'https' : 'http';
// Middleware // Middleware
app.use(express.json({ limit: '10mb' })); app.use(express.json({ limit: '10mb' }));
// Enhanced CORS configuration for Swagger UI
app.use(cors({ app.use(cors({
origin: process.env.ALLOWED_ORIGINS origin: process.env.ALLOWED_ORIGINS
? process.env.ALLOWED_ORIGINS.split(',').map(o => o.trim()) ? process.env.ALLOWED_ORIGINS.split(',').map(o => o.trim())
: [`${protocol}://${apiDomain}`], : [`${protocol}://${apiDomain}`],
methods: ['GET', 'POST'], methods: ['GET', 'POST', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization'] allowedHeaders: ['Content-Type', 'Authorization', 'Accept', 'Origin', 'X-Requested-With'],
credentials: true,
optionsSuccessStatus: 200
})); }));
// Additional middleware for Swagger UI preflight requests
app.use((req, res, next) => {
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Accept, Origin, X-Requested-With');
res.status(200).end();
return;
}
next();
});
// Debug endpoint to test CORS
app.get('/api/cors-test', (req, res) => {
res.json({
success: true,
message: 'CORS test successful',
timestamp: new Date().toISOString(),
origin: req.headers.origin,
host: req.headers.host
});
});
// Swagger Documentation // Swagger Documentation
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs, { app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpecs, {
customCss: '.swagger-ui .topbar { display: none }', customCss: '.swagger-ui .topbar { display: none }',
customSiteTitle: 'Cashu Redeem API Documentation', customSiteTitle: 'Cashu Redeem API Documentation',
swaggerOptions: { swaggerOptions: {
filter: true, filter: true,
showRequestHeaders: true showRequestHeaders: true,
tryItOutEnabled: true
} }
})); }));

View File

@@ -6,6 +6,11 @@ const apiDomain = process.env.API_DOMAIN || 'localhost:3000';
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
const protocol = isProduction ? 'https' : 'http'; const protocol = isProduction ? 'https' : 'http';
// For production behind Nginx, we need to ensure the URL doesn't include the internal port
const serverUrl = isProduction
? `${protocol}://${apiDomain}`
: `${protocol}://${apiDomain}`;
const options = { const options = {
definition: { definition: {
openapi: '3.0.0', openapi: '3.0.0',
@@ -24,7 +29,7 @@ const options = {
}, },
servers: [ servers: [
{ {
url: `${protocol}://${apiDomain}`, url: serverUrl,
description: isProduction ? 'Production server' : 'Development server' description: isProduction ? 'Production server' : 'Development server'
} }
], ],