import "dotenv/config"; import express from 'express'; import mysql from 'mysql2/promise'; import cors from 'cors'; import path from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const app = express(); const PORT = process.env.PORT || 3000; const isDebug = process.env.NODE_ENV !== 'production' || process.env.DEBUG === 'true'; // Middleware app.use(cors()); app.use(express.json()); // Database setup let pool; async function initializeDB() { const dbConfig = { host: process.env.DB_HOST || 'truenas.site', user: process.env.DB_USER || 'wifi', password: process.env.DB_PASSWORD || 'wifi12345', database: process.env.DB_NAME || 'wifishare', waitForConnections: true, connectionLimit: 10, queueLimit: 0 }; try { pool = mysql.createPool(dbConfig); // Create table (MariaDB/MySQL syntax) await pool.query(` CREATE TABLE IF NOT EXISTS markers ( id VARCHAR(50) PRIMARY KEY, name VARCHAR(255) NOT NULL, ssid VARCHAR(255) NOT NULL, password VARCHAR(255), lat DOUBLE NOT NULL, lng DOUBLE NOT NULL, securityType VARCHAR(50) NOT NULL, iconType VARCHAR(50) NOT NULL, description TEXT, addedBy VARCHAR(100), createdAt BIGINT, isPublic TINYINT DEFAULT 1 ) `); console.log(`[DB] MariaDB connected to ${dbConfig.host}/${dbConfig.database}`); const [rows] = await pool.query('SELECT COUNT(*) as count FROM markers'); console.log(`[DB] Current Status: ${rows[0].count} markers stored in database.`); } catch (error) { console.error('[DB] MariaDB connection failed details:', error); console.error('[DB] Host:', dbConfig.host); process.exit(1); } } // Routes app.get('/api/markers', async (req, res) => { const host = req.headers.host; if (isDebug) console.log(`[API] GET /api/markers - Host: ${host} - Fetching from MariaDB`); try { const [markers] = await pool.query('SELECT * FROM markers'); if (isDebug) console.log(`[API] Found ${markers.length} markers`); // Convert isPublic from 0/1 to boolean const formattedMarkers = markers.map(m => ({ ...m, isPublic: !!m.isPublic })); res.json(formattedMarkers); } catch (error) { console.error('[API] GET Markers Error:', error); res.status(500).json({ error: 'Failed to fetch markers', detail: error.message }); } }); app.post('/api/markers', async (req, res) => { const { id, name, ssid, password, lat, lng, securityType, iconType, description, addedBy, createdAt, isPublic } = req.body; if (isDebug) console.log(`[API] POST /api/markers - Saving marker: ${name} (${ssid}) to MariaDB`); try { await pool.query(` INSERT INTO markers (id, name, ssid, password, lat, lng, securityType, iconType, description, addedBy, createdAt, isPublic) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE name=VALUES(name), ssid=VALUES(ssid), password=VALUES(password), lat=VALUES(lat), lng=VALUES(lng), securityType=VALUES(securityType), iconType=VALUES(iconType), description=VALUES(description), addedBy=VALUES(addedBy), createdAt=VALUES(createdAt), isPublic=VALUES(isPublic) `, [id, name, ssid, password, lat, lng, securityType, iconType, description || '', addedBy, createdAt, isPublic ? 1 : 0]); if (isDebug) console.log(`[API] Successfully saved marker: ${id}`); res.json({ success: true }); } catch (error) { console.error('[API] POST Marker Error:', error); res.status(500).json({ error: 'Failed to save marker', detail: error.message }); } }); app.delete('/api/markers/:id', async (req, res) => { const { id } = req.params; if (isDebug) console.log(`[API] DELETE /api/markers/${id} - Deleting marker from MariaDB`); try { await pool.query('DELETE FROM markers WHERE id = ?', [id]); if (isDebug) console.log(`[API] Successfully deleted marker: ${id}`); res.json({ success: true }); } catch (error) { console.error(error); res.status(500).json({ error: 'Failed to delete marker' }); } }); // Serve static files from dist app.use(express.static(path.join(__dirname, 'dist'))); // Fallback for SPA app.get(/.*/, (req, res) => { res.sendFile(path.join(__dirname, 'dist', 'index.html')); }); initializeDB().then(() => { app.listen(PORT, '0.0.0.0', () => { console.log(`Server running on http://0.0.0.0:${PORT}`); }); });