GWM : login logic changed
This commit is contained in:
parent
423bbbb61e
commit
33780616c3
@ -7,24 +7,6 @@ const User = db.user;
|
||||
const EstablishmentUser = db.EstablishmentUser;
|
||||
const Establishment = db.Establishment;
|
||||
|
||||
// Register new user
|
||||
exports.register = async (req, res) => {
|
||||
try {
|
||||
const { name, email, password } = req.body;
|
||||
if (!name || !email || !password)
|
||||
return res.status(400).send({'status':"failed",'message':"All fields required",'data': ""});
|
||||
|
||||
const existing = await User.findOne({ where: { email } });
|
||||
if (existing) res.status(400).send({'status':"failed",'message':"Email already used",'data': ""});
|
||||
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
const newUser = await User.create({ name, email, password: hashedPassword });
|
||||
|
||||
res.status(201).send({'status':"success",'message':"User registered successfully",'data': newUser });
|
||||
} catch (err) {
|
||||
res.status(500).send({'status':"failed",'message':err.message });
|
||||
}
|
||||
};
|
||||
|
||||
//Admin user and Establishment user login
|
||||
exports.login = async (req, res) => {
|
||||
@ -91,7 +73,22 @@ exports.login = async (req, res) => {
|
||||
expiresIn: "6h",
|
||||
});
|
||||
|
||||
return res.status(200).json({ status: "success", message: "Login successful", data: token });
|
||||
// Set token in HTTP-only cookie (IMPORTANT PART)
|
||||
res.cookie("auth_token", token, {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production", // true in prod (HTTPS)
|
||||
sameSite: "lax", // or "strict" if suitable
|
||||
maxAge: 6 * 60 * 60 * 1000, // 6 hours in ms
|
||||
});
|
||||
|
||||
// Optionally return minimal user info (WITHOUT password)
|
||||
return res.status(200).json({
|
||||
status: "success",
|
||||
message: "Login successful",
|
||||
data: tokenData,
|
||||
});
|
||||
|
||||
// return res.status(200).json({ status: "success", message: "Login successful", data: token });
|
||||
|
||||
} catch (err) {
|
||||
return res.status(500).json({
|
||||
@ -101,6 +98,40 @@ exports.login = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
//logout
|
||||
exports.logout = (req, res) => {
|
||||
res.clearCookie("auth_token", {
|
||||
httpOnly: true,
|
||||
secure: process.env.NODE_ENV === "production",
|
||||
sameSite: "lax",
|
||||
});
|
||||
|
||||
return res.status(200).json({
|
||||
status: "success",
|
||||
message: "Logged out successfully",
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Register new user
|
||||
exports.register = async (req, res) => {
|
||||
try {
|
||||
const { name, email, password } = req.body;
|
||||
if (!name || !email || !password)
|
||||
return res.status(400).send({'status':"failed",'message':"All fields required",'data': ""});
|
||||
|
||||
const existing = await User.findOne({ where: { email } });
|
||||
if (existing) res.status(400).send({'status':"failed",'message':"Email already used",'data': ""});
|
||||
|
||||
const hashedPassword = await bcrypt.hash(password, 10);
|
||||
const newUser = await User.create({ name, email, password: hashedPassword });
|
||||
|
||||
res.status(201).send({'status':"success",'message':"User registered successfully",'data': newUser });
|
||||
} catch (err) {
|
||||
res.status(500).send({'status':"failed",'message':err.message });
|
||||
}
|
||||
};
|
||||
|
||||
// Login user
|
||||
// exports.login = async (req, res) => {
|
||||
// try {
|
||||
|
||||
@ -34,6 +34,20 @@ exports.testEmail = async (req, res) => {
|
||||
|
||||
exports.createEstablishment = async (req, res) => {
|
||||
try {
|
||||
|
||||
// convert empty "" → null BEFORE destructure
|
||||
[
|
||||
"establishment_code",
|
||||
"factory_name",
|
||||
"permanent_factory_code",
|
||||
"industry_code",
|
||||
"industry_code_production",
|
||||
"license_number",
|
||||
"isic_code"
|
||||
].forEach(key => {
|
||||
if (req.body[key] === "") req.body[key] = null;
|
||||
});
|
||||
|
||||
const {
|
||||
establishment_code,
|
||||
factory_name,
|
||||
@ -81,6 +95,7 @@ exports.createEstablishment = async (req, res) => {
|
||||
establishment_products
|
||||
} = req.body;
|
||||
|
||||
|
||||
// Basic Validation
|
||||
if (!establishment_code || !factory_name || !establishment_user) {
|
||||
return res.status(400).send({
|
||||
@ -585,6 +600,20 @@ exports.getEstablishmentById = async (req, res) => {
|
||||
// Update establishment
|
||||
exports.updateEstablishment = async (req, res) => {
|
||||
try {
|
||||
|
||||
// convert empty "" → null BEFORE destructure
|
||||
[
|
||||
"establishment_code",
|
||||
"factory_name",
|
||||
"permanent_factory_code",
|
||||
"industry_code",
|
||||
"industry_code_production",
|
||||
"license_number",
|
||||
"isic_code"
|
||||
].forEach(key => {
|
||||
if (req.body[key] === "") req.body[key] = null;
|
||||
});
|
||||
|
||||
const { id } = req.params;
|
||||
const { establishment_products, establishment_user, ...estData } = req.body;
|
||||
const user = await EstablishmentUser.findOne({where:{establishment_id:id}});
|
||||
|
||||
@ -1,18 +1,87 @@
|
||||
const db = require("../models");
|
||||
const NotificationTemplate = db.NotificationTemplate;
|
||||
const { sanitizeHtml } = require("../utils/sanitize");
|
||||
|
||||
// Create template
|
||||
exports.createTemplate = async (req, res) => {
|
||||
try {
|
||||
req.body.created_by = req.body.created_by || req.user.id;
|
||||
const template = await NotificationTemplate.create(req.body);
|
||||
res.status(201).send({
|
||||
|
||||
try {
|
||||
const { title , template_code, subject, body_html , created_by } = req.body;
|
||||
|
||||
if (!title || !template_code || !subject || !body_html ) {
|
||||
return res.status(400).json({
|
||||
status: "failed",
|
||||
message: "Missing required fields",
|
||||
});
|
||||
}
|
||||
|
||||
// sanitize input
|
||||
const cleanHtml = sanitizeHtml(body_html);
|
||||
|
||||
const template = await NotificationTemplate.create({
|
||||
title,
|
||||
template_code,
|
||||
subject,
|
||||
body_html: cleanHtml,
|
||||
created_by: created_by || req.user?.id || null,
|
||||
});
|
||||
|
||||
return res.status(201).json({
|
||||
status: "success",
|
||||
message: "Template created successfully",
|
||||
data: template,
|
||||
data: {
|
||||
id: template.id,
|
||||
template_code: template.template_code,
|
||||
subject: template.subject
|
||||
// DO NOT return HTML to avoid XSS
|
||||
},
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
res.status(500).send({ status: "failed", message: err.message });
|
||||
res.status(500).json({ status: "failed", message: err.message });
|
||||
}
|
||||
};
|
||||
|
||||
// Update template
|
||||
exports.updateTemplate = async (req, res) => {
|
||||
try {
|
||||
const id = req.params.id;
|
||||
|
||||
// whitelist fields
|
||||
const updateData = {};
|
||||
if (req.body.title) updateData.title = req.body.title;
|
||||
if (req.body.subject) updateData.subject = req.body.subject;
|
||||
|
||||
// sanitize HTML if provided
|
||||
if (req.body.body_html) {
|
||||
updateData.body_html = sanitizeHtml(req.body.body_html);
|
||||
}
|
||||
|
||||
updateData.updated_by = req.body.updated_by || req.user?.id || null;
|
||||
updateData.updated_at = new Date();
|
||||
|
||||
// run update
|
||||
const [updated] = await NotificationTemplate.update(updateData, {
|
||||
where: { id }
|
||||
});
|
||||
|
||||
if (!updated) {
|
||||
return res.status(404).json({
|
||||
status: "failed",
|
||||
message: "Template not found"
|
||||
});
|
||||
}
|
||||
|
||||
return res.status(200).json({
|
||||
status: "success",
|
||||
message: "Template updated successfully"
|
||||
});
|
||||
|
||||
} catch (err) {
|
||||
return res.status(500).json({
|
||||
status: "failed",
|
||||
message: err.message
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@ -49,29 +118,6 @@ exports.getTemplateById = async (req, res) => {
|
||||
}
|
||||
};
|
||||
|
||||
// Update template
|
||||
exports.updateTemplate = async (req, res) => {
|
||||
try {
|
||||
req.body.updated_by = req.body.updated_by || req.user.id;
|
||||
req.body.updated_at = req.body.updated_at || new Date();
|
||||
|
||||
const [updated] = await NotificationTemplate.update(req.body, {
|
||||
where: { id: req.params.id },
|
||||
});
|
||||
|
||||
if (!updated)
|
||||
return res
|
||||
.status(404)
|
||||
.send({ status: "failed", message: "Template not found" });
|
||||
|
||||
res
|
||||
.status(200)
|
||||
.send({ status: "success", message: "Updated successfully" });
|
||||
} catch (err) {
|
||||
res.status(500).send({ status: "failed", message: err.message });
|
||||
}
|
||||
};
|
||||
|
||||
// Delete template
|
||||
exports.deleteTemplate = async (req, res) => {
|
||||
try {
|
||||
|
||||
@ -1,15 +1,45 @@
|
||||
const jwt = require("jsonwebtoken");
|
||||
require("dotenv").config();
|
||||
|
||||
module.exports = function (req, res, next) {
|
||||
const authHeader = req.headers["authorization"];
|
||||
const token = authHeader && authHeader.split(" ")[1]; // Expect "Bearer <token>"
|
||||
// module.exports = function (req, res, next) {
|
||||
// const authHeader = req.headers["authorization"];
|
||||
// const token = authHeader && authHeader.split(" ")[1]; // Expect "Bearer <token>"
|
||||
|
||||
if (!token) return res.status(403).json({ message: "Access denied, token missing" });
|
||||
// if (!token) return res.status(403).json({ message: "Access denied, token missing" });
|
||||
|
||||
jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
|
||||
if (err) return res.status(401).json({ message: "Invalid or expired token" });
|
||||
// jwt.verify(token, process.env.JWT_SECRET, (err, decoded) => {
|
||||
// if (err) return res.status(401).json({ message: "Invalid or expired token" });
|
||||
// req.user = decoded;
|
||||
// next();
|
||||
// });
|
||||
// };
|
||||
|
||||
|
||||
const authJWT = (req, res, next) => {
|
||||
try {
|
||||
const token =
|
||||
req.cookies?.auth_token ||
|
||||
(req.headers.authorization && req.headers.authorization.split(" ")[1]);
|
||||
|
||||
if (!token) {
|
||||
return res
|
||||
.status(401)
|
||||
.json({ status: "failed", message: "Unauthorized: No token provided" });
|
||||
}
|
||||
|
||||
console.log('token ='+token)
|
||||
|
||||
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
||||
|
||||
// Attach user info to req for downstream handlers
|
||||
req.user = decoded;
|
||||
next();
|
||||
});
|
||||
} catch (err) {
|
||||
return res
|
||||
.status(401)
|
||||
.json({ status: "failed", message: "Unauthorized: Invalid token" });
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = authJWT;
|
||||
|
||||
|
||||
@ -69,6 +69,10 @@ const upload = multer({ dest: "../writable/uploads/products_bulk_uploads_files"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
* components:
|
||||
@ -201,7 +205,7 @@ router.post("/auth/login",[verifySignature], authController.login);
|
||||
* tags: [Admin Users]
|
||||
* security:
|
||||
* - appSignature: []
|
||||
* - bearerAuth: []
|
||||
* cookieAuth: [] # or bearerAuth: [] if you use Authorization header
|
||||
* responses:
|
||||
* 201:
|
||||
* description: Fetched successfully
|
||||
@ -210,7 +214,7 @@ router.post("/auth/login",[verifySignature], authController.login);
|
||||
* 500:
|
||||
* description: Server error
|
||||
*/
|
||||
router.get("/admin_users", [verifySignature, verifyToken], adminUserController.getAllUsers);
|
||||
router.get("/admin_users", [verifySignature , verifyToken], adminUserController.getAllUsers);
|
||||
|
||||
/**
|
||||
* @swagger
|
||||
|
||||
12
app/utils/sanitize.js
Normal file
12
app/utils/sanitize.js
Normal file
@ -0,0 +1,12 @@
|
||||
const sanitize = require("sanitize-html");
|
||||
|
||||
exports.sanitizeHtml = (html = "") => {
|
||||
return sanitize(html, {
|
||||
allowedTags: sanitize.defaults.allowedTags.concat(["img"]),
|
||||
allowedAttributes: {
|
||||
"*": ["style", "class"],
|
||||
img: ["src", "alt"]
|
||||
},
|
||||
disallowedTagsMode: "discard"
|
||||
});
|
||||
};
|
||||
201
package-lock.json
generated
201
package-lock.json
generated
@ -10,6 +10,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bcryptjs": "^3.0.2",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"csv-parser": "^3.2.0",
|
||||
"dotenv": "^17.2.3",
|
||||
@ -23,6 +24,7 @@
|
||||
"mysql2": "^3.15.2",
|
||||
"nodemailer": "^7.0.10",
|
||||
"nodemon": "^3.1.10",
|
||||
"sanitize-html": "^2.17.0",
|
||||
"sequelize": "^6.37.7",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"swagger-ui-express": "^5.0.1",
|
||||
@ -677,6 +679,23 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.7.tgz",
|
||||
"integrity": "sha512-nGUvgXnotP3BsjiLX2ypbQnWoGUPIIfHQNZkkC668ntrzGWEZVW70HDEB1qnNGMicPje6EttlIgzo51YSwNQGw==",
|
||||
"dependencies": {
|
||||
"cookie": "0.7.2",
|
||||
"cookie-signature": "1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-parser/node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
|
||||
@ -757,6 +776,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/denque": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz",
|
||||
@ -784,6 +811,57 @@
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/dom-serializer": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
|
||||
"integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.2",
|
||||
"entities": "^4.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domelementtype": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
|
||||
"integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/domhandler": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
|
||||
"integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domhandler?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/domutils": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
|
||||
"integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
|
||||
"dependencies": {
|
||||
"dom-serializer": "^2.0.0",
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/domutils?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "17.2.3",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz",
|
||||
@ -882,6 +960,17 @@
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/fb55/entities?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
|
||||
@ -914,6 +1003,17 @@
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
|
||||
},
|
||||
"node_modules/escape-string-regexp": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/esutils": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
|
||||
@ -1249,6 +1349,24 @@
|
||||
"node": ">=18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/htmlparser2": {
|
||||
"version": "8.0.2",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
|
||||
"integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
|
||||
"funding": [
|
||||
"https://github.com/fb55/htmlparser2?sponsor=1",
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/fb55"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"domelementtype": "^2.3.0",
|
||||
"domhandler": "^5.0.3",
|
||||
"domutils": "^3.0.1",
|
||||
"entities": "^4.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
|
||||
@ -1381,6 +1499,14 @@
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-plain-object": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
|
||||
"integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-promise": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
|
||||
@ -1942,6 +2068,23 @@
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.11",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
|
||||
"integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
|
||||
@ -2060,6 +2203,11 @@
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
|
||||
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
|
||||
},
|
||||
"node_modules/parse-srcset": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/parse-srcset/-/parse-srcset-1.0.2.tgz",
|
||||
"integrity": "sha512-/2qh0lav6CmI15FzA3i/2Bzk2zCgQhGMkvhOhKNcBVQ1ldgpbfiNTVslmooUmWJcADi1f1kIeynbDRVzNlfR6Q=="
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
@ -2090,6 +2238,11 @@
|
||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.1.tgz",
|
||||
"integrity": "sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w=="
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
@ -2101,6 +2254,33 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.5.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz",
|
||||
"integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.11",
|
||||
"picocolors": "^1.1.1",
|
||||
"source-map-js": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
@ -2289,6 +2469,19 @@
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"node_modules/sanitize-html": {
|
||||
"version": "2.17.0",
|
||||
"resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.17.0.tgz",
|
||||
"integrity": "sha512-dLAADUSS8rBwhaevT12yCezvioCA+bmUTPH/u57xKPT8d++voeYE6HeluA/bPbQ15TwDBG2ii+QZIEmYx8VdxA==",
|
||||
"dependencies": {
|
||||
"deepmerge": "^4.2.2",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"htmlparser2": "^8.0.0",
|
||||
"is-plain-object": "^5.0.0",
|
||||
"parse-srcset": "^1.0.2",
|
||||
"postcss": "^8.3.11"
|
||||
}
|
||||
},
|
||||
"node_modules/saxes": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
|
||||
@ -2509,6 +2702,14 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
|
||||
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/sqlstring": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"bcryptjs": "^3.0.2",
|
||||
"cookie-parser": "^1.4.7",
|
||||
"cors": "^2.8.5",
|
||||
"csv-parser": "^3.2.0",
|
||||
"dotenv": "^17.2.3",
|
||||
@ -25,6 +26,7 @@
|
||||
"mysql2": "^3.15.2",
|
||||
"nodemailer": "^7.0.10",
|
||||
"nodemon": "^3.1.10",
|
||||
"sanitize-html": "^2.17.0",
|
||||
"sequelize": "^6.37.7",
|
||||
"swagger-jsdoc": "^6.2.8",
|
||||
"swagger-ui-express": "^5.0.1",
|
||||
|
||||
56
server.js
56
server.js
@ -1,21 +1,52 @@
|
||||
const express = require("express");
|
||||
const cors = require("cors");
|
||||
const helmet = require("helmet");
|
||||
const helmet = require("helmet");
|
||||
const morgan = require("morgan");
|
||||
const swaggerUi = require("swagger-ui-express");
|
||||
const swaggerJsdoc = require("swagger-jsdoc");
|
||||
const routes = require("./app/routes/routes");
|
||||
const db = require("./app/models");
|
||||
const path = require("path");
|
||||
const cookieParser = require("cookie-parser");
|
||||
require("dotenv").config();
|
||||
|
||||
const app = express();
|
||||
|
||||
|
||||
app.use(express.json());
|
||||
app.use(cors());
|
||||
app.use(helmet());
|
||||
app.use(morgan("dev"));
|
||||
app.use(cookieParser());
|
||||
|
||||
// // Swagger setup
|
||||
// const swaggerOptions = {
|
||||
// definition: {
|
||||
// openapi: "3.0.0",
|
||||
// info: {
|
||||
// title: "FCSC IPI Survey",
|
||||
// version: "1.0.0",
|
||||
// description: "Federal Competitiveness and Statistics Centre (FCSC) - Industrial Production Index (IPI)",
|
||||
// },
|
||||
// components: {
|
||||
// securitySchemes: {
|
||||
// bearerAuth: {
|
||||
// type: "http",
|
||||
// scheme: "bearer",
|
||||
// bearerFormat: "JWT",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// security: [
|
||||
// {
|
||||
// bearerAuth: [],
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// apis: ["./app/routes/*.js"],
|
||||
// };
|
||||
// const swaggerDocs = swaggerJsdoc(swaggerOptions);
|
||||
// app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocs));
|
||||
// Swagger setup
|
||||
const swaggerOptions = {
|
||||
definition: {
|
||||
@ -27,23 +58,34 @@ const swaggerOptions = {
|
||||
},
|
||||
components: {
|
||||
securitySchemes: {
|
||||
// Optional: Still support Bearer for Swagger-only testing
|
||||
bearerAuth: {
|
||||
type: "http",
|
||||
scheme: "bearer",
|
||||
bearerFormat: "JWT",
|
||||
},
|
||||
appSignature: {
|
||||
type: "apiKey",
|
||||
in: "header",
|
||||
name: "x-app-signature"
|
||||
}
|
||||
},
|
||||
},
|
||||
security: [
|
||||
{
|
||||
bearerAuth: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
apis: ["./app/routes/*.js"],
|
||||
};
|
||||
|
||||
const swaggerDocs = swaggerJsdoc(swaggerOptions);
|
||||
app.use("/api-docs", swaggerUi.serve, swaggerUi.setup(swaggerDocs));
|
||||
|
||||
app.use(
|
||||
"/api-docs",
|
||||
swaggerUi.serve,
|
||||
swaggerUi.setup(swaggerDocs, {
|
||||
swaggerOptions: {
|
||||
withCredentials: true, // 🔥 VERY IMPORTANT
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
// Routes
|
||||
|
||||
Loading…
Reference in New Issue
Block a user