180 lines
4.5 KiB
TypeScript
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" });
|
|
}
|
|
}
|