Untitled

mail@pastecode.io avatar
unknown
typescript
7 months ago
3.2 kB
3
Indexable
Never
const sendOtpEmail = async (email: string, otp: string) => {
  const transporter = nodemailer.createTransport({
    host: "sandbox.smtp.mailtrap.io",
    port: 2525,
    auth: {
      user: "d32056e1316219",
      pass: "a560c8049b58d1",
    },
  });

  const mailOptions = {
    from: process.env.EMAIL_USERNAME,
    to: email,
    subject: "OTP for login",
    text: `Your OTP for login is ${otp}`,
  };

  try {
    const info = await transporter.sendMail(mailOptions);
    console.log("Message sent: %s", info.messageId);
  } catch (error) {
    console.error("Error sending email:", error);
  }

  await transporter.sendMail(mailOptions);
};

export const login = async (req: Request, res: Response) => {
  const { email, password } = req.body;

  if (!email || !password) {
    return res.status(400).json({
      error: true,
      message: REQUIRED_VALUE_EMPTY,
    });
  }

  try {
    const user = await Users.findOne({ email });
    if (!user || user.deletedAt) {
      throw new Error("Account does not exist in our system");
    }
    if (user.blockedAt) {
      throw new Error("Account was prohibited to login due to violations");
    }

    const decryptPassword = CryptoJS.AES.decrypt(
      user.password as string,
      encryptKey as string
    );
    const originalPassword = decryptPassword.toString(CryptoJS.enc.Utf8);

    if (originalPassword !== password) {
      throw new Error("Email or password is invalid");
    }

    // Correct password, generate OTP
    const otp = Math.floor(100000 + Math.random() * 900000).toString(); // 6-digit OTP
    user.otp = otp;
    user.otpExpiresAt = new Date(Date.now() + 10 * 60000); // OTP expires in 10 minutes
    await user.save();

    // Send OTP to user's email
    await sendOtpEmail(email, otp);

    // Do not send the JWT token now, wait for OTP verification
    return res.json({
      error: false,
      message: "OTP sent to email. Please verify to continue.",
    });
  } catch (err: any) {
    const message = err.message || UNKNOWN_ERROR_OCCURRED;
    return res.status(500).json({
      error: true,
      message: message,
    });
  }
};

export const verifyOtp = async (req: Request, res: Response) => {
  const { email, otp } = req.body;

  try {
    const user = await Users.findOne({
      email,
      otp,
      otpExpiresAt: { $gt: Date.now() },
    });
    if (!user) {
      res.json({
        error: true,
        message: "OTP is invalid or expired",
      });
    } else {
      // OTP is correct, and not expired
      user.otp = ""; // clear OTP
      user.otpExpiresAt = undefined; //clear OTP expiry
      await user.save();
    }
    // Now create the JWT token since OTP is verified

    const token = jwt.sign(
      { email: user?.email, role: user?.role },
      signKey as string,
      { expiresIn: "1d" }
    );

    res.json({
      error: false,
      message: "OTP verified, user logged in successfully",
      item: token,
      itemCount: null,
    });
  } catch (error) {
    res.json({
      error: true,
      message: String(error),
      items: null,
      itemCount: null,
    });
  }
};
Leave a Comment