Skip to content

Commit a2719a0

Browse files
committed
fix(public-api): resolve CORS preflight credential drops and add OPTIONS caching: - Replaced global npm middleware with custom to prevent eager responses that intercepted and broke credentialed requests.
- Added to preflight responses, allowing the safe transmission of HTTP-only cookies (e.g., Refresh Tokens). - Implemented CORS preflight caching with (24h) to significantly reduce frontend network latency by avoiding redundant OPTIONS requests. - Removed unused package import.
1 parent abbde14 commit a2719a0

1 file changed

Lines changed: 18 additions & 19 deletions

File tree

apps/public-api/src/app.js

Lines changed: 18 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ if (process.env.NODE_ENV !== 'test') {
1010

1111
const express = require('express')
1212
const mongoose = require('mongoose')
13-
const cors = require('cors')
1413
const cookieParser = require('cookie-parser');
1514
const app = express();
1615
app.set('trust proxy', 1);
@@ -31,7 +30,19 @@ app.use('/api/mail/webhook', express.raw({ type: 'application/json' }));
3130
app.use(express.json());
3231
app.use(express.urlencoded({ extended: true }));
3332
app.use(standardizeApiResponse);
34-
app.use(cors());
33+
const projectCorsPreflight = (req, res, next) => {
34+
res.header("Access-Control-Allow-Origin", req.headers.origin || "*");
35+
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH");
36+
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, x-api-key");
37+
res.header("Access-Control-Allow-Credentials", "true");
38+
res.header("Access-Control-Max-Age", "86400"); // Cache preflight for 24 hours
39+
if (req.method === 'OPTIONS') {
40+
return res.status(200).end();
41+
}
42+
next();
43+
};
44+
45+
app.use(projectCorsPreflight);
3546
app.use(cookieParser());
3647

3748

@@ -61,23 +72,11 @@ const mailRoute = require('./routes/mail');
6172
const healthRoute = require('./routes/health');
6273

6374
// ROUTES SETUP
64-
const projectCorsPreflight = (req, res, next) => {
65-
res.header("Access-Control-Allow-Origin", req.headers.origin || "*");
66-
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH");
67-
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, x-api-key");
68-
res.header("Access-Control-Allow-Credentials", "true");
69-
if (req.method === 'OPTIONS') {
70-
return res.status(200).end();
71-
}
72-
next();
73-
};
74-
75-
app.use('/api/userAuth', projectCorsPreflight, limiter, logger, userAuthRoute);
76-
77-
app.use('/api/data', projectCorsPreflight, limiter, logger, dataRoute);
78-
app.use('/api/schemas', projectCorsPreflight, limiter, logger, schemaRoute);
79-
app.use('/api/storage', projectCorsPreflight, limiter, logger, storageRoute);
80-
app.use('/api/mail', projectCorsPreflight, limiter, logger, mailRoute);
75+
app.use('/api/userAuth', limiter, logger, userAuthRoute);
76+
app.use('/api/data', limiter, logger, dataRoute);
77+
app.use('/api/schemas', limiter, logger, schemaRoute);
78+
app.use('/api/storage', limiter, logger, storageRoute);
79+
app.use('/api/mail', limiter, logger, mailRoute);
8180
app.use('/api/health', limiter, logger, healthRoute);
8281

8382
app.get('/api/server-ip', async (req, res) => {

0 commit comments

Comments
 (0)