diff --git a/server.js b/server.js index dfae8bc..a8268b0 100644 --- a/server.js +++ b/server.js @@ -15,15 +15,27 @@ const __dirname = path.dirname(__filename); const app = express(); const PORT = process.env.PORT || 3000; +// 1. CORS deve essere la prima cosa per gestire le richieste OPTIONS dei browser app.use(cors()); -app.use(express.json()); -app.use(express.static(path.join(__dirname, 'dist'))); +app.options('*', cors()); +// 2. Logging immediato di ogni richiesta app.use((req, res, next) => { - console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`); + const start = Date.now(); + res.on('finish', () => { + const duration = Date.now() - start; + console.log(`[${new Date().toISOString()}] ${req.method} ${req.url} - Status: ${res.statusCode} (${duration}ms)`); + }); next(); }); +// 3. Parser JSON con limite aumentato (fondamentale per template HTML grandi) +app.use(express.json({ limit: '10mb' })); +app.use(express.urlencoded({ limit: '10mb', extended: true })); + +// 4. File statici +app.use(express.static(path.join(__dirname, 'dist'))); + const rawDbType = (process.env.DB_TYPE || 'mysql').toLowerCase().trim(); const DB_TYPE = (rawDbType === 'postgres' || rawDbType === 'postgresql') ? 'postgres' : 'mysql'; @@ -35,13 +47,9 @@ const dbConfig = { port: process.env.DB_PORT || (DB_TYPE === 'postgres' ? 5432 : 3306), }; -console.log('--- Database Configuration ---'); -console.log(`Type: ${DB_TYPE}`); -console.log(`Host: ${dbConfig.host}`); -console.log(`User: ${dbConfig.user}`); -console.log(`Database: ${dbConfig.database}`); -console.log(`Port: ${dbConfig.port}`); -console.log('------------------------------'); +console.log('--- App Version: 1.0.2 ---'); +console.log(`DB Type: ${DB_TYPE}`); +console.log(`DB Host: ${dbConfig.host}`); let pool; @@ -49,46 +57,16 @@ const initDB = async (retries = 5) => { while (retries > 0) { try { if (!dbConfig.host || !dbConfig.user || !dbConfig.database) { - throw new Error("Missing required database environment variables."); + throw new Error("Missing required database environment variables (DB_HOST, DB_USER, DB_NAME)."); } if (DB_TYPE === 'postgres') { const { Pool } = pg; pool = new Pool(dbConfig); - await pool.query(` - CREATE TABLE IF NOT EXISTS email_templates ( - id VARCHAR(255) PRIMARY KEY, - template_key VARCHAR(255) UNIQUE NOT NULL, - name VARCHAR(255) NOT NULL, - description TEXT, - subject VARCHAR(255), - header_html TEXT, - body_html TEXT, - footer_html TEXT, - full_html TEXT, - required_variables JSONB, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - ); - `); + await pool.query('SELECT 1'); // Test connection } else { pool = mysql.createPool(dbConfig); - await pool.query(` - CREATE TABLE IF NOT EXISTS email_templates ( - id VARCHAR(255) PRIMARY KEY, - template_key VARCHAR(255) UNIQUE NOT NULL, - name VARCHAR(255) NOT NULL, - description TEXT, - subject VARCHAR(255), - header_html MEDIUMTEXT, - body_html MEDIUMTEXT, - footer_html MEDIUMTEXT, - full_html MEDIUMTEXT, - required_variables JSON, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP - ); - `); + await pool.query('SELECT 1'); // Test connection } console.log(`Connected to ${DB_TYPE} database successfully.`); return; @@ -96,10 +74,11 @@ const initDB = async (retries = 5) => { retries -= 1; console.error(`Database connection failed (${retries} retries left):`, err.message); if (retries === 0) { - console.error("No more retries. Exiting."); - process.exit(1); + console.error("FATAL: Could not connect to database."); + // Non usciamo per permettere al server di servire i file statici e mostrare errori via API + } else { + await new Promise(resolve => setTimeout(resolve, 5000)); } - await new Promise(resolve => setTimeout(resolve, 5000)); } } }; @@ -108,6 +87,8 @@ initDB(); app.get('/api/templates', async (req, res) => { try { + if (!pool) return res.status(503).json({ error: "Database not connected" }); + let rows; if (DB_TYPE === 'postgres') { const result = await pool.query('SELECT * FROM email_templates ORDER BY updated_at DESC'); @@ -137,12 +118,10 @@ app.get('/api/templates', async (req, res) => { }); app.post('/api/templates', async (req, res) => { - console.log("POST /api/templates - Ricevuta richiesta di salvataggio"); const t = req.body; if (!t.name || !t.id) { - console.error("ERRORE: Dati mancanti nella richiesta POST", t); - return res.status(400).json({ error: "Nome e ID sono obbligatori" }); + return res.status(400).json({ error: "Name and ID are required" }); } const header = t.header || ''; @@ -166,7 +145,8 @@ app.post('/api/templates', async (req, res) => { ]; try { - console.log(`Tentativo di salvataggio nel DB (${DB_TYPE}) per chiave: ${templateKey}`); + if (!pool) throw new Error("Database not connected"); + if (DB_TYPE === 'postgres') { const query = ` INSERT INTO email_templates (id, template_key, name, description, subject, header_html, body_html, footer_html, full_html, required_variables, updated_at) @@ -201,16 +181,16 @@ app.post('/api/templates', async (req, res) => { `; await pool.query(query, params); } - console.log("Salvataggio DB riuscito"); res.json({ success: true }); } catch (err) { - console.error("ERRORE SALVATAGGIO DB:", err.message); - res.status(500).json({ error: 'Failed to save template', details: err.message }); + console.error("DB Save Error:", err.message); + res.status(500).json({ error: 'Database save failed', details: err.message }); } }); app.delete('/api/templates/:id', async (req, res) => { try { + if (!pool) return res.status(503).json({ error: "Database not connected" }); if (DB_TYPE === 'postgres') { await pool.query('DELETE FROM email_templates WHERE id = $1', [req.params.id]); } else { @@ -227,6 +207,6 @@ app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')); }); -app.listen(PORT, () => { +app.listen(PORT, '0.0.0.0', () => { console.log(`Server running on port ${PORT}`); });