portfolio-page/backend/server.js

112 lines
3.1 KiB
JavaScript

import express from 'express';
import cors from 'cors';
import helmet from 'helmet';
import rateLimit from 'express-rate-limit';
import dotenv from 'dotenv';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
import { contactRouter } from './routes/contact.js';
import { errorHandler, notFoundHandler } from './middleware/errorHandlers.js';
import { requestLogger } from './middleware/logger.js';
import { initializeEmailService } from './services/emailService.js';
// Get the directory of the current module
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Load environment variables from the backend directory
dotenv.config({ path: join(__dirname, '.env') });
async function startServer() {
// Initialize email service after environment variables are loaded
await initializeEmailService();
const app = express();
const PORT = process.env.PORT || 3001;
// Security middleware
app.use(
helmet({
crossOriginResourcePolicy: { policy: 'cross-origin' },
})
);
// CORS configuration
app.use(
cors({
origin: process.env.FRONTEND_URL || 'http://localhost:5173',
methods: ['GET', 'POST'],
allowedHeaders: ['Content-Type', 'Authorization'],
credentials: true,
})
);
// Rate limiting
const limiter = rateLimit({
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000, // 15 minutes
max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS) || 5, // limit each IP to 5 requests per windowMs
message: {
error: 'Too many requests from this IP, please try again later.',
retryAfter: Math.ceil(
(parseInt(process.env.RATE_LIMIT_WINDOW_MS) || 15 * 60 * 1000) / 1000
),
},
standardHeaders: true,
legacyHeaders: false,
});
app.use('/api/', limiter);
// Body parsing middleware
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true, limit: '10mb' }));
// Request logging
app.use(requestLogger);
// Health check endpoint
app.get('/health', (req, res) => {
res.json({
status: 'ok',
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV || 'development',
});
});
// API routes
app.use('/api/contact', contactRouter);
// Error handling middleware
app.use(notFoundHandler);
app.use(errorHandler);
// Start server
app.listen(PORT, () => {
console.log(`🚀 Server is running on port ${PORT}`);
console.log(
`📧 Email service: ${process.env.EMAIL_SERVICE || 'Not configured'}`
);
console.log(`🌍 Environment: ${process.env.NODE_ENV || 'development'}`);
console.log(
`🔗 Frontend URL: ${process.env.FRONTEND_URL || 'http://localhost:5173'}`
);
});
// Graceful shutdown
process.on('SIGTERM', () => {
console.log('SIGTERM signal received: closing HTTP server');
process.exit(0);
});
process.on('SIGINT', () => {
console.log('SIGINT signal received: closing HTTP server');
process.exit(0);
});
}
// Start the server
startServer().catch((error) => {
console.error('Failed to start server:', error);
process.exit(1);
});