import { Request, Response } from "express"; import { User } from "../models/user"; import { saveSession, hashPassword, decodeBase64, matchPassword, } from "../utils/utils"; import { MONGODB_IGNORED_FIELDS } from "../utils/constants"; import { isUsernameValid, isPasswordValid } from "../validation/validation"; import { Session } from "../models/session"; export async function SignUp(req: Request, res: Response) { const { accountName, username, password } = req.body; if (!accountName || !username || !password) { return res.status(400).json({ status: "err" }); } const existingUser = await User.findOne({ accountName }) .select("accountName -_id") .lean(); if (existingUser) { return res.status(400).json({ status: 1 }); } if (!isPasswordValid(password)) { return res.status(400).json({ status: "err" }); } const decodedPassword = decodeBase64(password); const hashedPassword = await hashPassword(decodedPassword); const user = new User({ accountName: accountName, username: username, password: hashedPassword, }); user .save() .then(() => saveSession(res, accountName)) .catch((err) => { console.log(err); res.status(500).json({ status: "err" }); }); } export async function Login(req: Request, res: Response) { try { if (!req.body.accountName || !req.body.password) { return res.status(400).json({ status: "err" }); } const { accountName, password } = req.body; const user = await User.findOne({ accountName }).lean(); if (!user) { return res.status(401).json({ status: "err" }); } if ( user.accountName === null || user.accountName === undefined || user.password === undefined || user.password === null ) { return res.status(401).json({ status: "err" }); } const decodedPassword = decodeBase64(password); const isPasswordValid = await matchPassword(decodedPassword, user.password); if (!isPasswordValid) { return res.status(401).json({ status: "err" }); } saveSession(res, user.accountName); } catch (error) { console.error("error on login:", error); res.status(500).json({ status: "err" }); } } export async function GetUserProfile(req: Request, res: Response) { try { const user = await User.findOne({ accountName: req.params.accountName, }) .select(MONGODB_IGNORED_FIELDS) .lean(); if (!user) { return res.status(404).json({ status: "err" }); } res.json({ accountName: user.accountName, username: user.username, }); } catch (error) { console.error("error on get user profile:", error); res.status(500).json({ status: "err" }); } } export async function ChangeUsername(req: Request, res: Response) { const { accountName, newUsername } = req.body; if (!accountName || !newUsername) { return res.status(400).json({ status: "err" }); } if (!isUsernameValid(newUsername)) { return res.status(400).json({ status: "err" }); } try { await User.updateOne( { accountName: accountName }, { $set: { username: newUsername } } ); res.status(200).json({ status: "ok" }); } catch (error) { console.error(error); res.status(500).json({ status: "err" }); } } export async function ChangePassword(req: Request, res: Response) { const { accountName, currentPassword, newPassword } = req.body; if (!accountName || !currentPassword || !newPassword) { return res.status(400).json({ status: "err" }); } try { const decodedCurrentPassword = decodeBase64(currentPassword); const existingUser = await User.findOne({ accountName }) .select("password -_id") .lean(); if (!existingUser) { return res.status(400).json({ status: 1 }); } const decodedNewPassword = decodeBase64(newPassword); if (!isPasswordValid(decodedCurrentPassword)) { return res.status(400).json({ status: "err" }); } const isPasswordMatching = await matchPassword( decodedCurrentPassword, existingUser.password ); if (!isPasswordMatching || !isPasswordValid(decodedNewPassword)) { return res.status(401).json({ status: "err" }); } await User.updateOne( { accountName: accountName }, { $set: { password: await hashPassword(decodedNewPassword) } } ); res.status(200).json({ status: "ok" }); // delete all sessions await Session.deleteMany({ accountName: accountName }); } catch (error) { console.error(error); res.status(500).json({ status: "err" }); } }