const express = require("express"); const path = require("path"); const session = require("express-session"); const bcrypt = require("bcrypt"); const pool = require("./config/database"); require("dotenv").config(); const app = express(); //ตั้งค่าsessionให้ใช้ MySQLStore const MySQLStore = require('express-mysql-session')(session); const sessionStore = new MySQLStore({ clearExpired: true, checkExpirationInterval: 900000, // 15 นาที expiration: 86400000, // 1 วัน }, pool); app.use(session({ secret: process.env.SESSION_SECRET || "mysecret", resave: false, saveUninitialized: false, store: sessionStore, cookie: { maxAge: 24 * 60 * 60 * 1000, secure: false, // เปลี่ยนเป็น true ถ้าใช้ HTTPS httpOnly: false // เปลี่ยนจาก true เป็น false เพื่อลองดูว่า cookie เก็บค่าหรือไม่ } })); app.use((req, res, next) => { console.log("SESSION:", req.session); next(); }); console.log("Session Middleware Initialized"); //Middleware app.use(express.static(path.join(__dirname, "public"))); app.use(express.json()); app.use(express.urlencoded({ extended: true })); //Middlewareเช็คSessionUser app.use((req, res, next) => { res.locals.user = req.session.user || null; next(); }); //ตั้งค่าEJS app.set("view engine", "ejs"); app.set("views", path.join(__dirname, "views")); //เชื่อมRoute const orderRoutes = require("./shop-routes/order"); const cartRoutes = require("./shop-routes/cart"); const indexRoutes = require("./shop-routes/index"); const productRoutes = require("./shop-routes/product"); app.use("/", indexRoutes); app.use("/cart", cartRoutes); app.use("/order", orderRoutes); app.use("/products", productRoutes); //Middlewareเช็คLogin const isLoggedIn = (req, res, next) => { if (req.session.user) { next(); } else { res.redirect('/login'); } }; //Register app.get('/register', (req, res) => { res.render('register'); }); app.post("/register", async (req, res) => { try { const { email, password, name } = req.body; if (!email || !password || !name) return res.status(400).json({ message: "All fields are required." }); const hashedPassword = await bcrypt.hash(password, 10); const [existingUser] = await pool.execute("SELECT * FROM users WHERE email = ?", [email]); if (existingUser.length > 0) return res.status(400).json({ message: "Email is already registered." }); await pool.execute("INSERT INTO users (email, password, name) VALUES (?, ?, ?)", [email, hashedPassword, name]); res.status(201).json({ success: true, message: "Registration successful." }); } catch (error) { res.status(500).json({ message: "Registration failed." }); } }); app.get('/login', (req, res) => { res.render('login'); }); app.post("/login", async (req, res) => { try { const { email, password } = req.body; if (!email || !password) return res.status(400).json({ message: "All fields are required." }); const [users] = await pool.execute("SELECT * FROM users WHERE email = ?", [email]); if (users.length === 0) return res.status(400).json({ message: "Invalid email or password." }); const user = users[0]; const passwordMatch = await bcrypt.compare(password, user.password); if (!passwordMatch) return res.status(400).json({ message: "Invalid email or password." }); req.session.user = { id: user.id, email: user.email }; req.session.save(err => { //บันทึก Session ก่อน Redirect if (err) { console.error("Session save error:", err); return res.send("Session save failed."); } console.log("Session after login:", req.session); res.redirect('/'); }); } catch (error) { res.status(500).json({ message: "Login failed." }); } }); app.get("/search", async (req, res) => { const searchQuery = req.query.query; try { const [results] = await pool.execute( "SELECT * FROM products WHERE name LIKE ? OR description LIKE ?", [`%${searchQuery}%`, `%${searchQuery}%`] ); res.render("index", { products: results }); } catch (err) { res.status(500).send("Error retrieving search results"); } }); app.get("/cart", isLoggedIn, async (req, res) => { try { // ดึงรายการสินค้าในตะกร้าจากฐานข้อมูล const [cartItems] = await pool.execute(` SELECT c.id, p.name, p.price, c.quantity, p.stock, p.image FROM cart_items c JOIN products p ON c.product_id = p.id WHERE c.user_id = ? `, [req.session.user.id]); // คำนวณยอดรวม const total = cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0); res.render("cart", { cartItems, total }); } catch (error) { console.error("Cart Error:", error); res.status(500).send("Error loading cart."); } }); app.post("/cart/add", async (req, res) => { if (!req.session.user) { return res.status(401).json({ message: "Please login first." }); } const { productId, quantity } = req.body; const userId = req.session.user.id; try { // เช็คว่าสินค้ามีอยู่ในตะกร้าหรือยัง const [existingCart] = await pool.execute( "SELECT * FROM cart_items WHERE user_id = ? AND product_id = ?", [userId, productId] ); if (existingCart.length > 0) { // ถ้ามีสินค้าอยู่แล้ว ให้เพิ่มจำนวน await pool.execute( "UPDATE cart_items SET quantity = quantity + ? WHERE user_id = ? AND product_id = ?", [quantity, userId, productId] ); } else { // ถ้าไม่มีสินค้า ให้เพิ่มใหม่ await pool.execute( "INSERT INTO cart_items (user_id, product_id, quantity) VALUES (?, ?, ?)", [userId, productId, quantity] ); } console.log("Added to Cart:", { userId, productId, quantity }); res.redirect("/cart"); } catch (error) { console.error("Error adding to cart:", error); res.status(500).json({ message: "Failed to add to cart." }); } }); app.post("/cart/update", async (req, res) => { try { const { cartItemId, quantity } = req.body; if (quantity < 1) { return res.status(400).json({ message: "Quantity must be at least 1" }); } await pool.execute("UPDATE cart_items SET quantity = ? WHERE id = ?", [quantity, cartItemId]); res.json({ success: true, message: "Cart updated" }); } catch (error) { console.error("Update error:", error); res.status(500).json({ message: "Update failed" }); } }); app.get('/order/checkout', isLoggedIn, (req, res) => { res.render('checkout'); }); app.get("/logout", (req, res) => { req.session.destroy(err => { if (err) return res.status(500).json({ message: "Logout failed." }); res.clearCookie('connect.sid', { path: '/' }); // เคลียร์ Cookie อย่างถูกต้อง res.redirect("/login"); }); }); app.use((err, req, res, next) => { console.error("Unhandled error:", err); res.status(500).json({ message: "Internal Server Error" }); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`));