diff --git a/config/config.js b/config/config.js index 0aa5418..ef3e630 100644 --- a/config/config.js +++ b/config/config.js @@ -15,13 +15,17 @@ if (process.env.USE_SSL === 'true') { } } -// CORS Configuration +// CORS Configuration - Whitelisted domains that can access the API const allowedOrigins = [ - 'http://uniformnetwork.com', - 'http://localhost', 'https://crewsportswear.com', + 'https://www.crewsportswear.com', 'https://crewsportswear.app', - 'https://merchbay.com' + 'https://dev-crew.crewsportswear.app', + 'https://merchbay.com', + 'https://www.merchbay.com', + 'https://dev.merchbay.app', + 'http://localhost', + 'http://localhost:8080' ]; // Screenshot Configuration diff --git a/middleware/cors.js b/middleware/cors.js index 83ae599..3a3f859 100644 --- a/middleware/cors.js +++ b/middleware/cors.js @@ -1,17 +1,46 @@ const { allowedOrigins } = require('../config/config'); /** - * CORS middleware - * Handles Cross-Origin Resource Sharing for allowed domains + * CORS and Security middleware + * Only allows requests from whitelisted domains */ function corsMiddleware(req, res, next) { const origin = req.headers.origin; + const referer = req.headers.referer; - if (allowedOrigins.indexOf(origin) > -1) { + // Check if origin is allowed + const isOriginAllowed = origin && allowedOrigins.indexOf(origin) > -1; + + // Check if referer matches allowed domains + const isRefererAllowed = referer && allowedOrigins.some(allowed => { + try { + const refererHost = new URL(referer).origin; + return refererHost === allowed || referer.startsWith(allowed); + } catch (e) { + return false; + } + }); + + // Allow if origin OR referer is whitelisted + // Also allow health check endpoint without restrictions + if (req.path === '/health') { + return next(); + } + + if (!isOriginAllowed && !isRefererAllowed) { + console.warn(`Blocked request from Origin: ${origin || 'none'}, Referer: ${referer || 'none'}`); + return res.status(403).json({ + error: 'Forbidden', + message: 'Access denied. This API is restricted to authorized domains only.' + }); + } + + // Set CORS headers for allowed origin + if (isOriginAllowed) { res.setHeader('Access-Control-Allow-Origin', origin); } - res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); res.setHeader('Access-Control-Allow-Credentials', true);