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(); const MySQLStore = require('express-mysql-session')(session); const sessionStore = new MySQLStore({ clearExpired: true, checkExpirationInterval: 900000, expiration: 86400000 }, pool); const isLoggedIn = (req, res, next) => { if (req.session.user) { next(); } else { res.redirect('/login'); } }; app.use(session({ secret: process.env.SESSION_SECRET || "mysecret", resave: false, saveUninitialized: false, store: sessionStore, cookie: { maxAge: 24 * 60 * 60 * 1000, secure: false, httpOnly: true, }, })); app.use(express.static(path.join(__dirname, "public"))); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.use((req, res, next) => { console.log("🔹 Session Data:", req.session); next(); }); app.set("view engine", "ejs"); app.set("views", path.join(__dirname, "views")); const orderRoutes = require("./shop-routes/order"); const cartRoutes = require("./shop-routes/cart"); const indexRoutes = require("./shop-routes/index"); app.use((req, res, next) => { res.locals.session = req.session; next(); }); app.use("/", indexRoutes); app.use("/cart", cartRoutes); app.use("/order", orderRoutes); app.get('/order/checkout', isLoggedIn, (req, res) => { res.render('checkout'); }); 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 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('/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 }; console.log("User logged in:", req.session); return res.redirect('/order/checkout'); } catch (error) { res.status(500).json({ message: "Login failed." }); } }); // Logout Routes app.get("/logout", (req, res) => { if (!req.session) { return res.redirect("/login"); } req.session.destroy((err) => { if (err) { return res.status(500).json({ message: "Logout failed." }); } res.clearCookie('connect.sid'); console.log("User logged out."); res.redirect("/login"); }); }); app.post("/logout", (req, res) => { if (!req.session) { return res.status(400).json({ message: "No active session." }); } req.session.destroy(err => { if (err) { return res.status(500).json({ message: "Logout failed." }); } res.clearCookie('connect.sid'); console.log("User logged out (POST)"); res.status(200).json({ message: "Logged out successfully" }); }); }); 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.use((err, req, res, next) => { res.status(500).json({ message: "Something went wrong." }); }); const PORT = process.env.PORT || 3000; app.listen(PORT, () => console.log(`Server running on port ${PORT}`));