Repository: dude613/avoda-be
Pull request #3: Chore/constants
Author: login: dude613
Labels: name: Review effort 3/5
Created: 2025-03-14T06:02:45Z | Merged: 2025-03-19T00:35:59Z

### **PR Type**
Enhancement, Bug fix, Documentation


___

### **Description**
- Introduced email templates and constants for better modularity.

- Added Sentry for error monitoring and performance tracking.

- Refactored and modularized mailer components and user-related controllers.

- Updated project configuration, including `package.json` and environment variables.


___



### **Changes walkthrough** 📝
<table><thead><tr><th></th><th align="left">Relevant files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>11 files</summary><table>
<tr>
  <td><strong>ForgotTemplate.js</strong><dd><code>Added Forgot Password email template.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-e40d6189742341f32c1e9b8b0c3ab3d91e5db74f548ca214af52e507fc09c1eb">+37/-0</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>SendOTPMail.js</strong><dd><code>Added function to send OTP emails.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-78b74fecf8280a2e1959ac88735b77053152ed60abbfe92307901595740f1c4c">+44/-0</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>Transporter.js</strong><dd><code>Added transporter configuration for nodemailer.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-2044c2d136f62b95f1f640310eff264d0ad35ce59ed95046c5e4bf40412913b7">+13/-0</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>AppConstants.js</strong><dd><code>Added general application constants.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-5912e7c5c3570eb0ba6df6c09da83a820575be37c074b4ec7a8967d4b05f9642">+15/-0</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>MailerConstants.js</strong><dd><code>Added constants for mailer templates and content.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-7b3516454f51b7cfa01bfaab71fe4b48fb0d7d02f1634860ca0e144a11880e11">+20/-0</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>UserConstants.js</strong><dd><code>Added constants for user-related messages and validation.</code></dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-6fb9c0681022bf7452a6ccb5ccb1d5449c45a9bcb6003e5537995c4e2efebafb">+17/-0</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>ForgotPassword.js</strong><dd><code>Added Forgot Password and Set New Password controllers.</code>&nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-6df052d3ab8b576f69a32f216f5f3f30f92568552a92301a79f17ac8543346b6">+111/-0</a>&nbsp; </td>

</tr>

<tr>
  <td><strong>Register.js</strong><dd><code>Refactored OTP mail logic and removed redundant Forgot Password logic.</code></dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-33d81b5f12f742bbe7e17c594eef30d72f0445fc82e9e79a0a3c8704dfb26cbe">+2/-39</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>AuthRoute.js</strong><dd><code>Added routes for Forgot Password and Set New Password.</code>&nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-2384c5f10f2fff47150143c4b510c22b7d2dcab79f102d1ff511c0ca1f174a57">+3/-1</a>&nbsp; &nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>index.js</strong><dd><code>Integrated Sentry and refactored constants usage.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346">+28/-7</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>instrument.js</strong><dd><code>Added Sentry initialization and profiling configuration.</code>&nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-279f921830a8324a2fc3ce40f99e0301756238f7be86fc7c64e5eb47da42058f">+14/-0</a>&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Cleanup</strong></td><td><details><summary>4 files</summary><table>
<tr>
  <td><strong>OTPTemplate.js</strong><dd><code>Removed unused OTP email template.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-ec85d1a400a9dbaeae23177b4b3e994d99a3c7e8342fce5995919f88a8bcc113">+0/-23</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>VerifyEmail.js</strong><dd><code>Removed unused email verification logic.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-c5d2e741bc2726f04035ef6c64808f42c6c3fa16e97bbf4ddd851d708878bf9b">+0/-33</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>Transporter.js</strong><dd><code>Removed redundant transporter and OTP mail logic.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-8a6f5246e48179bb29c46027dc3eaf9324c3088969672ab21b5df43ea7cf1256">+0/-40</a>&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>Login.js</strong><dd><code>Removed unused OTP template logic from login controller.</code>&nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-756d62bdc8acff596abc8d111cd979b94c0035dad842bd456dda567795f82d19">+0/-7</a>&nbsp; &nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Bug fix</strong></td><td><details><summary>1 files</summary><table>
<tr>
  <td><strong>VerifyOtp.js</strong><dd><code>Updated OTP mail import path.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-16330fd18ce9a270f0393725c5b92c6f553d1a875d7dde563b536bd34edeaabf">+1/-1</a>&nbsp; &nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Configuration changes</strong></td><td><details><summary>1 files</summary><table>
<tr>
  <td><strong>package.json</strong><dd><code>Updated project name and added lint script.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-7ae45ad102eab3b6d7e7896acd08c427a9b25b346470d7bc6507b6481575d519">+7/-6</a>&nbsp; &nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>1 files</summary><table>
<tr>
  <td><strong>sample.env</strong><dd><code>Added sample environment variables.</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
  <td><a href="https://github.com/dude613/avoda-be/pull/3/files#diff-b80385df109d2e96812772e7905b6d846a851623b7261d35480bdb4e83a009d0">+2/-0</a>&nbsp; &nbsp; &nbsp; </td>

</tr>
</table></details></td></tr></tr></tbody></table>

___

> <details> <summary>  Need help?</summary><li>Type <code>/help how to ...</code> in the comments thread for any questions about Qodo Merge usage.</li><li>Check out the <a href="https://qodo-merge-docs.qodo.ai/usage-guide/">documentation</a> for more information.</li></details>


Diff:
diff --git a/Components/MailerComponents/ForgotTemplate.js b/Components/MailerComponents/ForgotTemplate.js
new file mode 100644
index 0000000..537c2f7
--- /dev/null
+++ b/Components/MailerComponents/ForgotTemplate.js
@@ -0,0 +1,37 @@
+import nodemailer from "nodemailer";
+import dotenv from "dotenv";
+import { transporter } from "./Transporter.js";
+import {
+    PASSWORD_RESET_REQUEST_HEADING,
+    RESET_PASSWORD_LINK_TEXT,
+    RESET_PASSWORD_BUTTON_TEXT,
+    IGNORE_RESET_EMAIL_MESSAGE,
+    RESET_YOUR_PASSWORD_SUBJECT,
+    EMAIL_SENT_SUCCESSFULLY_MESSAGE
+} from "../../Constants/MailerConstants.js";
+dotenv.config();
+
+export async function ForgotTemplate(email, resetLink) {
+    try {
+        const emailContent = `
+            <div style="font-family: Arial, sans-serif; line-height: 1.5;">
+                <h2>${PASSWORD_RESET_REQUEST_HEADING}</h2>
+                <p>${RESET_PASSWORD_LINK_TEXT}</p>
+                <p><a href="${resetLink}" style="display:inline-block; padding:10px 20px; color:#fff; background-color:#007BFF; text-decoration:none; border-radius:5px;">${RESET_PASSWORD_BUTTON_TEXT}</a></p>
+                <p>${IGNORE_RESET_EMAIL_MESSAGE}</p>
+            </div>
+        `;
+
+        const mailOptions = {
+            from: process.env.EMAIL_USER,
+            to: email,
+            subject: RESET_YOUR_PASSWORD_SUBJECT,
+            html: emailContent,
+        };
+
+        const info = await transporter.sendMail(mailOptions);
+        return { success: true, message: EMAIL_SENT_SUCCESSFULLY_MESSAGE };
+    } catch (error) {
+        return { success: false, error: error.message };
+    }
+}
diff --git a/Components/MailerComponents/OTPTemplate.js b/Components/MailerComponents/OTPTemplate.js
deleted file mode 100644
index 7753330..0000000
--- a/Components/MailerComponents/OTPTemplate.js
+++ /dev/null
@@ -1,23 +0,0 @@
-export function OTPTemplate(fullName, otp) {
-    console.log(fullName, otp);
-    return `
-   <html>
-    <head>
-    <title>OTP Verification</title>
-    
-    </head>
-    <body>
-      <div class="container">
-        <p>Dear <strong>${fullName}</strong>,</p>
-        <p>Welcome to Orlian Services!</p>
-        <p>To complete your registration and verify your account, please enter the following One-Time Password (OTP) on the verification page:</p>
-        <h3>Your OTP Code: <strong>${otp}</strong></h3>
-        <p>This code is valid for the next <strong>10 minutes</strong>. Please make sure to use it before it expires.</p>
-        <p>If you did not request this, please disregard this email.</p>
-        <p>Thank you for joining Eco Fleet Services! We are excited to have you on board.</p>
-        <p class="footer">Best regards,<br>The Orlian Services Team</p>
-      </div>
-    </body>
-  </html>
-   `;
-  }
\ No newline at end of file
diff --git a/Components/MailerComponents/SendOTPMail.js b/Components/MailerComponents/SendOTPMail.js
new file mode 100644
index 0000000..12f4665
--- /dev/null
+++ b/Components/MailerComponents/SendOTPMail.js
@@ -0,0 +1,45 @@
+import nodemailer from "nodemailer";
+import { transporter } from "./Transporter.js";
+import dotenv from "dotenv";
+import {
+  EMAIL_VERIFICATION_HEADING,
+  OTP_MESSAGE,
+  OTP_EXPIRATION_PREFIX,
+  OTP_EXPIRATION_SUFFIX,
+  VERIFY_EMAIL_SUBJECT,
+  IGNORE_EMAIL_MESSAGE,
+  VERIFY_EMAIL_BUTTON_TEXT,
+  VERIFICATION_LINK_BASE
+} from "../../Constants/MailerConstants.js";
+dotenv.config();
+
+
+
+export async function SendOTPInMail(otp, toEmail) {
+  try {
+    const verificationLink = `${VERIFICATION_LINK_BASE}?email=${encodeURIComponent(
+      toEmail
+    )}&otp=${otp}`;
+    const emailContent = `
+          <h2>${EMAIL_VERIFICATION_HEADING}</h2>
+          <p>${OTP_MESSAGE}<strong>${otp}</strong></p>
+          <p>${OTP_EXPIRATION_PREFIX}<strong>30${OTP_EXPIRATION_SUFFIX}</strong>.</p>
+          <a href="${verificationLink}" style="padding: 10px 15px; background-color: blue; color: white; text-decoration: none; border-radius: 5px;">
+            ${VERIFY_EMAIL_BUTTON_TEXT}
+          </a>
+          <p>${IGNORE_EMAIL_MESSAGE}</p>
+        `;
+
+    const mailOptions = {
+      from: process.env.EMAIL_USER,
+      to: toEmail,
+      subject: VERIFY_EMAIL_SUBJECT,
+      html: emailContent,
+    };
+
+    await transporter.sendMail(mailOptions);
+    return { success: true };
+  } catch (e) {
+    return { success: false, error: e.message };
+  }
+}
diff --git a/Components/MailerComponents/Transporter.js b/Components/MailerComponents/Transporter.js
new file mode 100644
index 0000000..738c54d
--- /dev/null
+++ b/Components/MailerComponents/Transporter.js
@@ -0,0 +1,13 @@
+import nodemailer from "nodemailer";
+import dotenv from "dotenv";
+dotenv.config();
+
+export const transporter = nodemailer.createTransport({
+  service: "gmail",
+  auth: {
+    user: process.env.EMAIL_USER,
+    pass: process.env.EMAIL_PASS,
+  },
+});
+
+
diff --git a/Components/MailerComponents/VerifyEmail.js b/Components/MailerComponents/VerifyEmail.js
deleted file mode 100644
index de4c9d0..0000000
--- a/Components/MailerComponents/VerifyEmail.js
+++ /dev/null
@@ -1,33 +0,0 @@
-import UserSchema from "../../Model/UserSchema.js";
-
-
-export async function VerifyEmail(req, res) {
-  const code = req.params.code;
-  const userId = req.user?.userId;
-  if (!code) {
-    return res.status(403).send({ error: "Access denied, no code provided!" });
-  }
-  try {
-    const user = await UserSchema.find({ userId });
-    if (!user) {
-      return res.status(404).send({ success: false, error: "User not Register in database!" });
-    }
-  
-      return res
-        .status(201)
-        .send({ success: true, error: "Already verified!" });
-    const codeMatches = user.some((userObj) => userObj.code === code);
-    if (codeMatches) {
-      res.status(200).send({ success: true, error: "", msg: "Verified" });
-    } else {
-      return res.status(403).send({
-        success: false,
-        error: "Access denied, invalid code provided!",
-      });
-    }
-  } catch (error) {
-    res.status(400).send({ success: false, error: "Invalid or expired code!" });
-  }
-}
-
-
diff --git a/Components/Transporter.js b/Components/Transporter.js
deleted file mode 100644
index b95c04d..0000000
--- a/Components/Transporter.js
+++ /dev/null
@@ -1,40 +0,0 @@
-import nodemailer from "nodemailer";
-import dotenv from "dotenv";
-dotenv.config();
-
-export const transporter = nodemailer.createTransport({
-  service: "gmail",
-  auth: {
-    user: process.env.EMAIL_USER,
-    pass: process.env.EMAIL_PASS,
-  },
-});
-
-export async function SendOTPInMail(otp, toEmail) {
-  try {
-    const verificationLink = `http://localhost:5173/register/verifyCode?email=${encodeURIComponent(
-      toEmail
-    )}&otp=${otp}`;
-    const emailContent = `
-        <h2>Email Verification</h2>
-        <p>Your OTP code is: <strong>${otp}</strong></p>
-        <p>This OTP will expire in <strong>30 minutes</strong>.</p>
-        <p>Click the button below to verify your email:</p>
-        <a href="${verificationLink}" style="padding: 10px 15px; background-color: blue; color: white; text-decoration: none; border-radius: 5px;">
-          Verify Email
-        </a>
-        <p>If you didn't request this, please ignore this email.</p>
-      `;
-
-    const mailOptions = {
-      from: process.env.EMAIL_USER,
-      to: toEmail,
-      subject: "Verify Your Email",
-      html: emailContent,
-    };
-
-    await transporter.sendMail(mailOptions);
-  } catch (e) {
-    return;
-  }
-}
diff --git a/Constants/AppConstants.js b/Constants/AppConstants.js
new file mode 100644
index 0000000..407f5fc
--- /dev/null
+++ b/Constants/AppConstants.js
@@ -0,0 +1,15 @@
+// General application constants
+
+// Server messages
+export const SERVER_WORKING_MESSAGE = "Server working";
+
+// URL constants
+export const BASE_URL = "http://localhost";
+
+// Socket.io events
+export const SOCKET_CONNECTION_EVENT = "connection";
+export const SOCKET_MESSAGE_EVENT = "message";
+export const SOCKET_DISCONNECT_EVENT = "disconnect";
+
+// API routes
+export const API_BASE_ROUTE = "/api";
diff --git a/Constants/MailerConstants.js b/Constants/MailerConstants.js
new file mode 100644
index 0000000..40f3b42
--- /dev/null
+++ b/Constants/MailerConstants.js
@@ -0,0 +1,20 @@
+// Constants related to email templates and content
+
+// Email verification constants
+export const EMAIL_VERIFICATION_HEADING = "Email Verification";
+export const OTP_MESSAGE = "Your OTP code is: ";
+export const OTP_EXPIRATION_PREFIX = "This OTP will expire in ";
+export const OTP_EXPIRATION_SUFFIX = " minutes";
+export const VERIFY_EMAIL_SUBJECT = "Verify Your Email";
+export const IGNORE_EMAIL_MESSAGE = "If you didn't request this, please ignore this email.";
+export const VERIFY_EMAIL_BUTTON_TEXT = "Verify Email";
+export const VERIFICATION_LINK_BASE = "http://localhost:5173/register/verifyCode";
+
+// Password reset constants
+export const PASSWORD_RESET_REQUEST_HEADING = "Password Reset Request";
+export const RESET_PASSWORD_LINK_TEXT = "Click the link below to reset your password:";
+export const RESET_PASSWORD_BUTTON_TEXT = "Reset Password";
+export const IGNORE_RESET_EMAIL_MESSAGE = "If you did not make this request, you can ignore this email.";
+export const RESET_YOUR_PASSWORD_SUBJECT = "Reset Your Password";
+export const EMAIL_SENT_SUCCESSFULLY_MESSAGE = "Email sent successfully.";
+export const RESET_LINK_BASE = "http://localhost:5173/new-password";
diff --git a/Constants/UserConstants.js b/Constants/UserConstants.js
new file mode 100644
index 0000000..66759a6
--- /dev/null
+++ b/Constants/UserConstants.js
@@ -0,0 +1,17 @@
+// Constants related to user actions and messages
+
+// Error messages
+export const EMAIL_NOT_FOUND_ERROR = "This email doesn't exist in our database. Please try another email.";
+export const EMAIL_REQUIRED_ERROR = "email is required!";
+export const INVALID_EMAIL_FORMAT_ERROR = "Invalid email format!";
+export const PASSWORD_REQUIRED_ERROR = "Password is required!";
+export const PASSWORD_COMPLEXITY_ERROR = "Password must be at least 8 characters long, include an uppercase letter, a number, and a special character.";
+export const GENERIC_ERROR_MESSAGE = "An error occurred while processing your request.";
+
+// Success messages
+export const PASSWORD_RESET_EMAIL_SENT = "A password reset link has been sent to your email. Please check your inbox and follow the instructions to reset your password.";
+export const PASSWORD_UPDATED_SUCCESS = "Password updated successfully!";
+
+// Regex patterns
+export const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
+export const PASSWORD_REGEX = /^(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
diff --git a/Controller/User/ForgotPassword.js b/Controller/User/ForgotPassword.js
new file mode 100644
index 0000000..8dd9e9c
--- /dev/null
+++ b/Controller/User/ForgotPassword.js
@@ -0,0 +1,112 @@
+import UserSchema from "../../Model/UserSchema.js";
+import dotenv from "dotenv";
+import crypto from "crypto";
+import { OAuth2Client } from "google-auth-library";
+import { ForgotTemplate } from "../../Components/MailerComponents/ForgotTemplate.js";
+import {
+    EMAIL_NOT_FOUND_ERROR,
+    EMAIL_REQUIRED_ERROR,
+    INVALID_EMAIL_FORMAT_ERROR,
+    PASSWORD_REQUIRED_ERROR,
+    PASSWORD_COMPLEXITY_ERROR,
+    GENERIC_ERROR_MESSAGE,
+    PASSWORD_RESET_EMAIL_SENT,
+    PASSWORD_UPDATED_SUCCESS,
+    EMAIL_REGEX,
+    PASSWORD_REGEX
+} from "../../Constants/UserConstants.js";
+import { RESET_LINK_BASE } from "../../Constants/MailerConstants.js";
+
+
+dotenv.config();
+const CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
+const AUTH_URL = process.env.AUTH_URL;
+const client = new OAuth2Client(CLIENT_ID);
+const FRONTEND_URL = process.env.FRONTEND_URL;
+
+
+export async function ForgotPasswordMail(req, res) {
+    try {
+        const { email } = req.body;
+        const validationResponse = validate(req, res);
+        if (validationResponse !== true) {
+            return;
+        }
+        const user = await UserSchema.findOne({ email });
+        if (!user) {
+            return res.status(404).json({ success: false, error: EMAIL_NOT_FOUND_ERROR });
+        }
+        const resetToken = crypto.randomBytes(32).toString("hex");
+        const expiryTime = Date.now() + 15 * 60 * 1000;
+
+        await UserSchema.findOneAndUpdate(
+            { email },
+            {
+                $set: {
+                    resetPasswordToken: resetToken,
+                    resetPasswordExpires: expiryTime,
+                },
+            },
+            { upsert: true, new: true }
+        );
+        const resetLink = `${RESET_LINK_BASE}?email=${encodeURIComponent(email)}&token=${resetToken}`;
+        const decodedLink = decodeURIComponent(resetLink);
+        await ForgotTemplate(email, decodedLink);
+        res.status(200).send({ success: true, message: PASSWORD_RESET_EMAIL_SENT })
+        setTimeout(async () => {
+            await UserSchema.updateOne(
+                { email, resetPasswordExpires: { $lt: Date.now() } },
+                { $unset: { resetPasswordToken: 1, resetPasswordExpires: 1 } }
+            );
+        }, 15 * 60 * 1000);
+    } catch (error) {
+        console.log("error message forgot password:::", error.message);
+        res.status(500).json({ success: false, error: error.message || GENERIC_ERROR_MESSAGE });
+    }
+}
+
+const validate = (req, res) => {
+    const { email } = req.body;
+    if (!email) {
+        return res
+            .status(400)
+            .send({ success: false, error: EMAIL_REQUIRED_ERROR });
+    }
+    if (!EMAIL_REGEX.test(email)) {
+        return res
+            .status(400)
+            .send({ success: false, error: INVALID_EMAIL_FORMAT_ERROR });
+    }
+    return true;
+};
+
+export async function SetNewPassword(req, res) {
+    try {
+        const { email, password } = req.body;
+
+        const validationResponse = validate(req, res);
+        if (validationResponse !== true) {
+            return;
+        }
+
+        if (!password) {
+            return res.status(404).send({ success: false, error: PASSWORD_REQUIRED_ERROR });
+        }
+        if (!PASSWORD_REGEX.test(password)) {
+            return res.status(404).send({ success: false, error: PASSWORD_COMPLEXITY_ERROR })
+        }
+
+        const user = await UserSchema.findOne({ email });
+        if (!user) {
+            return res.status(404).json({ success: false, error: EMAIL_NOT_FOUND_ERROR });
+        }
+
+        user.password = password;
+        await user.save();
+
+        return res.status(200).json({ success: true, message: PASSWORD_UPDATED_SUCCESS });
+    } catch (error) {
+        console.log("error set new password:::", error.message);
+        return res.status(500).json({ success: false, error: GENERIC_ERROR_MESSAGE });
+    }
+}
diff --git a/Controller/User/Login.js b/Controller/User/Login.js
index f81f04b..2be2e3d 100644
--- a/Controller/User/Login.js
+++ b/Controller/User/Login.js
@@ -8,7 +8,6 @@ import {
   generateAccessToken,
   generateRefreshToken,
 } from "../../Components/VerfiyAccessToken.js";
-import { OTPTemplate } from "../../Components/MailerComponents/OTPTemplate.js";
 
 const CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
 const AUTH_URL = process.env.AUTH_URL;
@@ -53,12 +52,6 @@ export async function Login(req, res) {
 
     const fullName = `${user.firstName} ${user.lastName}`.trim();
 
-    // await SendOTPInMail({
-    //     to: email,
-    //     subject: "Your OTP",
-    //     message: OTPTemplate(fullName, otp, user),
-    // });
-
     res.status(201).send({
       success: true,
       message: "OTP has been successfully sent to your email address.",
diff --git a/Controller/User/Register.js b/Controller/User/Register.js
index c0d6611..0dfaf4e 100644
--- a/Controller/User/Register.js
+++ b/Controller/User/Register.js
@@ -5,9 +5,10 @@ import {
   generateAccessToken,
   generateRefreshToken,
 } from "../../Components/VerfiyAccessToken.js";
-import { SendOTPInMail } from "../../Components/Transporter.js";
 import UserSchema from "../../Model/UserSchema.js";
 import UserOtpSchema from "../../Model/UserOtpSchema.js";
+import { SendOTPInMail } from "../../Components/MailerComponents/SendOTPMail.js";
+
 
 dotenv.config();
 const CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
@@ -123,44 +124,6 @@ const validate = (req, res) => {
   return true;
 };
 
-
-export async function ForgotPasswordMail(req, res) {
-  try {
-    const { email} = req.body;
-    const validationResponse = validate(req, res);
-    if (validationResponse !== true) {
-      return;
-    }
-    let user = await UserSchema.findOne({ email });
-
-    if (user) {
-      return res.status(400).send({
-        success: false,
-        error:
-          "This email is already registered. Please use a different email!",
-      });
-    }
-    user = new UserSchema({ email, password });
-    await user.save();
-
-    const otp = crypto.randomInt(100000, 999999).toString();
-    const otpExpiration = new Date(Date.now() + 30 * 60 * 1000);
-    await UserOtpSchema.findOneAndUpdate(
-      { userId: user._id },
-      { otp, expiresAt: otpExpiration },
-      { upsert: true, new: true }
-    );
-    await SendOTPInMail(otp, email);
-    res.status(201).send({
-      success: true,
-      message: "User registered successfully!",
-    });
-  } catch (error) {
-    console.log("User Register Error:", error.message);
-    return res.status(500).json({ success: false, error: error.message });
-  }
-}
-
 export async function ResetPassword(req, res) {
   try {
     const { email, password } = req.body;
diff --git a/Controller/User/VerifyOtp.js b/Controller/User/VerifyOtp.js
index 11f6f34..447f77f 100644
--- a/Controller/User/VerifyOtp.js
+++ b/Controller/User/VerifyOtp.js
@@ -1,4 +1,4 @@
-import { SendOTPInMail } from "../../Components/Transporter.js";
+import { SendOTPInMail } from "../../Components/MailerComponents/SendOTPMail.js";
 import {
   generateAccessToken,
   generateRefreshToken,
diff --git a/Routes/Auth/AuthRoute.js b/Routes/Auth/AuthRoute.js
index 0f1fb3c..d4ad6d1 100644
--- a/Routes/Auth/AuthRoute.js
+++ b/Routes/Auth/AuthRoute.js
@@ -1,12 +1,12 @@
 import express from "express";
 import {
-  ForgotPasswordMail,
   Register,
   registerWithGoogle,
   ResetPassword,
 } from "../../Controller/User/Register.js";
 import { Login, loginWithGoogle } from "../../Controller/User/Login.js";
 import { ResendOtp, VerifyOtp } from "../../Controller/User/VerifyOtp.js";
+import { ForgotPasswordMail, SetNewPassword } from "../../Controller/User/ForgotPassword.js";
 
 export const authRouter = express.Router();
 
@@ -18,3 +18,5 @@ authRouter.post("/login", Login);
 authRouter.post("/google-login", loginWithGoogle);
 authRouter.post("/forgot-password", ForgotPasswordMail);
 authRouter.post("/reset-password", ResetPassword);
+authRouter.post("/new-password", SetNewPassword);
+
diff --git a/index.js b/index.js
index 4fb7535..b3c6357 100644
--- a/index.js
+++ b/index.js
@@ -11,6 +11,14 @@ import bodyParser from "body-parser";
 import dotenv from "dotenv";
 import { apiRouter } from "./Routes/Api.js";
 import { ConnectDatabase } from "./Components/ConnectDatabase.js";
+import { 
+  SERVER_WORKING_MESSAGE, 
+  BASE_URL, 
+  SOCKET_CONNECTION_EVENT, 
+  SOCKET_MESSAGE_EVENT, 
+  SOCKET_DISCONNECT_EVENT,
+  API_BASE_ROUTE
+} from "./Constants/AppConstants.js";
 
 dotenv.config();
 const app = express();
@@ -29,10 +37,10 @@ app.use(bodyParser.json());
 Sentry.setupExpressErrorHandler(app);
 
 app.get("/", (req, res) => {
-    res.send("Server working");
+    res.send(SERVER_WORKING_MESSAGE);
 });
 
-app.use("/api", apiRouter);
+app.use(API_BASE_ROUTE, apiRouter);
 ConnectDatabase();
 
 
@@ -44,13 +52,13 @@ app.use(function onError(err, req, res, next) {
   res.end(res.sentry + "\n");
 });
 
-io.on("connection", (socket) => {
-    socket.on("message", (data) => {
-        io.emit("message", data);
+io.on(SOCKET_CONNECTION_EVENT, (socket) => {
+    socket.on(SOCKET_MESSAGE_EVENT, (data) => {
+        io.emit(SOCKET_MESSAGE_EVENT, data);
     });
-    socket.on("disconnect", () => { });
+    socket.on(SOCKET_DISCONNECT_EVENT, () => { });
 });
 
 server.listen(PORT, () => {
-    console.log(`http://localhost:${PORT}`);
+    console.log(`${BASE_URL}:${PORT}`);
 });
diff --git a/package.json b/package.json
index 1b07bfa..de6bebc 100644
--- a/package.json
+++ b/package.json
@@ -1,17 +1,16 @@
 {
-  "name": "backend",
+  "name": "av-backend",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
   "type": "module",
   "scripts": {
     "start": "nodemon index.js",
-    "test": "npm run test "
+    "test": "npm run test ",
+    "lint": "eslint ."
   },
-  "keywords": [
-    "Orlian"
-  ],
-  "author": "Orlian",
+  "keywords": [],
+  "author": "",
   "license": "ISC",
   "dependencies": {
     "@sentry/node": "^9.5.0",


Reviews:
user: login: qodo-code-review[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T06:04:26Z
user: login: qodo-code-review[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T06:05:13Z

Review comments:
diff_hunk: @@ -0,0 +1,44 @@
+import nodemailer from "nodemailer";
+import { transporter } from "./Transporter.js";
+import dotenv from "dotenv";
+import {
+  EMAIL_VERIFICATION_HEADING,
+  OTP_MESSAGE,
+  OTP_EXPIRATION_PREFIX,
+  OTP_EXPIRATION_SUFFIX,
+  VERIFY_EMAIL_SUBJECT,
+  IGNORE_EMAIL_MESSAGE,
+  VERIFY_EMAIL_BUTTON_TEXT,
+  VERIFICATION_LINK_BASE
+} from "../../Constants/MailerConstants.js";
+dotenv.config();
+
+
+
+export async function SendOTPInMail(otp, toEmail) {
+  try {
+    const verificationLink = `${VERIFICATION_LINK_BASE}?email=${encodeURIComponent(
+      toEmail
+    )}&otp=${otp}`;
+    const emailContent = `
+          <h2>${EMAIL_VERIFICATION_HEADING}</h2>
+          <p>${OTP_MESSAGE}<strong>${otp}</strong></p>
+          <p>${OTP_EXPIRATION_PREFIX}<strong>30${OTP_EXPIRATION_SUFFIX}</strong>.</p>
+          <a href="${verificationLink}" style="padding: 10px 15px; background-color: blue; color: white; text-decoration: none; border-radius: 5px;">
+            ${VERIFY_EMAIL_BUTTON_TEXT}
+          </a>
+          <p>${IGNORE_EMAIL_MESSAGE}</p>
+        `;
+
+    const mailOptions = {
+      from: process.env.EMAIL_USER,
+      to: toEmail,
+      subject: VERIFY_EMAIL_SUBJECT,
+      html: emailContent,
+    };
+
+    await transporter.sendMail(mailOptions);
+  } catch (e) {
+    return;
+  }
+}
path: Components/MailerComponents/SendOTPMail.js
user: login: qodo-code-review[bot]
body: **Suggestion:** Add missing return value
```suggestion
export async function SendOTPInMail(otp, toEmail) {
  try {
    const verificationLink = `${VERIFICATION_LINK_BASE}?email=${encodeURIComponent(
      toEmail
    )}&otp=${otp}`;
    const emailContent = `
          <h2>${EMAIL_VERIFICATION_HEADING}</h2>
          <p>${OTP_MESSAGE}<strong>${otp}</strong></p>
          <p>${OTP_EXPIRATION_PREFIX}<strong>30${OTP_EXPIRATION_SUFFIX}</strong>.</p>
          <a href="${verificationLink}" style="padding: 10px 15px; background-color: blue; color: white; text-decoration: none; border-radius: 5px;">
            ${VERIFY_EMAIL_BUTTON_TEXT}
          </a>
          <p>${IGNORE_EMAIL_MESSAGE}</p>
        `;

    const mailOptions = {
      from: process.env.EMAIL_USER,
      to: toEmail,
      subject: VERIFY_EMAIL_SUBJECT,
      html: emailContent,
    };

    await transporter.sendMail(mailOptions);
    return { success: true };
  } catch (e) {
    return { success: false, error: e.message };
  }
}
```

<!-- manually_applied -->
created_at: 2025-03-14T06:04:26Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,111 @@
+import UserSchema from "../../Model/UserSchema.js";
+import dotenv from "dotenv";
+import crypto from "crypto";
+import { OAuth2Client } from "google-auth-library";
+import { ForgotTemplate } from "../../Components/MailerComponents/ForgotTemplate.js";
+import {
+    EMAIL_NOT_FOUND_ERROR,
+    EMAIL_REQUIRED_ERROR,
+    INVALID_EMAIL_FORMAT_ERROR,
+    PASSWORD_REQUIRED_ERROR,
+    PASSWORD_COMPLEXITY_ERROR,
+    GENERIC_ERROR_MESSAGE,
+    PASSWORD_RESET_EMAIL_SENT,
+    PASSWORD_UPDATED_SUCCESS,
+    EMAIL_REGEX,
+    PASSWORD_REGEX
+} from "../../Constants/UserConstants.js";
+import { RESET_LINK_BASE } from "../../Constants/MailerConstants.js";
+
+
+dotenv.config();
+const CLIENT_ID = process.env.GOOGLE_CLIENT_ID;
+const AUTH_URL = process.env.AUTH_URL;
+const client = new OAuth2Client(CLIENT_ID);
+const FRONTEND_URL = process.env.FRONTEND_URL;
+
+
+export async function ForgotPasswordMail(req, res) {
+    try {
+        const { email } = req.body;
+        const validationResponse = validate(req, res);
+        if (validationResponse !== true) {
+            return;
+        }
+        const user = await UserSchema.findOne({ email });
+        if (!user) {
+            return res.status(404).json({ success: false, error: EMAIL_NOT_FOUND_ERROR });
+        }
+        const resetToken = crypto.randomBytes(32).toString("hex");
+        const expiryTime = Date.now() + 15 * 60 * 1000;
+
+        await UserSchema.findOneAndUpdate(
+            { email },
+            {
+                $set: {
+                    resetPasswordToken: resetToken,
+                    resetPasswordExpires: expiryTime,
+                },
+            },
+            { upsert: true, new: true }
+        );
+        const resetLink = `${RESET_LINK_BASE}?email=${encodeURIComponent(email)}&token=${resetToken}`;
+        const decodedLink = decodeURIComponent(resetLink);
+        await ForgotTemplate(email, decodedLink);
+        res.status(200).send({ success: true, message: PASSWORD_RESET_EMAIL_SENT })
+        setTimeout(async () => {
+            await UserSchema.updateOne(
+                { email, resetPasswordExpires: { $lt: Date.now() } },
+                { $unset: { resetPasswordToken: 1, resetPasswordExpires: 1 } }
+            );
+        }, 15 * 60 * 1000);
+    } catch (error) {
+        console.log("error message forgot password:::", error.message);
+        res.status(500).json({ success: false, error: error.message || GENERIC_ERROR_MESSAGE });
+    }
+}
+
+const validate = (req, res) => {
+    const { email } = req.body;
+    if (!email) {
+        return res
+            .status(400)
+            .send({ success: false, error: EMAIL_REQUIRED_ERROR });
+    }
+    if (!EMAIL_REGEX.test(email)) {
+        return res
+            .status(400)
+            .send({ success: false, error: INVALID_EMAIL_FORMAT_ERROR });
+    }
+    return true;
+};
+
+export async function SetNewPassword(req, res) {
+    try {
+        const { email, password } = req.body;
+
+        const validationResponse = validate(req, res);
+        if (validationResponse !== true) {
+            return;
+        }
+
+        if (!password) {
+            return res.status(404).send({ success: false, error: PASSWORD_REQUIRED_ERROR });
+        }
+        if (!PASSWORD_REGEX.test(password)) {
+            return res.status(404).send({ success: false, error: PASSWORD_COMPLEXITY_ERROR })
+        }
+
+        const user = await UserSchema.findOne({ email });
+        if (!user) {
+            return res.status(404).json({ success: false, error: EMAIL_NOT_FOUND_ERROR });
+        }
+
+        user.password = password;
+        await user.save();
+
+        return res.status(200).json({ success: true, message: PASSWORD_UPDATED_SUCCESS });
+    } catch (error) {
+        console.log("error set new password:::", error.message)
+    }
+}
path: Controller/User/ForgotPassword.js
user: login: qodo-code-review[bot]
body: **Suggestion:** Add missing error response
```suggestion
export async function SetNewPassword(req, res) {
    try {
        const { email, password } = req.body;

        const validationResponse = validate(req, res);
        if (validationResponse !== true) {
            return;
        }

        if (!password) {
            return res.status(404).send({ success: false, error: PASSWORD_REQUIRED_ERROR });
        }
        if (!PASSWORD_REGEX.test(password)) {
            return res.status(404).send({ success: false, error: PASSWORD_COMPLEXITY_ERROR })
        }

        const user = await UserSchema.findOne({ email });
        if (!user) {
            return res.status(404).json({ success: false, error: EMAIL_NOT_FOUND_ERROR });
        }

        user.password = password;
        await user.save();

        return res.status(200).json({ success: true, message: PASSWORD_UPDATED_SUCCESS });
    } catch (error) {
        console.log("error set new password:::", error.message);
        return res.status(500).json({ success: false, error: GENERIC_ERROR_MESSAGE });
    }
}
```

<!-- manually_applied -->
created_at: 2025-03-14T06:05:13Z
author_association: CONTRIBUTOR

PR comments:
user: login: qodo-code-review[bot]
created_at: 2025-03-14T06:03:18Z
body: ## PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

<table>
<tr><td>⏱️&nbsp;<strong>Estimated effort to review</strong>: 3 🔵🔵🔵⚪⚪</td></tr>
<tr><td>🧪&nbsp;<strong>No relevant tests</strong></td></tr>
<tr><td>🔒&nbsp;<strong>Security concerns</strong><br><br>

<strong>Sensitive information exposure:</strong><br> The code in Transporter.js creates a nodemailer transport with Gmail credentials stored in environment variables. While using environment variables is good practice, the implementation of Sentry in instrument.js might potentially capture and report errors that contain sensitive information like email addresses or tokens. It's important to ensure Sentry is configured to properly scrub sensitive data before transmission.</td></tr>
<tr><td>⚡&nbsp;<strong>Recommended focus areas for review</strong><br><br>

<details><summary><a href='https://github.com/dude613/avoda-be/pull/3/files#diff-6df052d3ab8b576f69a32f216f5f3f30f92568552a92301a79f17ac8543346b6R108-R110'><strong>Error Handling</strong></a>

The SetNewPassword function has a try-catch block but doesn't properly handle errors. It logs the error but doesn't return a response to the client, which could leave requests hanging.
</summary>

```javascript
} catch (error) {
    console.log("error set new password:::", error.message)
}
```

</details>

<details><summary><a href='https://github.com/dude613/avoda-be/pull/3/files#diff-78b74fecf8280a2e1959ac88735b77053152ed60abbfe92307901595740f1c4cR41-R43'><strong>Silent Failure</strong></a>

The catch block silently returns without any error handling or logging, which could make debugging difficult and hide potential issues with email sending.
</summary>

```javascript
} catch (e) {
  return;
}
```

</details>

<details><summary><a href='https://github.com/dude613/avoda-be/pull/3/files#diff-279f921830a8324a2fc3ce40f99e0301756238f7be86fc7c64e5eb47da42058fR5-R5'><strong>Environment Variable</strong></a>

The Sentry DSN is accessed directly from process.env without using dotenv.config(), which might cause issues if the environment variable isn't loaded properly.
</summary>

```javascript
dsn: process.env.SEN_DSN,
```

</details>

</td></tr>
</table>

author_association: CONTRIBUTOR
user: login: qodo-code-review[bot]
created_at: 2025-03-14T06:03:43Z
body: ## PR Code Suggestions ✨
<!-- 1343491 -->

Latest suggestions up to 1343491
<table><thead><tr><td><strong>Category</strong></td><td align=left><strong>Suggestion&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </strong></td><td align=center><strong>Impact</strong></td></tr><tbody><tr><td rowspan=1>Security</td>
<td>



<details><summary>Remove unnecessary URL decoding</summary>

___


**The code is unnecessarily decoding an already encoded URL. When you encode a URL <br>parameter with <code>encodeURIComponent()</code> and then immediately decode it with <br><code>decodeURIComponent()</code>, you're undoing the encoding which could lead to security <br>issues with special characters in the email.**

[Controller/User/ForgotPassword.js [52-54]](https://github.com/dude613/avoda-be/pull/3/files#diff-6df052d3ab8b576f69a32f216f5f3f30f92568552a92301a79f17ac8543346b6R52-R54)

```diff
 const resetLink = `${RESET_LINK_BASE}?email=${encodeURIComponent(email)}&token=${resetToken}`;
-const decodedLink = decodeURIComponent(resetLink);
-await ForgotTemplate(email, decodedLink);
+await ForgotTemplate(email, resetLink);
```

- [ ] **Apply this suggestion** <!-- /improve --apply_suggestion=0 -->

<details><summary>Suggestion importance[1-10]: 8</summary>

__

Why: The code unnecessarily decodes an already encoded URL, which defeats the purpose of encoding and could lead to security issues with special characters in email addresses. Removing this redundant step improves security.


</details></details></td><td align=center>Medium

</td></tr><tr><td rowspan=1>Possible issue</td>
<td>



<details><summary>Add fallback for missing DSN</summary>

___


**The Sentry initialization is using an environment variable <code>process.env.SEN_DSN</code> <br>directly without checking if it exists. If this environment variable is not set, <br>Sentry will initialize with an undefined DSN which could cause runtime errors or <br>silent failures in error reporting.**

[instrument.js [5]](https://github.com/dude613/avoda-be/pull/3/files#diff-279f921830a8324a2fc3ce40f99e0301756238f7be86fc7c64e5eb47da42058fR5-R5)

```diff
 Sentry.init({
-  dsn: process.env.SEN_DSN,
+  dsn: process.env.SEN_DSN || "",
   integrations: [
     nodeProfilingIntegration(),
   ],
   // Tracing
   tracesSampleRate: 1.0, //  Capture 100% of the transactions
 
   // Set sampling rate for profiling - this is relative to tracesSampleRate
   profilesSampleRate: 1.0,
 });
```


`[To ensure code accuracy, apply this suggestion manually]`

<details><summary>Suggestion importance[1-10]: 7</summary>

__

Why: Without a fallback for the DSN environment variable, Sentry initialization could fail silently if the variable is not set. Adding a fallback prevents potential runtime errors in error reporting.


</details></details></td><td align=center>Medium

</td></tr><tr><td rowspan=1>General</td>
<td>



<details><summary>Remove redundant comment</summary>

___


**Remove the comment that explains how to import the file since you're already <br>correctly importing it. This comment is redundant and could confuse developers <br>who might think there's still something to be done.**

[index.js [1-3]](https://github.com/dude613/avoda-be/pull/3/files#diff-e727e4bdf3657fd1d798edcd6b099d6e092f8573cba266154583a746bba0f346R1-R3)

```diff
-// IMPORTANT: Make sure to import `instrument.js` at the top of your file.
-// If you're using ECMAScript Modules (ESM) syntax, use `import "./instrument.js";`
 import "./instrument.js";
```

- [ ] **Apply this suggestion** <!-- /improve --apply_suggestion=2 -->

<details><summary>Suggestion importance[1-10]: 2</summary>

__

Why: The comment is redundant since the code is already correctly importing the file. While removing it improves code cleanliness, it has minimal impact on functionality.


</details></details></td><td align=center>Low

</td></tr>
<tr><td align="center" colspan="2">

- [ ] Update <!-- /improve --more_suggestions=true -->

</td><td></td></tr></tbody></table>

___

#### Previous suggestions
<details><summary>✅ Suggestions up to commit 1662146</summary>
<br><table><thead><tr><td><strong>Category</strong></td><td align=left><strong>Suggestion&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </strong></td><td align=center><strong>Impact</strong></td></tr><tbody><tr><td rowspan=1>Possible issue</td>
<td>



<details><summary>✅ 
Add missing error response
</summary>

___


**The function is missing a proper error response when an exception occurs. <br>Currently, it only logs the error but doesn't send any response back to the <br>client, which would leave the request hanging.**

[Controller/User/ForgotPassword.js [83-111]](https://github.com/dude613/avoda-be/pull/3/files#diff-6df052d3ab8b576f69a32f216f5f3f30f92568552a92301a79f17ac8543346b6R83-R111)

```diff
 export async function SetNewPassword(req, res) {
     try {
         const { email, password } = req.body;
 
         const validationResponse = validate(req, res);
         if (validationResponse !== true) {
             return;
         }
 
         if (!password) {
             return res.status(404).send({ success: false, error: PASSWORD_REQUIRED_ERROR });
         }
         if (!PASSWORD_REGEX.test(password)) {
             return res.status(404).send({ success: false, error: PASSWORD_COMPLEXITY_ERROR })
         }
 
         const user = await UserSchema.findOne({ email });
         if (!user) {
             return res.status(404).json({ success: false, error: EMAIL_NOT_FOUND_ERROR });
         }
 
         user.password = password;
         await user.save();
 
         return res.status(200).json({ success: true, message: PASSWORD_UPDATED_SUCCESS });
     } catch (error) {
-        console.log("error set new password:::", error.message)
+        console.log("error set new password:::", error.message);
+        return res.status(500).json({ success: false, error: GENERIC_ERROR_MESSAGE });
     }
 }
```

`[Suggestion has been applied]`

<details><summary>Suggestion importance[1-10]: 9</summary>

__

Why: The suggestion addresses a critical issue where the function doesn't send any response to the client when an error occurs, which would leave the request hanging. Adding a proper error response is essential for API reliability.


</details></details></td><td align=center>High

</td></tr><tr><td rowspan=1>General</td>
<td>



<details><summary>✅ 
Add missing return value
</summary>

___


**The function should return a success status or result when the email is sent <br>successfully. Currently, it only returns undefined in the catch block but <br>doesn't return anything in the success path.**

[Components/MailerComponents/SendOTPMail.js [18-44]](https://github.com/dude613/avoda-be/pull/3/files#diff-78b74fecf8280a2e1959ac88735b77053152ed60abbfe92307901595740f1c4cR18-R44)

```diff
 export async function SendOTPInMail(otp, toEmail) {
   try {
     const verificationLink = `${VERIFICATION_LINK_BASE}?email=${encodeURIComponent(
       toEmail
     )}&otp=${otp}`;
     const emailContent = `
           <h2>${EMAIL_VERIFICATION_HEADING}</h2>
           <p>${OTP_MESSAGE}<strong>${otp}</strong></p>
           <p>${OTP_EXPIRATION_PREFIX}<strong>30${OTP_EXPIRATION_SUFFIX}</strong>.</p>
           <a href="${verificationLink}" style="padding: 10px 15px; background-color: blue; color: white; text-decoration: none; border-radius: 5px;">
             ${VERIFY_EMAIL_BUTTON_TEXT}
           </a>
           <p>${IGNORE_EMAIL_MESSAGE}</p>
         `;
 
     const mailOptions = {
       from: process.env.EMAIL_USER,
       to: toEmail,
       subject: VERIFY_EMAIL_SUBJECT,
       html: emailContent,
     };
 
     await transporter.sendMail(mailOptions);
+    return { success: true };
   } catch (e) {
-    return;
+    return { success: false, error: e.message };
   }
 }
```

`[Suggestion has been applied]`

<details><summary>Suggestion importance[1-10]: 7</summary>

__

Why: The suggestion improves error handling by returning meaningful success/failure status objects instead of undefined. This makes the function more reliable and allows calling code to properly handle errors.


</details></details></td><td align=center>Medium

</td></tr>
<tr><td align="center" colspan="2">

 <!-- /improve --more_suggestions=true -->

</td><td></td></tr></tbody></table>

</details>
author_association: CONTRIBUTOR
user: login: dude613
created_at: 2025-03-14T06:05:34Z
body: /improve
author_association: OWNER