Files
balikci/backend/src/app.js
salvacybersec 9f53a34cfb ulaan
2025-11-11 07:46:58 +03:00

164 lines
5.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

require('dotenv').config({ path: require('path').join(__dirname, '../.env') });
const express = require('express');
const session = require('express-session');
// const helmet = require('helmet'); // Geçici olarak devre dışı
const cors = require('cors');
const logger = require('./config/logger');
const sessionConfig = require('./config/session');
const { testConnection } = require('./config/database');
const errorHandler = require('./middlewares/errorHandler');
const { apiLimiter } = require('./middlewares/rateLimiter');
const app = express();
const PORT = process.env.PORT || 3000;
// Security middleware - Helmet'i tamamen kaldır (CORS ve mixed content sorunları için)
// app.use(helmet()); // Geçici olarak devre dışı
// CORS - Her yerden erişime izin ver (tüm route'larda)
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, PATCH, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
// OPTIONS request'i için hemen cevap ver
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
// CORS middleware'i de ekle (çift güvence)
app.use(cors({
origin: '*', // Tüm origin'lere izin ver
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
allowedHeaders: ['Content-Type', 'Authorization', 'X-Requested-With', 'Origin', 'Accept'],
}));
// Body parsing middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Serve static files (landing page and frontend build)
const path = require('path');
app.use(express.static(path.join(__dirname, 'public'), {
setHeaders: (res, filePath) => {
// CORS headers for ALL static files (CSS, JS, images, etc.)
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.set('Access-Control-Allow-Headers', 'Content-Type, Accept, Origin');
res.set('Access-Control-Allow-Credentials', 'true');
// Content-Type header'larını doğru ayarla
if (filePath.endsWith('.js')) {
res.set('Content-Type', 'application/javascript; charset=utf-8');
} else if (filePath.endsWith('.css')) {
res.set('Content-Type', 'text/css; charset=utf-8');
}
}
}));
// Serve landing page at /landing route
app.get('/landing', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'landing.html'));
});
// Session middleware
app.use(session(sessionConfig));
// Rate limiting
app.use('/api', apiLimiter);
// Request logging
app.use((req, res, next) => {
logger.info(`${req.method} ${req.path}`, {
ip: req.ip,
userAgent: req.get('user-agent'),
});
next();
});
// Health check
app.get('/health', (req, res) => {
res.json({
success: true,
message: 'Server is running',
timestamp: new Date().toISOString(),
});
});
// API Routes
app.use('/api/auth', require('./routes/auth.routes'));
app.use('/api/companies', require('./routes/company.routes'));
app.use('/api/tokens', require('./routes/token.routes'));
app.use('/api/templates', require('./routes/template.routes'));
app.use('/api/settings', require('./routes/settings.routes'));
app.use('/api/ollama', require('./routes/ollama.routes'));
app.use('/api/stats', require('./routes/stats.routes'));
// Public tracking route (no rate limit on this specific route)
app.use('/t', require('./routes/tracking.routes'));
// Serve frontend SPA (must be after API routes)
app.get('*', (req, res, next) => {
// Skip if it's an API route, tracking route, or landing page
if (req.path.startsWith('/api') || req.path.startsWith('/t') || req.path.startsWith('/landing') || req.path.startsWith('/health')) {
return next();
}
// CORS headers for HTML
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
// Serve frontend index.html for all other routes
const frontendPath = path.join(__dirname, 'public', 'dist', 'index.html');
res.sendFile(frontendPath, (err) => {
if (err) {
// If frontend build doesn't exist, return 404
next();
}
});
});
// 404 handler
app.use((req, res) => {
res.status(404).json({
success: false,
error: 'Endpoint not found',
});
});
// Error handler (must be last)
app.use(errorHandler);
// Start server
const startServer = async () => {
try {
// Test database connection
await testConnection();
// Start listening on all interfaces (0.0.0.0) to allow remote access
app.listen(PORT, '0.0.0.0', () => {
logger.info(`🚀 Server is running on port ${PORT}`);
logger.info(`📊 Environment: ${process.env.NODE_ENV || 'development'}`);
logger.info(`🔗 Health check: http://0.0.0.0:${PORT}/health`);
console.log(`\n✨ Oltalama Backend Server Started!`);
console.log(`🌐 API: http://0.0.0.0:${PORT}/api`);
console.log(`🎯 Tracking: http://0.0.0.0:${PORT}/t/:token`);
console.log(`🌍 Server listening on all interfaces (0.0.0.0:${PORT})\n`);
});
} catch (error) {
logger.error('Failed to start server:', error);
process.exit(1);
}
};
startServer();
module.exports = app;