import jwt from "jsonwebtoken"; import { plainToInstance } from "class-transformer"; import { validate } from "class-validator"; import { User } from "../../../models/User"; import { LoginResult, LoginInput } from "./types"; import redis from "../../../config/redis"; import { formatValidationErrors } from "../../../utils"; export const login = async (input: LoginInput): Promise => { const dto = plainToInstance(LoginInput, input); const errors = await validate(dto); if (errors.length > 0) { const formattedErrors = formatValidationErrors(errors); return { code: 400, message: formattedErrors[0], }; } const { password, mail } = input; const user = await User.findOne({ mail }); if (!user) { return { message: "User not found", code: 404, }; } if (user.password !== password) { return { message: "Wrong password", code: 401, }; } if (!user.isMailVerified) { return { message: "Please verify your email address.", code: 403, payload: { isMailVerified: user.isMailVerified, mail: user.mail, }, }; } const accessToken = jwt.sign( { companyName: user.companyName, fullName: user.fullName, userId: user._id, mail: user.mail }, process.env.JWT_SECRET as string, { expiresIn: "4h" } ); await redis.setex(`user:${user._id.toString()}`, 14400, accessToken); const refreshToken = jwt.sign( { companyName: user.companyName, fullName: user.fullName, userId: user._id, mail: user.mail }, process.env.JWT_REFRESH_SECRET as string || process.env.JWT_SECRET as string, { expiresIn: "30d" } ); user.refreshToken = refreshToken; await user.save(); return { message: "Login successful", code: 200, payload: { refreshToken, accessToken, user: { phoneNumber: user.phoneNumber, companyName: user.companyName, userId: user._id.toString(), firstName: user.firstName, lastName: user.lastName, fullName: user.fullName, mail: user.mail, }, }, }; }; export default login;