From c1a0e9e81f3d3ad1f2d657c6445b2f33202105a6 Mon Sep 17 00:00:00 2001
From: 65160381 <65160381@go.buu.ac.th>
Date: Tue, 25 Mar 2025 03:03:11 +0700
Subject: [PATCH] 9.2

---
 app.js                   | 239 ++++++++-------------------------------
 public/index.html        |  15 ++-
 public/post-product.html |   9 +-
 3 files changed, 68 insertions(+), 195 deletions(-)

diff --git a/app.js b/app.js
index f92b3f6..d34a121 100644
--- a/app.js
+++ b/app.js
@@ -5,8 +5,10 @@ const mysql = require('mysql2/promise');
 const bcrypt = require('bcryptjs');
 const session = require('express-session');
 const cookieParser = require('cookie-parser');
+const path = require('path');
+const multer = require('multer'); // เพิ่มการใช้ multer
 
-const app = express(); // ต้องมีการสร้าง express app
+const app = express();
 
 // Middleware สำหรับ parse cookie และ JSON
 app.use(express.json());
@@ -19,9 +21,9 @@ app.use(session({
     resave: false,
     saveUninitialized: true,
     cookie: {
-        secure: process.env.NODE_ENV === 'production', // secure เมื่อเป็น production mode
-        httpOnly: true, // ป้องกันการเข้าถึงผ่าน JavaScript
-        maxAge: 1000 * 60 * 60 * 24 // อายุของ session (1 วัน)
+        secure: process.env.NODE_ENV === 'production', 
+        httpOnly: true,
+        maxAge: 1000 * 60 * 60 * 24
     }
 }));
 
@@ -48,7 +50,10 @@ pool.getConnection()
         process.exit(1); // หยุดโปรแกรมหากเชื่อมต่อไม่สำเร็จ
     });
 
-// ตัวอย่าง route ทดสอบ
+// Static file serving
+app.use(express.static(path.join(__dirname, 'public')));
+
+// Session และ routes
 app.get('/', (req, res) => {
     if (req.session.user) {
         res.sendFile(path.join(__dirname, 'public', 'index.html'));
@@ -57,63 +62,35 @@ app.get('/', (req, res) => {
     }
 });
 
-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'));
-});
+// Routes สำหรับ login และ register
+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
+// Logout route
 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
+        res.redirect('/login');
     });
 });
 
-
+// User Registration
 app.post('/register', async (req, res) => {
     const { email, password } = req.body;
-
-    if (!email || !password) {
-        return res.status(400).json({ error: 'All fields are required' });
-    }
+    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]
-        );
+        const [existingUser] = await pool.query('SELECT * FROM users WHERE email = ?', [email]);
 
-        if (existingUser.length > 0) {
-            return res.status(400).json({ error: 'Email already exists' });
-        }
+        if (existingUser.length > 0) return res.status(400).json({ error: 'Email already exists' });
 
-        // เข้ารหัสรหัสผ่านด้วย bcryptjs
         const hashedPassword = await bcrypt.hash(password, 10);
+        await pool.query('INSERT INTO users (email, password) VALUES (?, ?)', [email, hashedPassword]);
 
-        // เพิ่มข้อมูลลงฐานข้อมูล (ใช้แค่ 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);
@@ -121,195 +98,77 @@ app.post('/register', async (req, res) => {
     }
 });
 
-
-// Route สำหรับการล็อกอิน
+// User Login
 app.post('/login', async (req, res) => {
-    const { email, password } = req.body;  // ใช้ email แทน user
+    const { email, password } = req.body;
+
     try {
         const connection = await pool.getConnection();
-        // ค้นหาผู้ใช้จาก email
-        const [rows] = await connection.query(
-            'SELECT * FROM users WHERE email = ?',
-            [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;
+                req.session.user = { id: rows[0].user_id, email: rows[0].email };
+                res.redirect('/');
             } 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) => {
+// Product API (for logged in users)
+const upload = multer({ dest: './uploads/' });  // การตั้งค่า multer เพื่ออัปโหลดไฟล์
+
+app.post('/api/products', upload.single('productImg'), (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
+    const { productName, productPrice } = req.body;
+    const productImg = req.file ? `/uploads/${req.file.filename}` : null;
+    const userId = req.session.user.id;
 
-    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');
+    if (!productName || !productPrice || !productImg) {
+        return res.status(400).json({ message: 'All fields are required' });
+    }
+
+    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.json({ message: 'Product added successfully', productId: results.insertId });
     });
 });
 
-// ดึงสินค้าของผู้ใช้
+// Fetch products of logged-in user
 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');
-        }
+    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);
     });
 });
 
-// ดึงสินค้าทั้งหมด
+// Fetch all products
 app.get('/api/products', (req, res) => {
     pool.query('SELECT * FROM products', (err, results) => {
-        if (err) {
-            return res.status(500).send('Error fetching products');
-        }
+        if (err) return res.status(500).send('Error fetching products');
         res.json(results);
     });
 });
 
-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
+// Start server
 const port = process.env.PORT || 3000;
 app.listen(port, () => {
     console.log(`🚀 Server started on port ${port}`);
diff --git a/public/index.html b/public/index.html
index 72f362c..bfec8a2 100644
--- a/public/index.html
+++ b/public/index.html
@@ -20,7 +20,7 @@
         </div>
         <div class="user-info">
             <span id="welcome-message">Welcome, User</span> <!-- Display User's Email here -->
-            <a href="edit-order.html" class="edit-order-btn">Edit Order</a> <!-- ปุ่ม Edit Order -->
+            <a href="edit-order.html" class="edit-order-btn">Edit Order</a>
         </div>
         <div class="logout">
             <a href="/logout">Logout</a>
@@ -69,6 +69,7 @@
             });
         }
 
+        // Search products function
         function searchProducts() {
             const searchQuery = document.getElementById('search').value.toLowerCase();
             fetchProducts(searchQuery);
@@ -104,17 +105,23 @@
             cartItemCount.textContent = totalQuantity;
         }
 
+        // Display user's email from session
         async function displayUsername() {
             try {
                 const response = await fetch('/api/getUser');  // Endpoint to get the user's email
-                const user = await response.json();
-                document.getElementById('welcome-message').innerText = `Welcome, ${user.email}`; // Display email here
+                if (response.status === 401) {
+                    console.log('User not logged in');
+                    document.getElementById('welcome-message').innerText = 'Please log in';
+                } else {
+                    const user = await response.json();
+                    document.getElementById('welcome-message').innerText = `Welcome, ${user.email}`; // Display email here
+                }
             } catch (error) {
                 console.log('Error fetching user info:', error);
             }
         }
 
-        // Initially load products and cart item count
+        // Initially load products, cart item count, and user info
         fetchProducts();  // Fetch all products initially
         updateCart(); // Update cart count when page loads
         displayUsername(); // Display user's email when page loads
diff --git a/public/post-product.html b/public/post-product.html
index d5a4e55..837d342 100644
--- a/public/post-product.html
+++ b/public/post-product.html
@@ -39,6 +39,12 @@
             const productPrice = document.getElementById('product_price').value;
             const productImg = document.getElementById('product_img').value;
 
+            // Validate form fields
+            if (!productName || !productPrice || !productImg) {
+                alert('All fields are required!');
+                return;
+            }
+
             try {
                 const response = await fetch('/api/products', {
                     method: 'POST',
@@ -47,7 +53,7 @@
                     },
                     body: JSON.stringify({
                         product_name: productName,
-                        product_price: productPrice,
+                        product_price: parseFloat(productPrice),
                         product_img: productImg
                     }),
                     credentials: 'same-origin', // ส่ง cookie ไปกับ request
@@ -55,6 +61,7 @@
 
                 if (response.ok) {
                     alert('Product posted successfully');
+                    document.getElementById('post-product-form').reset();  // รีเซ็ตฟอร์ม
                     window.location.href = '/';  // เปลี่ยนเส้นทางไปหน้าหลัก
                 } else {
                     const errorMessage = await response.text();
-- 
GitLab