Skip to content

Commit 38085b3

Browse files
committed
fix: protect main routes vs public routes
1 parent 0e7a85e commit 38085b3

1 file changed

Lines changed: 25 additions & 11 deletions

File tree

backend/app.js

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,7 @@ const { getPublicIp } = require('./utils/network');
1919
// Initialize Queue Workers
2020
require('./queues/emailQueue');
2121

22-
// Middleware
23-
app.use(cors());
22+
// Middleware (We apply admin options globally except where overridden via dynamic handling)
2423
app.use(express.json());
2524
app.use(express.urlencoded({ extended: true }));
2625

@@ -79,15 +78,30 @@ const schemaRoute = require('./routes/schemas');
7978
const releaseRoute = require('./routes/releases');
8079

8180
// ROUTES SETUP
82-
app.use('/api/auth/login', authLimiter); // Strict limiter on login
83-
app.use('/api/auth/register', authLimiter); // Strict limiter on register
84-
app.use('/api/auth', dashboardLimiter, authRoute); // Developer Auth (general)
85-
app.use('/api/projects', dashboardLimiter, projectRoute); // Project Mgmt
86-
app.use('/api/userAuth', limiter, logger, userAuthRoute);
87-
app.use('/api/data', limiter, cors(adminCorsOptions), logger, dataRoute);
88-
app.use('/api/schemas', limiter, cors(adminCorsOptions), logger, schemaRoute);
89-
app.use('/api/storage', limiter, cors(adminCorsOptions), logger, storageRoute);
90-
app.use('/api/releases', releaseRoute);
81+
app.use('/api/auth/login', cors(adminCorsOptions), authLimiter); // Strict limiter on login
82+
app.use('/api/auth/register', cors(adminCorsOptions), authLimiter); // Strict limiter on register
83+
app.use('/api/auth', cors(adminCorsOptions), dashboardLimiter, authRoute); // Developer Auth (general)
84+
app.use('/api/projects', cors(adminCorsOptions), dashboardLimiter, projectRoute); // Project Mgmt
85+
app.use('/api/userAuth', cors(adminCorsOptions), limiter, logger, userAuthRoute);
86+
app.use('/api/releases', cors(adminCorsOptions), releaseRoute);
87+
88+
// For project-specific routes, we handle CORS dynamically inside `verifyApiKey.js`
89+
// and a custom pre-flight middleware to allow varying allowedDomains.
90+
const projectCorsPreflight = (req, res, next) => {
91+
// Basic catch-all for OPTIONS requests so the browser doesn't get blocked
92+
// verifyApiKey handles the actual domain verification for GET/POST/PUT/DELETE
93+
res.header("Access-Control-Allow-Origin", req.headers.origin || "*");
94+
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, PATCH");
95+
res.header("Access-Control-Allow-Headers", "Content-Type, Authorization, x-api-key");
96+
if (req.method === 'OPTIONS') {
97+
return res.status(200).end();
98+
}
99+
next();
100+
};
101+
102+
app.use('/api/data', projectCorsPreflight, limiter, logger, dataRoute);
103+
app.use('/api/schemas', projectCorsPreflight, limiter, logger, schemaRoute);
104+
app.use('/api/storage', projectCorsPreflight, limiter, logger, storageRoute);
91105

92106
app.get('/api/server-ip', async (req, res) => {
93107
const ip = await getPublicIp();

0 commit comments

Comments
 (0)