GWM : cookies

This commit is contained in:
Gowtham M 2025-12-04 17:28:33 +05:30
parent 4a99233ea1
commit 510fc030ec
7 changed files with 115 additions and 14 deletions

View File

@ -1637,8 +1637,18 @@ exports.establishmentBulkUpload = async (req, res) => {
exports.downloadCompanyProfileSample = async (req, res) => {
try {
const filePath = path.join(__dirname, "../uploads/company_profile_upload_sample.csv");
return res.download(filePath, "company_profile_upload_sample.csv");
const safeBasePath = path.resolve(__dirname, "../uploads");
const safeFilePath = path.join(safeBasePath, "company_profile_upload_sample.csv");
// Verify file exists BEFORE sending
if (!fs.existsSync(safeFilePath)) {
return res.status(404).send({
status: "failed",
message: "File not found",
});
}
return res.download(safeFilePath, "unit_master_sample.csv");
} catch (error) {
return res.status(500).send({ status: "failed", message: error.message });
}

View File

@ -179,7 +179,7 @@ exports.uploadUnitMasterFromCSV = async (req, res) => {
if (!req.file)
return res.status(400).send({ status: "failed", message: "No file uploaded." });
const filePath = req.file.path;
const filePath = path.resolve(req.file.path);
// Validate file type
if (!req.file.originalname.endsWith(".csv")) {
@ -431,7 +431,7 @@ exports.uploadUnitMasterFromCSV = async (req, res) => {
});
} catch (error) {
console.error("Error uploading Unit Master CSV:", error);
if (req.file && fs.existsSync(req.file.path)) fs.unlinkSync(req.file.path);
if (req.file && fs.existsSync(path.resolve(req.file.path))) fs.unlinkSync(path.resolve(req.file.path));
return res.status(500).send({
status: "failed",
message: "Error processing CSV file.",
@ -440,11 +440,33 @@ exports.uploadUnitMasterFromCSV = async (req, res) => {
}
};
// exports.downloadUnitMasterFile = async (req, res) => {
// try {
// const filePath = path.join(__dirname, "../uploads/unit_master_sample.csv");
// return res.download(filePath, "unit_master_sample.csv");
// } catch (error) {
// return res.status(500).send({ status: "failed", message: error.message });
// }
// };
exports.downloadUnitMasterFile = async (req, res) => {
try {
const filePath = path.join(__dirname, "../uploads/unit_master_sample.csv");
return res.download(filePath, "unit_master_sample.csv");
const safeBasePath = path.resolve(__dirname, "../uploads");
const safeFilePath = path.join(safeBasePath, "unit_master_sample.csv");
// Verify file exists BEFORE sending
if (!fs.existsSync(safeFilePath)) {
return res.status(404).send({
status: "failed",
message: "File not found",
});
}
return res.download(safeFilePath, "unit_master_sample.csv");
} catch (error) {
return res.status(500).send({ status: "failed", message: error.message });
return res.status(500).send({
status: "failed",
message: error.message,
});
}
};
};

View File

@ -17,7 +17,7 @@ exports.createUser = async (req, res) => {
logger.info(`User created: ${email}`);
res.status(201).send({'status':"success",'message':"created successfully",'data': user });
res.status(201).send({'status':"success",'message':"created successfully" });
} catch (err) {
logger.error(err.message);

View File

@ -64,7 +64,31 @@ module.exports = (sequelize, DataTypes) => {
{
timestamps: false,
tableName: "establishment_users",
}
},
{
// 1. EXCLUDE sensitive fields from all queries
defaultScope: {
attributes: { exclude: ["password", "reset_otp", "reset_otp_expires_at"] },
},
// 2. Ensure manual selections still hide sensitive fields
scopes: {
withSensitive: {
attributes: { include: ["password", "reset_otp", "reset_otp_expires_at"] },
},
},
// 3. Remove sensitive fields when converting to JSON
instanceMethods: {
toJSON() {
const values = { ...this.get() };
delete values.password;
delete values.reset_otp;
delete values.reset_otp_expires_at;
return values;
},
},
}
);
EstablishmentUser.associate = (models) => {

View File

@ -34,7 +34,32 @@ module.exports = (sequelize, DataTypes) => {
type: DataTypes.BOOLEAN,
defaultValue: true,
},
});
},
{
// 1. EXCLUDE sensitive fields from all queries
defaultScope: {
attributes: { exclude: ["password", "reset_otp", "reset_otp_expires_at"] },
},
// 2. Ensure manual selections still hide sensitive fields
scopes: {
withSensitive: {
attributes: { include: ["password", "reset_otp", "reset_otp_expires_at"] },
},
},
// 3. Remove sensitive fields when converting to JSON
instanceMethods: {
toJSON() {
const values = { ...this.get() };
delete values.password;
delete values.reset_otp;
delete values.reset_otp_expires_at;
return values;
},
},
}
);
return User;
};

View File

@ -23,9 +23,12 @@ function sanitizeValue(value) {
return value; // numbers, booleans, null
}
module.exports = function sanitizeInput(req, res, next) {
if (req.body) {
req.body = sanitizeValue(req.body);
}
if (req.body) req.body = sanitizeValue(req.body);
if (req.query) req.query = sanitizeValue(req.query);
if (req.params) req.params = sanitizeValue(req.params);
next();
};

View File

@ -21,6 +21,23 @@ app.use(
contentSecurityPolicy: false,
})
);
// prevent framing (clickjacking protection)
app.use(
helmet.frameguard({
action: "deny",
})
);
// Add HSTS explicitly (fixes scanner warning)
if (process.env.NODE_ENV === "production") {
app.use(
helmet.hsts({
maxAge: 31536000, // 1 year
includeSubDomains: true,
preload: true,
})
);
}
app.use(morgan("dev"));
app.use(sanitizeInput);