GWM : cookies
This commit is contained in:
parent
4a99233ea1
commit
510fc030ec
@ -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 });
|
||||
}
|
||||
|
||||
@ -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,
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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();
|
||||
};
|
||||
|
||||
|
||||
17
server.js
17
server.js
@ -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);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user