feat: implement comprehensive audit logging system

This commit is contained in:
nguyenvanbao
2026-02-10 16:42:35 +07:00
parent d440a04618
commit 970fcbac7d
28 changed files with 4783 additions and 2221 deletions

View File

@@ -45,6 +45,9 @@ const addBaseUrlToImages = (data, baseUrl) => {
};
const Visa = require("../models/visa");
const slugify = require("slugify");
const writeAuditLog = require("../audit/writeAuditLog");
const diffObject = require("../audit/diffObject");
const AUDIT_ACTIONS = require("../constants/auditAction");
const createSlug = (text) => {
return slugify(text, {
lower: true,
@@ -184,6 +187,15 @@ exports.update = async (req, res) => {
// Get current data
const currentData = await getVisaData();
// ✅ Capture BEFORE state
const beforeData = currentData
? JSON.parse(
JSON.stringify(
currentData.toObject ? currentData.toObject() : currentData,
),
)
: {};
// Create updated data object
const updatedData = {
...(currentData.toObject ? currentData.toObject() : currentData),
@@ -200,23 +212,37 @@ exports.update = async (req, res) => {
updatedData.hero.title = req.body.heroTitle;
}
// Check if there are changes
const hasChanges =
JSON.stringify(updatedData) !== JSON.stringify(currentData);
if (!hasChanges) {
req.flash("info_msg", "No changes were made");
return req.session.save(() => res.redirect("/admin/visa"));
}
// Update or create document
try {
let savedData;
if (currentData._id) {
await Visa.findByIdAndUpdate(currentData._id, updatedData, {
savedData = await Visa.findByIdAndUpdate(currentData._id, updatedData, {
new: true,
});
} else {
await Visa.create(updatedData);
savedData = await Visa.create(updatedData);
}
// ✅ Capture AFTER state
const afterData = JSON.parse(JSON.stringify(savedData.toObject()));
// ✅ AUDIT LOGGING - Visa Updated
const changes = diffObject(beforeData, afterData);
if (changes.length > 0) {
await writeAuditLog({
model: "Visa",
documentId: savedData._id,
action: AUDIT_ACTIONS.UPDATE_VISA,
before: beforeData,
after: afterData,
changes,
req,
});
console.log(
`✅ Audit log created for Visa update: ${changes.length} changes`,
);
} else {
console.log(" No changes detected for Visa update");
}
req.flash("success_msg", "Visa data updated successfully");
@@ -243,6 +269,11 @@ exports.addCountry = async (req, res) => {
visaData = getDefaultVisaData();
}
// ✅ Capture BEFORE state
const beforeData = JSON.parse(
JSON.stringify(visaData.toObject ? visaData.toObject() : visaData),
);
// Validate required fields
if (!req.body.name) {
return res.status(400).json({ error: "Name is required" });
@@ -305,6 +336,28 @@ exports.addCountry = async (req, res) => {
savedData = await Visa.create(updatedData);
}
// ✅ Capture AFTER state
const afterData = JSON.parse(
JSON.stringify(savedData.toObject ? savedData.toObject() : savedData),
);
// ✅ AUDIT LOGGING - Visa Country Added
const changes = diffObject(beforeData, afterData);
if (changes.length > 0) {
await writeAuditLog({
model: "Visa",
documentId: savedData._id,
action: AUDIT_ACTIONS.UPDATE_VISA,
before: beforeData,
after: afterData,
changes,
req,
});
console.log(
`✅ Audit log created for Visa country addition: ${changes.length} changes`,
);
}
console.log(`✅ Country "${newCountry.name}" added successfully`);
res.json({
success: true,
@@ -330,6 +383,11 @@ exports.updateCountry = async (req, res) => {
.json({ error: "Cấu trúc dữ liệu Visa không hợp lệ" });
}
// ✅ Capture BEFORE state
const beforeData = JSON.parse(
JSON.stringify(visaData.toObject ? visaData.toObject() : visaData),
);
// 2. Tìm index theo ID (Chuyển về Number để so sánh chính xác)
const countryIndex = visaData.hero.summaryList.findIndex(
(c) => c.id === parseInt(id),
@@ -390,10 +448,33 @@ exports.updateCountry = async (req, res) => {
visaData.markModified("hero.summaryList");
}
let savedData;
if (visaData._id) {
await visaData.save(); // Sử dụng save() trực tiếp nếu visaData là Mongoose Document
savedData = await visaData.save(); // Sử dụng save() trực tiếp nếu visaData là Mongoose Document
} else {
await Visa.create(visaData);
savedData = await Visa.create(visaData);
}
// ✅ Capture AFTER state
const afterData = JSON.parse(
JSON.stringify(savedData.toObject ? savedData.toObject() : savedData),
);
// ✅ AUDIT LOGGING - Visa Country Updated
const changes = diffObject(beforeData, afterData);
if (changes.length > 0) {
await writeAuditLog({
model: "Visa",
documentId: savedData._id,
action: AUDIT_ACTIONS.UPDATE_VISA,
before: beforeData,
after: afterData,
changes,
req,
});
console.log(
`✅ Audit log created for Visa country update: ${changes.length} changes`,
);
}
console.log(