diff --git a/public/dashboard.html b/public/dashboard.html index 0c81db9..dc800a6 100644 --- a/public/dashboard.html +++ b/public/dashboard.html @@ -123,23 +123,29 @@ async function getProfile() { const token = localStorage.getItem("token"); + const user = JSON.parse(localStorage.getItem("user")); - await fetch("/api/profile", { - method: "GET", + await fetch("/api/confirm-count", { + method: "POST", headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, + body: JSON.stringify({ + email: user.email, + }), }) .then((res) => res.json()) .then((data) => { document.getElementById( "welcome-user", - ).innerHTML = `Welcome, ${data?.user?.name} ▼`; + ).innerHTML = `Welcome, ${ + JSON.parse(localStorage.getItem("user")).name + } ▼`; document.getElementById( "confirm-count-user", - ).innerHTML = `Confirmed: ${data?.user?.confirm_count}`; + ).innerHTML = `Confirmed: ${data?.count}`; }) .catch((err) => { console.error(err); @@ -304,8 +310,7 @@ ); if (currentVerUser) { deviceConfirmBtn.style.display = "none"; - confirmedUserName.textContent = - currentVerUser.user.name; + confirmedUserName.textContent = currentVerUser.user; confirmUserText.style.display = "inline"; } else { deviceConfirmBtn.style.display = "inline-block"; @@ -602,6 +607,7 @@ ${license}`.trim(); if (!pendingDevice) return; const token = localStorage.getItem("token"); + const user = JSON.parse(localStorage.getItem("user")); try { const res = await fetch("/api/confirm-device", { method: "POST", @@ -609,7 +615,11 @@ ${license}`.trim(); "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, - body: JSON.stringify(pendingDevice), + body: JSON.stringify({ + ...pendingDevice, + name: user.name, + email: user.email, + }), }); const data = await res.json(); if (data.success) { diff --git a/public/login.html b/public/login.html index e29668e..57f7996 100644 --- a/public/login.html +++ b/public/login.html @@ -67,11 +67,17 @@ const errorMsg = document.querySelector(".error-msg"); try { - const res = await fetch("/api/login", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ email, password }), - }); + const res = await fetch( + "https://stage.nswteam.net/api/login", + { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + userEmail: email, + password, + }), + }, + ); const data = await res.json(); @@ -83,7 +89,16 @@ } localStorage.setItem("token", data.token); - localStorage.setItem("user", JSON.stringify(data.user)); + localStorage.setItem( + "user", + JSON.stringify({ + name: + data.data.firstName + + " " + + data.data.lastName, + email: data.data.userEmail, + }), + ); window.location.href = "/"; } catch (err) { diff --git a/route/web.js b/route/web.js index 1aae46c..32f6cf7 100644 --- a/route/web.js +++ b/route/web.js @@ -1,8 +1,5 @@ const express = require("express"); const path = require("path"); -const bcrypt = require("bcrypt"); -const { createToken } = require("../utils/jwt"); -const { authenticateToken } = require("../middleware/auth"); let router = express.Router(); @@ -15,60 +12,5 @@ module.exports = (app, db) => { res.sendFile(path.join(__dirname, "../public/login.html")); }); - router.post("/api/login", async (req, res) => { - const { email, password } = req.body; - - try { - const [rows] = await db.query( - "SELECT * FROM users WHERE email = ?", - [email], - ); - const user = rows[0]; - const isMatch = await bcrypt.compare( - password, - user?.password || "!@#", - ); - - if (!user || !isMatch) { - return res - .status(401) - .json({ message: "Invalid email or password" }); - } - - const token = createToken({ - id: user.id, - email: user.email, - name: user.name, - }); - return res - .status(200) - .json({ token, user: { name: user.name, email: user.email } }); - } catch (err) { - console.error("Login error:", err); - return res.status(500).json({ message: "Internal Server Error" }); - } - }); - - router.get("/api/profile", authenticateToken, async (req, res) => { - const userId = req.user?.id; - - try { - const [rows] = await db.query("SELECT * FROM users WHERE id = ?", [ - userId, - ]); - const user = rows[0]; - - return res.status(200).json({ - user: { - name: user.name, - confirm_count: user.confirm_count, - }, - }); - } catch (err) { - console.error(err); - return res.status(500).json({ message: "Internal Server Error" }); - } - }); - app.use("/", router); }; diff --git a/server.js b/server.js index 9dc7e9d..d13ebaa 100644 --- a/server.js +++ b/server.js @@ -5,9 +5,7 @@ const dotenv = require("dotenv"); dotenv.config(); const stringSimilarity = require("string-similarity"); -const bcrypt = require("bcrypt"); const inititalWebRoute = require("./route/web"); -const { authenticateToken } = require("./middleware/auth"); // Nhận mảng message đầu vào, trả về mảng message đã loại bỏ trùng lặp function deduplicateErrors(errors, threshold = 0.3) { @@ -37,10 +35,17 @@ app.use(bodyParser.json()); app.use(express.static("public")); app.use(express.urlencoded({ extended: true })); +// const db = mysql.createPool({ +// host: "localhost", +// user: "admin", +// password: "Work1234", +// database: "log_analysis", +// }); + const db = mysql.createPool({ host: "localhost", - user: "admin", - password: "Work1234", + user: "root", + password: "", database: "log_analysis", }); @@ -54,21 +59,6 @@ async function columnExists(table, column) { return rows[0].count > 0; } -const checkAndInsertAdminUser = async () => { - const [rows] = await db.query(`SELECT id FROM users WHERE email = ?`, [ - "admin@apactech.io", - ]); - - if (rows.length === 0) { - const hashedPassword = await bcrypt.hash("admin0312", 10); - - await db.query( - `INSERT INTO users (name, email, password) VALUES (?, ?, ?)`, - ["Admin", "admin@apactech.io", hashedPassword], - ); - } -}; - // === Tạo bảng (async () => { await db.query(` @@ -94,12 +84,25 @@ const checkAndInsertAdminUser = async () => { await db.query(`ALTER TABLE devices DROP COLUMN updated_by`); } - if (!(await columnExists("devices", "updated_user"))) { + if (await columnExists("devices", "updated_user")) { + await db.query( + `ALTER TABLE devices DROP FOREIGN KEY fk_updated_by_user`, + ); + await db.query(`ALTER TABLE devices DROP COLUMN updated_user`); + } + + if (!(await columnExists("devices", "update_name"))) { await db.query(` - ALTER TABLE devices - ADD COLUMN updated_user INT DEFAULT NULL, - ADD CONSTRAINT fk_updated_by_user FOREIGN KEY (updated_user) REFERENCES users(id) ON DELETE SET NULL ON UPDATE CASCADE - `); + ALTER TABLE devices + ADD COLUMN update_name VARCHAR(255) + `); + } + + if (!(await columnExists("devices", "update_email"))) { + await db.query(` + ALTER TABLE devices + ADD COLUMN update_email VARCHAR(255) + `); } if (!(await columnExists("devices", "is_confirmed"))) { @@ -121,9 +124,9 @@ const checkAndInsertAdminUser = async () => { ) `); - if (!(await columnExists(`${command}_outputs`, "is_deleted"))) { + if (await columnExists(`${command}_outputs`, "is_deleted")) { await db.query( - `ALTER TABLE ${command}_outputs ADD COLUMN is_deleted BOOLEAN DEFAULT FALSE`, + `ALTER TABLE ${command}_outputs DROP COLUMN is_deleted`, ); } }; @@ -134,18 +137,8 @@ const checkAndInsertAdminUser = async () => { await createOutputTable("logging"); await db.query(` - CREATE TABLE IF NOT EXISTS users ( - id INT AUTO_INCREMENT PRIMARY KEY, - name VARCHAR(100) NOT NULL, - email VARCHAR(100) NOT NULL UNIQUE, - password VARCHAR(255) NOT NULL, - confirm_count INT DEFAULT 0, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP - ) + DROP TABLE IF EXISTS users `); - - await checkAndInsertAdminUser(); })(); // === APIs === @@ -162,7 +155,7 @@ app.get("/api/pid/:pid/versions", async (req, res) => { // Lấy danh sách các version tương ứng với PID const [devices] = await db.query( - "SELECT id, version, updated_user FROM devices WHERE pid = ?", + "SELECT id, version, update_name FROM devices WHERE pid = ?", [pid], ); @@ -171,12 +164,7 @@ app.get("/api/pid/:pid/versions", async (req, res) => { for (const device of devices) { const deviceId = device.id; const version = device.version; - const userId = device.updated_user; - const [user] = await db.query( - "SELECT id, name FROM users WHERE id = ?", - [userId], - ); const [[inv]] = await db.query( "SELECT COUNT(*) AS c FROM inventory_outputs WHERE device_id = ?", [deviceId], @@ -195,7 +183,7 @@ app.get("/api/pid/:pid/versions", async (req, res) => { ); results.push({ - user: user[0], + user: device.update_name, version, commands: { inventory: inv.c, @@ -219,16 +207,15 @@ app.get("/api/device/:pid/:version/:command", async (req, res) => { if (!device) return res.status(404).json({ message: "Not found" }); const [logs] = await db.query( - `SELECT id, filename, output, created_at, is_deleted FROM ${command}_outputs WHERE device_id = ? ORDER BY created_at DESC`, + `SELECT id, filename, output, created_at FROM ${command}_outputs WHERE device_id = ? ORDER BY created_at DESC`, [device.id], ); res.json(logs); }); -app.post("/api/confirm-device", authenticateToken, async (req, res) => { - const { pid, version, deletedLogs } = req.body; - const updatedBy = req.user?.id; +app.post("/api/confirm-device", async (req, res) => { + const { pid, version, deletedLogs, name, email } = req.body; if (!pid || !version) { return res.status(400).json({ @@ -263,9 +250,10 @@ app.post("/api/confirm-device", authenticateToken, async (req, res) => { `UPDATE devices SET is_confirmed = true, updated_at = CURRENT_TIMESTAMP, - updated_user = ? + update_name = ?, + update_email = ? WHERE pid = ? AND version = ?`, - [updatedBy, pid, version], + [name, email, pid, version], ); // Delete Log @@ -297,11 +285,6 @@ app.post("/api/confirm-device", authenticateToken, async (req, res) => { ]); } - await db.query( - "UPDATE users SET confirm_count = confirm_count + 1 WHERE id = ?", - [updatedBy], - ); - res.json({ success: true, message: "Device confirmed successfully!", @@ -315,6 +298,26 @@ app.post("/api/confirm-device", authenticateToken, async (req, res) => { } }); +app.post("/api/confirm-count", async (req, res) => { + try { + const { email } = req.body; + + if (!email) { + return res.status(400).json({ error: "Email is required" }); + } + + const [[result]] = await db.query( + "SELECT COUNT(*) AS c FROM devices WHERE update_email = ?", + [email], + ); + + res.json({ count: result.c }); + } catch (err) { + console.error("Error fetching confirm count:", err); + res.status(500).json({ error: "Internal server error" }); + } +}); + // Danh sách regex lọc lỗi const errorPatterns = [ {