require('dotenv').config(); // โหลดค่าตัวแปรจากไฟล์ .env const express = require('express'); const mysql = require('mysql2/promise'); const bcrypt = require('bcryptjs'); const session = require('express-session'); const cookieParser = require('cookie-parser'); const app = express(); // ต้องมีการสร้าง express app // Middleware สำหรับ parse cookie และ JSON app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use(cookieParser()); // Session configuration app.use(session({ secret: process.env.DB_SESSION || 'melon', resave: false, saveUninitialized: true, cookie: { secure: process.env.NODE_ENV === 'production', // secure เมื่อเป็น production mode httpOnly: true, // ป้องกันการเข้าถึงผ่าน JavaScript maxAge: 1000 * 60 * 60 * 24 // อายุของ session (1 วัน) } })); // Database configuration const pool = mysql.createPool({ host: process.env.DB_HOST || "10.104.20.74", port: process.env.DB_PORT || "3306", user: process.env.DB_USER || "root", password: process.env.DB_PASSWORD || "TNSypb73606", database: process.env.DB_NAME || "project", waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); // ทดสอบการเชื่อมต่อกับฐานข้อมูล pool.getConnection() .then(connection => { console.log('✅ Database connected successfully!'); connection.release(); }) .catch(err => { console.error('❌ Database connection failed:', err); process.exit(1); // หยุดโปรแกรมหากเชื่อมต่อไม่สำเร็จ }); // ตัวอย่าง route ทดสอบ app.get('/', (req, res) => { if (req.session.user) { res.sendFile(path.join(__dirname, 'public', 'index.html')); } else { res.redirect('/login'); } }); const path = require('path'); app.use(express.static(path.join(__dirname, 'public'))); app.get('/login', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'login.html')); }); app.get('/register', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'register.html')); }); app.get('/post-product', (req, res) => { res.sendFile(path.join(__dirname, 'public', 'post-product.html')); }); // Route สำหรับการ logout app.get('/logout', (req, res) => { // ลบข้อมูลใน session req.session.destroy((err) => { if (err) { console.error('Logout error:', err); return res.status(500).send('Logout failed'); } // เมื่อ logout สำเร็จ, redirect ไปที่หน้า login หรือหน้าอื่น res.redirect('/login'); // เปลี่ยนไปหน้า login หลังจาก logout }); }); app.post('/register', async (req, res) => { const { email, password } = req.body; if (!email || !password) { return res.status(400).json({ error: 'All fields are required' }); } try { // ตรวจสอบว่า email มีอยู่แล้วหรือไม่ const [existingUser] = await pool.query( 'SELECT * FROM users WHERE email = ?', [email] ); if (existingUser.length > 0) { return res.status(400).json({ error: 'Email already exists' }); } // เข้ารหัสรหัสผ่านด้วย bcryptjs const hashedPassword = await bcrypt.hash(password, 10); // เพิ่มข้อมูลลงฐานข้อมูล (ใช้แค่ email และ password) await pool.query( 'INSERT INTO users (email, password) VALUES (?, ?)', [email, hashedPassword] ); // หลังจากสมัครเสร็จแล้ว Redirect ไปหน้า Login res.redirect('/login'); } catch (error) { console.error('❌ Registration failed:', error); res.status(500).json({ error: 'Registration failed' }); } }); // Route สำหรับการล็อกอิน app.post('/login', async (req, res) => { const { email, password } = req.body; // ใช้ email แทน user try { const connection = await pool.getConnection(); // ค้นหาผู้ใช้จาก email const [rows] = await connection.query( 'SELECT * FROM users WHERE email = ?', [email] ); connection.release(); if (rows.length > 0) { // ตรวจสอบรหัสผ่าน const match = await bcrypt.compare(password, rows[0].password); if (match) { // เก็บข้อมูลผู้ใช้ใน session (แค่ user_id และ email) req.session.user = { id: rows[0].user_id, // user_id ของผู้ใช้ email: rows[0].email }; console.log("User session:", req.session.user); // เพิ่ม console log เพื่อตรวจสอบ res.redirect('/'); // ไปที่หน้า home หรือหน้าแรกหลังจากล็อกอิน return; } else { res.status(400).send('Invalid password'); return; } } else { res.status(400).send('User not found'); return; } } catch (err) { console.error('Login error:', err); res.status(500).send('Login failed'); return; } }); // API สำหรับดึงข้อมูลผู้ใช้หลังจากล็อกอิน app.get('/api/getUser', (req, res) => { if (req.session.user) { res.json({ user_id: req.session.user.id, // ส่งข้อมูล user_id จาก session email: req.session.user.email // ส่งข้อมูล email จาก session }); } else { res.status(401).send('User not logged in'); } }); // เพิ่มสินค้าใหม่ app.get('/api/user/products', async (req, res) => { if (!req.session.user) { return res.status(401).send('User not logged in'); } const userId = req.session.user.id; // ใช้ user_id จาก session try { const connection = await pool.getConnection(); const [products] = await connection.query( 'SELECT * FROM products WHERE user_id = ?', [userId] ); connection.release(); res.json(products); } catch (err) { console.error('Error fetching user products:', err); res.status(500).send('Error fetching user products'); } }); // เพิ่มสินค้าใหม่ app.post('/api/products', (req, res) => { if (!req.session.user) { return res.status(401).send('User not logged in'); } const { productName, productPrice, productImg } = req.body; const userId = req.session.user.id; // user_id จาก session pool.query(` INSERT INTO products (product_name, product_price, product_img, user_id) VALUES (?, ?, ?, ?) `, [productName, productPrice, productImg, userId], (err, results) => { if (err) { return res.status(500).send('Error adding product'); } res.send('Product added successfully'); }); }); // ดึงสินค้าของผู้ใช้ app.get('/api/user/products', (req, res) => { if (!req.session.user) { return res.status(401).send('User not logged in'); } const userId = req.session.user.id; pool.query(` SELECT * FROM products WHERE user_id = ? `, [userId], (err, results) => { if (err) { return res.status(500).send('Error fetching user products'); } res.json(results); }); }); // ดึงสินค้าทั้งหมด app.get('/api/products', (req, res) => { pool.query('SELECT * FROM products', (err, results) => { if (err) { return res.status(500).send('Error fetching products'); } res.json(results); }); }); app.use(express.json()); // สำหรับการ parse ข้อมูลแบบ JSON app.use(express.urlencoded({ extended: true })); // สำหรับการ parse ข้อมูลแบบ URL-encoded app.post('/logout', (req, res) => { req.session.destroy(err => { if (err) { console.error('❌ Logout failed:', err); return res.status(500).json({ error: 'Logout failed' }); } res.clearCookie('connect.sid'); res.status(200).json({ message: 'Logout successful' }); }); }); const isAuthenticated = (req, res, next) => { if (req.session.user) { next(); } else { res.status(401).json({ error: 'Unauthorized' }); } }; app.get('/dashboard', isAuthenticated, (req, res) => { res.status(200).json({ message: `Welcome ${req.session.user.username}` }); }); // ให้บริการไฟล์ static เช่น รูปภาพที่ถูกอัพโหลด app.use('/uploads', express.static(path.join(__dirname, 'uploads'))); // ตั้งค่าการจัดเก็บไฟล์ const storage = multer.diskStorage({ destination: function(req, file, cb) { cb(null, './uploads/'); // กำหนดโฟลเดอร์ที่ใช้เก็บไฟล์ }, filename: function(req, file, cb) { cb(null, Date.now() + path.extname(file.originalname)); // ตั้งชื่อไฟล์ใหม่ (ใช้ timestamp) } }); const upload = multer({ storage: storage }); // ฟอร์มสำหรับโพสต์สินค้าที่รองรับการอัพโหลดไฟล์ app.post('/api/products', upload.single('productImg'), (req, res) => { const { productName, productPrice } = req.body; const productImg = req.file ? `/uploads/${req.file.filename}` : null; const userId = req.session.user.id; // ค่าของ user_id จาก session หรือ JWT if (!productName || !productPrice || !productImg) { return res.status(400).json({ message: 'All fields are required' }); } // คำสั่ง SQL สำหรับเพิ่มสินค้าใหม่ในฐานข้อมูล const query = ` INSERT INTO products (product_name, product_price, product_img, user_id) VALUES (?, ?, ?, ?) `; // บันทึกข้อมูลสินค้าในฐานข้อมูล pool.query(query, [productName, productPrice, productImg, userId], (err, results) => { if (err) { console.error('Error adding product:', err); return res.status(500).send('Error adding product'); } res.json({ message: 'Product added successfully', productId: results.insertId }); }); }); // Start the server const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`🚀 Server started on port ${port}`); });