This repository has been archived on 2024-01-23. You can view files and clone it, but cannot push or open issues/pull-requests.
API/src/controllers/userController.ts

180 lines
4.5 KiB
TypeScript

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" });
}
}