diff --git a/app/controllers/auth.controller.js b/app/controllers/auth.controller.js index 5ad086b..5088191 100644 --- a/app/controllers/auth.controller.js +++ b/app/controllers/auth.controller.js @@ -41,7 +41,7 @@ exports.login = async (req, res) => { // Check password const validPass = await bcrypt.compare(password, userData.password); if (!validPass) { - return res.status(401).json({ status: "failed", message: "Invalid password", data: "" }); + return res.status(401).json({ status: "failed", message: "Invalid password" }); } // Prepare token data @@ -115,62 +115,41 @@ exports.logout = (req, res) => { }); }; - // 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': ""}); + return res.status(400).send({ + status: "error", + code: "MISSING_FIELDS", + message: "All fields are required", + data: "" + }); const existing = await User.findOne({ where: { email } }); - if (existing) res.status(400).send({'status':"failed",'message':"Email already used",'data': ""}); - + if (existing) { + return res.status(400).send({ + status: "error", + code: "EMAIL_IN_USE", + message: "Email already used", + data: "" + }); + } const hashedPassword = await bcrypt.hash(password, 10); const newUser = await User.create({ name, email, password: hashedPassword }); + return res.status(201).send({ + status: "ok", + code: "REGISTERED", + message: "User registered successfully", + data: newUser + }); - res.status(201).send({'status':"success",'message':"User registered successfully",'data': newUser }); } catch (err) { - res.status(500).send({'status':"failed",'message':err.message }); + return res.status(500).send({ + status: "error", + code: "SERVER_ERROR", + message: "An unexpected error occurred" + }); } }; - -// Login user -// exports.login = async (req, res) => { -// try { -// const { email, password } = req.body; - -// userRole = 'EstablishmentUser' -// userData = await EstablishmentUser.findOne({ where: { email, is_active : { [Op.or]: [true, 1] } } }); -// if (!userData) { -// userData = await User.findOne({ where: { email, is_active : { [Op.or]: [true, 1] } } }); -// userRole = 'Admin' -// if (!userData) res.status(404).send({'status':"failed",'message':"User not found",'data': ""}); -// } - - -// const validPass = await bcrypt.compare(password, userData.password); -// if (!validPass) res.status(401).send({'status':"failed",'message':"Invalid password",'data': ""}); - - -// if(userRole == 'Admin') -// { -// tokenData = { id: userData.id, email: userData.email , name: userData.name , role : userRole , last_login : userData.last_login } -// await User.update({ last_login : Date() }, { where: { id: userData.id } }); -// }else{ -// const establishment_data = await Establishment.findByPk(userData.establishment_id); -// tokenData = { id: userData.id, email: userData.email , name: userData.name , role : userRole , establishment_id: userData.establishment_id , establishment_data , last_login : userData.last_login } -// await EstablishmentUser.update({ last_login : Date(), updated_at: new Date() }, { where: { id: userData.id } }); -// } - -// const token = jwt.sign(tokenData, process.env.JWT_SECRET, { -// expiresIn: "6h", -// }); - -// res.status(200).send({'status':"success",'message':"Login successful",'data': token }); - -// } catch (err) { -// res.status(500).send({'status':"failed",'message':err.message }); -// } -// }; - diff --git a/app/controllers/establishment.controller.js b/app/controllers/establishment.controller.js index 1c7ed53..7626663 100644 --- a/app/controllers/establishment.controller.js +++ b/app/controllers/establishment.controller.js @@ -18,15 +18,16 @@ const csv = require("csv-parser"); const path = require("path"); const { version } = require("os"); const sequelize = db.sequelize; +const sanitizeForLog = require("../utils/sanitizeLog"); exports.testEmail = async (req, res) => { placeHolderData = { contact_name : 'Gowtham', portal_url : process.env.FE_BASE_URL, - username : '--', - password : '--', - support_email : '--', - support_phone : '--', + username: 'test_user', + password: 'Test@123!', + support_email : process.env.SUPPORT_EMAIL, + support_phone : process.env.SUPPORT_PHONE, } await sendEmailService('gowthamceline46@gmail.com', 'establishment_user_creation_to_user', placeHolderData); @@ -1026,7 +1027,9 @@ exports.forgotPasswordRequestOTP = async (req, res) => { `

Dear ${adminUser.name},

Your OTP for password reset is ${otp}. It is valid for 10 minutes.

` ); } - logger.info(`OTP sent to ${registered_email}`); + + const safeEmail = sanitizeForLog(registered_email); + logger.info(`OTP sent email: ${safeEmail}`); return res.status(200).json({ status: "success", @@ -1100,7 +1103,8 @@ exports.forgotPasswordVerifyOTP = async (req, res) => { } - logger.info(`Password reset successful for user=${registered_email}`); + const safeEmail = sanitizeForLog(registered_email); + logger.info(`Password reset successful for user: ${safeEmail}`); return res.status(200).json({ status: "success", diff --git a/app/controllers/establishment_user.controller.js b/app/controllers/establishment_user.controller.js index 630a3fc..37d9040 100644 --- a/app/controllers/establishment_user.controller.js +++ b/app/controllers/establishment_user.controller.js @@ -108,23 +108,39 @@ exports.changeUserPassword = async (req, res) => { // Validate inputs if (!old_password || !new_password || !confirm_password) { - return res.status(400).send({ status: "failed", message: "All password fields are required" }); + return res.status(400).send({ + status: "error", + code: "MISSING_FIELDS", + message: "All password fields are required" + }); } if (new_password !== confirm_password) { - return res.status(400).send({ status: "failed", message: "New password and confirm password do not match" }); + return res.status(400).send({ + status: "error", + code: "PASSWORD_MISMATCH", + message: "New password and confirm password do not match" + }); } // Find user const user = await EstablishmentUser.findByPk(userId); if (!user) { - return res.status(404).send({ status: "failed", message: "User not found" }); + return res.status(404).send({ + status: "error", + code: "USER_NOT_FOUND", + message: "User not found" + }); } // Verify old password const isMatch = await bcrypt.compare(old_password, user.password); if (!isMatch) { - return res.status(400).send({ status: "failed", message: "Old password is incorrect" }); + return res.status(401).send({ + status: "error", + code: "OLD_PASSWORD_INCORRECT", + message: "Old password is incorrect" + }); } // Hash and update new password @@ -134,10 +150,18 @@ exports.changeUserPassword = async (req, res) => { { where: { id: userId } } ); - return res.status(200).send({status: "success", message: "Password updated successfully",}); - + return res.status(200).send({ + status: "ok", + code: "PASSWORD_UPDATED", + message: "Password updated successfully" + }); + } catch (err) { - return res.status(500).send({ status: "failed", message: err.message }); + return res.status(500).send({ + status: "error", + code: "SERVER_ERROR", + message: "An unexpected error occurred" + }); } }; diff --git a/app/controllers/user.controller.js b/app/controllers/user.controller.js index 2c69c2f..a6e8c0c 100644 --- a/app/controllers/user.controller.js +++ b/app/controllers/user.controller.js @@ -15,9 +15,9 @@ exports.createUser = async (req, res) => { const user = await User.create({ name, email, password: hashedPassword }); - logger.info(`User created: ${email}`); + logger.info("User created successfully"); - res.status(201).send({'status':"success",'message':"created successfully" }); + res.status(201).send({'status':"success",'message':"User created successfully" }); } catch (err) { logger.error(err.message); diff --git a/app/routes/routes.js b/app/routes/routes.js index c9bd875..1e4ff50 100644 --- a/app/routes/routes.js +++ b/app/routes/routes.js @@ -131,7 +131,7 @@ const upload = multer({ dest: uploadDir }); * example: john@example.com * password: * type: string - * example: secret123 + * example: "" * responses: * 201: * description: User registered successfully @@ -166,7 +166,7 @@ router.post("/auth/admin_register",[verifySignature], authController.register); * example: john@example.com * password: * type: string - * example: secret123 + * example: "" * responses: * 201: * description: User verifyed successfully @@ -281,7 +281,9 @@ router.get("/admin_users/:id", [verifySignature, verifyToken], adminUserControll * properties: * name: { type: string } * email: { type: string } - * password: { type: string } + * password: + * type: string + * example: "" * responses: * 201: * description: created successfully @@ -388,10 +390,10 @@ router.delete("/admin_users/:id",[verifySignature, verifyToken], adminUserContro * example: "OldPassword@123" * new_password: * type: string - * example: "NewPassword@123" + * example: "ExamplePassword123!" * confirm_password: * type: string - * example: "NewPassword@123" + * example: "ExamplePassword123!" * responses: * 200: * description: Password updated successfully @@ -490,7 +492,9 @@ router.get("/testEmail", establishmentController.testEmail); * properties: * name: { type: string } * email: { type: string } - * password: { type: string } + * password: + * type: string + * example: "" * establishment_products: * type: array * items: @@ -776,7 +780,7 @@ router.post("/establishments/uploadCSV",[verifySignature, verifyToken, upload.si * example: gem@alpha.com * password: * type: string - * example: StrongPass@123 + * example: "" * gender: * type: string * example: male @@ -871,7 +875,7 @@ router.get("/establishment-users/:id",[verifySignature, verifyToken], establishm * example: gem.updated@alpha.com * password: * type: string - * example: NewPassword@123 + * example: "" * gender: * type: string * example: male @@ -920,10 +924,10 @@ router.put("/establishment-users/:id",[verifySignature, verifyToken], establishm * example: "OldPassword@123" * new_password: * type: string - * example: "NewPassword@123" + * example: "ExamplePassword123!" * confirm_password: * type: string - * example: "NewPassword@123" + * example: "ExamplePassword123!" * responses: * 200: * description: Password updated successfully @@ -971,61 +975,6 @@ router.delete("/establishment-users/:id",[verifySignature, verifyToken], establi - - - - -// /** -// * @swagger -// * /api/auth/user_login: -// * post: -// * summary: Login as establishment user -// * tags: [Establishments User Auth] -// * security: -// * - appSignature: [] -// * requestBody: -// * required: true -// * content: -// * application/json: -// * schema: -// * type: object -// * required: -// * - email -// * - password -// * properties: -// * email: -// * type: string -// * example: gem@alpha.com -// * password: -// * type: string -// * example: StrongPass@123 -// * responses: -// * 200: -// * description: Login successful -// * 400: -// * description: Missing fields -// * 401: -// * description: Invalid credentials -// * 404: -// * description: User not found -// * 500: -// * description: Server error -// */ -// router.post("/auth/user_login",[verifySignature], establishmentUserAuthController.login); - - - - - - - - - - - - - - /** * @swagger * /api/products: @@ -2670,13 +2619,13 @@ router.put("/quarterly_windows/:id",[verifySignature, verifyToken], quarterlyWin * /api/password-reset-requests: * get: * summary: Get all establishment password reset requests - * tags: [Establishment Password Reset Requests] + * tags: [Establishment Reset Requests] * security: * - appSignature: [] - * cookieAuth: [] # or bearerAuth: [] if you use Authorization header + * cookieAuth: [] * responses: * 200: - * description: List of all password reset requests + * description: List of all reset requests * 500: * description: Internal server error */ @@ -2687,11 +2636,11 @@ router.get("/password-reset-requests", establishmentController.getAllRequests); * @swagger * /api/password-reset-requests: * post: - * summary: Create a new establishment password reset request - * tags: [Establishment Password Reset Requests] + * summary: Create a new establishment reset request + * tags: [Establishment Reset Requests] * security: * - appSignature: [] - * cookieAuth: [] # or bearerAuth: [] if you use Authorization header + * cookieAuth: [] * requestBody: * required: true * content: @@ -2720,10 +2669,10 @@ router.get("/password-reset-requests", establishmentController.getAllRequests); * example: "+971501234567" * additional_notes: * type: string - * example: "Forgot credentials and need password reset." + * example: "Forgot credentials and need account reset." * responses: * 201: - * description: Password reset request created successfully + * description: Reset request created successfully * 400: * description: Validation failed or mismatch between establishment and email * 404: @@ -2740,8 +2689,8 @@ router.post("/password-reset-requests", establishmentController.createRequest); * @swagger * /api/forgot-password/request-otp: * post: - * summary: Request OTP for establishment user password reset - * tags: [Establishment Password Reset Requests] + * summary: Request OTP for establishment user pwd reset + * tags: [Establishment Pwd Reset Requests] * requestBody: * required: true * content: @@ -2756,6 +2705,7 @@ router.post("/password-reset-requests", establishmentController.createRequest); * establishment_name: { type: string, example: "ABC Industries" } * establishment_code: { type: string, example: "EST1234" } * registered_email: { type: string, example: "contact@abcindustries.com" } + * user_type: {type: string, example: "establishment_user"} * responses: * 200: * description: OTP sent successfully @@ -2791,8 +2741,8 @@ router.post("/forgot-password/request-otp", establishmentController.forgotPasswo * properties: * registered_email: { type: string, example: "contact@abcindustries.com" } * otp: { type: string, example: "123456" } - * password: { type: string, example: "NewPassword@123" } - * confirm_password: { type: string, example: "NewPassword@123" } + * password: { type: string, example: "ExamplePassword123!" } + * confirm_password: { type: string, example: "ExamplePassword123!" } * responses: * 200: * description: Password reset successfully diff --git a/app/utils/sanitizeLog.js b/app/utils/sanitizeLog.js new file mode 100644 index 0000000..9d80bea --- /dev/null +++ b/app/utils/sanitizeLog.js @@ -0,0 +1,5 @@ +module.exports = function sanitizeForLog(input) { + if (typeof input !== "string") return input; + // remove newline, carriage return, tab — prevents log forging + return input.replace(/[\r\n\t]/g, " "); +}; \ No newline at end of file