Skip to content

Commit 3cf7652

Browse files
feat: add helmet, rate limiting and secure session configuration
1 parent 938d321 commit 3cf7652

1 file changed

Lines changed: 82 additions & 37 deletions

File tree

backend/server.js

Lines changed: 82 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,72 +13,117 @@ require('./config/passportConfig');
1313

1414
const app = express();
1515

16-
// CORS configuration (env-based whitelist)
17-
const rawAllowed = process.env.CLIENT_URL || process.env.ALLOWED_ORIGINS || 'http://localhost:5173';
18-
const allowedOrigins = rawAllowed.split(',').map(s => s.trim()).filter(Boolean);
19-
20-
app.use(cors({
21-
origin: function(origin, callback) {
22-
// allow requests with no origin (server-to-server, curl)
23-
if (!origin) return callback(null, true);
24-
if (allowedOrigins.indexOf(origin) !== -1) return callback(null, true);
25-
return callback(new Error('Not allowed by CORS'));
26-
},
27-
credentials: true,
28-
}));
16+
/* =========================
17+
Security Middleware
18+
========================= */
2919

20+
// Helmet security headers
3021
app.use(helmet());
3122

32-
// Rate limiting
23+
// Rate Limiter
3324
const limiter = rateLimit({
34-
windowMs: 15 * 60 * 1000, // 15 minutes
25+
windowMs: 15 * 60 * 1000, // 15 mins
3526
max: 100,
3627
message: 'Too many requests from this IP, please try again later.',
3728
standardHeaders: true,
3829
legacyHeaders: false,
3930
});
31+
4032
app.use('/api', limiter);
4133

42-
// Middleware
34+
/* =========================
35+
CORS Configuration
36+
========================= */
37+
38+
const rawAllowedOrigins =
39+
process.env.ALLOWED_ORIGINS ||
40+
process.env.CLIENT_URL ||
41+
'http://localhost:5173';
42+
43+
const allowedOrigins = rawAllowedOrigins
44+
.split(',')
45+
.map(origin => origin.trim());
46+
47+
app.use(cors({
48+
origin: (origin, callback) => {
49+
// Allow server-to-server requests
50+
if (!origin) {
51+
return callback(null, true);
52+
}
53+
54+
if (allowedOrigins.includes(origin)) {
55+
return callback(null, true);
56+
}
57+
58+
return callback(new Error('Not allowed by CORS'));
59+
},
60+
credentials: true,
61+
}));
62+
63+
/* =========================
64+
Body Parser
65+
========================= */
66+
4367
app.use(bodyParser.json());
44-
const sessionSecret = process.env.SESSION_SECRET || 'dev-secret';
45-
if (!process.env.SESSION_SECRET) {
46-
console.warn('Warning: SESSION_SECRET is not set. Using a fallback development secret. Set SESSION_SECRET in backend/.env for production.');
68+
69+
/* =========================
70+
Session Configuration
71+
========================= */
72+
73+
const sessionSecret = process.env.SESSION_SECRET;
74+
75+
if (!sessionSecret) {
76+
console.warn('⚠ SESSION_SECRET is missing in .env');
4777
}
78+
4879
app.use(session({
49-
secret: sessionSecret,
80+
secret: sessionSecret || 'dev-secret',
5081
resave: false,
5182
saveUninitialized: false,
5283
cookie: {
5384
httpOnly: true,
5485
secure: process.env.NODE_ENV === 'production',
5586
sameSite: 'lax',
56-
maxAge: 1000 * 60 * 60 * 24 // 1 day
57-
}
87+
maxAge: 1000 * 60 * 60 * 24, // 1 day
88+
},
5889
}));
90+
91+
/* =========================
92+
Passport Middleware
93+
========================= */
94+
5995
app.use(passport.initialize());
6096
app.use(passport.session());
6197

62-
// Routes
98+
/* =========================
99+
Routes
100+
========================= */
101+
63102
const authRoutes = require('./routes/auth');
103+
64104
app.use('/api/auth', authRoutes);
65105

66-
// Connect to MongoDB with sensible defaults and warnings
106+
/* =========================
107+
MongoDB Connection
108+
========================= */
109+
67110
const PORT = process.env.PORT || 5000;
68-
const MONGO_URI = process.env.MONGO_URI || 'mongodb://localhost:27017/githubTracker';
111+
const MONGO_URI =
112+
process.env.MONGO_URI ||
113+
'mongodb://127.0.0.1:27017/githubTracker';
69114

70115
if (!process.env.MONGO_URI) {
71-
console.warn('Warning: process.env.MONGO_URI is not set. Using local default:', MONGO_URI);
72-
}
73-
if (!process.env.SESSION_SECRET) {
74-
console.warn('Warning: process.env.SESSION_SECRET is not set. Using an insecure default for development.');
116+
console.warn('⚠ MONGO_URI missing in .env');
75117
}
76118

77-
mongoose.connect(MONGO_URI, {}).then(() => {
78-
console.log('Connected to MongoDB');
79-
app.listen(PORT, () => {
80-
console.log(`Server running on port ${PORT}`);
81-
});
82-
}).catch((err) => {
83-
console.log('MongoDB connection error:', err);
84-
});
119+
mongoose.connect(MONGO_URI)
120+
.then(() => {
121+
console.log('✅ Connected to MongoDB');
122+
123+
app.listen(PORT, () => {
124+
console.log(`🚀 Server running on port ${PORT}`);
125+
});
126+
})
127+
.catch((err) => {
128+
console.error('❌ MongoDB connection error:', err);
129+
});

0 commit comments

Comments
 (0)