mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-06 13:40:16 +08:00
using asynchandlerwrapper
removed try catches
This commit is contained in:
parent
07a32b63e5
commit
4935a6594d
2 changed files with 228 additions and 283 deletions
|
@ -14,296 +14,233 @@ const uaparser = require("ua-parser-js");
|
|||
// import { isUsernameValid } from "../../handlers/validation";
|
||||
|
||||
class UserController {
|
||||
static async createNewUser(req, res, next) {
|
||||
try {
|
||||
const { name } = req.body;
|
||||
const { email, uid } = req.decodedToken;
|
||||
await UsersDAO.addUser(name, email, uid);
|
||||
Logger.log("user_created", `${name} ${email}`, uid);
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
static async createNewUser(req, res) {
|
||||
const { name } = req.body;
|
||||
const { email, uid } = req.decodedToken;
|
||||
await UsersDAO.addUser(name, email, uid);
|
||||
Logger.log("user_created", `${name} ${email}`, uid);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async deleteUser(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
const userInfo = await UsersDAO.getUser(uid);
|
||||
await UsersDAO.deleteUser(uid);
|
||||
Logger.log("user_deleted", `${userInfo.email} ${userInfo.name}`, uid);
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
static async deleteUser(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
const userInfo = await UsersDAO.getUser(uid);
|
||||
await UsersDAO.deleteUser(uid);
|
||||
Logger.log("user_deleted", `${userInfo.email} ${userInfo.name}`, uid);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async updateName(req, res, next) {
|
||||
static async updateName(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
const { name } = req.body;
|
||||
if (!isUsernameValid(name))
|
||||
return res.status(400).json({
|
||||
message:
|
||||
"Username invalid. Name cannot contain special characters or contain more than 14 characters. Can include _ . and -",
|
||||
});
|
||||
let olduser = await UsersDAO.getUser(uid);
|
||||
await UsersDAO.updateName(uid, name);
|
||||
Logger.log(
|
||||
"user_name_updated",
|
||||
`changed name from ${olduser.name} to ${name}`,
|
||||
uid
|
||||
);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async clearPb(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
await UsersDAO.clearPb(uid);
|
||||
Logger.log("user_cleared_pbs", "", uid);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async checkName(req, res) {
|
||||
const { name } = req.body;
|
||||
if (!isUsernameValid(name))
|
||||
return next({
|
||||
status: 400,
|
||||
message:
|
||||
"Username invalid. Name cannot contain special characters or contain more than 14 characters. Can include _ . and -",
|
||||
});
|
||||
const available = await UsersDAO.isNameAvailable(name);
|
||||
if (!available)
|
||||
return res.status(400).json({ message: "Username unavailable" });
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async updateEmail(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
const { newEmail } = req.body;
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
const { name } = req.body;
|
||||
if (!isUsernameValid(name))
|
||||
return res.status(400).json({
|
||||
message:
|
||||
"Username invalid. Name cannot contain special characters or contain more than 14 characters. Can include _ . and -",
|
||||
});
|
||||
let olduser = await UsersDAO.getUser(uid);
|
||||
await UsersDAO.updateName(uid, name);
|
||||
Logger.log(
|
||||
"user_name_updated",
|
||||
`changed name from ${olduser.name} to ${name}`,
|
||||
uid
|
||||
await UsersDAO.updateEmail(uid, newEmail);
|
||||
} catch (e) {
|
||||
throw new MonkeyError(400, e.message, "update email", uid);
|
||||
}
|
||||
Logger.log("user_email_updated", `changed email to ${newEmail}`, uid);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async getUser(req, res) {
|
||||
const { email, uid } = req.decodedToken;
|
||||
let userInfo;
|
||||
try {
|
||||
userInfo = await UsersDAO.getUser(uid);
|
||||
} catch (e) {
|
||||
if (email && uid) {
|
||||
userInfo = await UsersDAO.addUser(undefined, email, uid);
|
||||
} else {
|
||||
throw new MonkeyError(
|
||||
400,
|
||||
"User not found. Could not recreate user document.",
|
||||
"Tried to recreate user document but either email or uid is nullish",
|
||||
uid
|
||||
);
|
||||
}
|
||||
}
|
||||
let agent = uaparser(req.headers["user-agent"]);
|
||||
let logobj = {
|
||||
ip:
|
||||
req.headers["cf-connecting-ip"] ||
|
||||
req.headers["x-forwarded-for"] ||
|
||||
req.ip ||
|
||||
"255.255.255.255",
|
||||
agent:
|
||||
agent.os.name +
|
||||
" " +
|
||||
agent.os.version +
|
||||
" " +
|
||||
agent.browser.name +
|
||||
" " +
|
||||
agent.browser.version,
|
||||
};
|
||||
if (agent.device.vendor) {
|
||||
logobj.device =
|
||||
agent.device.vendor +
|
||||
" " +
|
||||
agent.device.model +
|
||||
" " +
|
||||
agent.device.type;
|
||||
}
|
||||
Logger.log("user_data_requested", logobj, uid);
|
||||
return res.status(200).json(userInfo);
|
||||
}
|
||||
|
||||
static async linkDiscord(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
|
||||
let requser;
|
||||
try {
|
||||
requser = await UsersDAO.getUser(uid);
|
||||
} catch (e) {
|
||||
requser = null;
|
||||
}
|
||||
if (requser?.banned === true) {
|
||||
throw new MonkeyError(403, "Banned accounts cannot link with Discord");
|
||||
}
|
||||
|
||||
let discordFetch = await fetch("https://discord.com/api/users/@me", {
|
||||
headers: {
|
||||
authorization: `${req.body.data.tokenType} ${req.body.data.accessToken}`,
|
||||
},
|
||||
});
|
||||
discordFetch = await discordFetch.json();
|
||||
const did = discordFetch.id;
|
||||
if (!did) {
|
||||
throw new MonkeyError(
|
||||
500,
|
||||
"Could not get Discord account info",
|
||||
"did is undefined"
|
||||
);
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
let user;
|
||||
try {
|
||||
user = await UsersDAO.getUserByDiscordId(did);
|
||||
} catch (e) {
|
||||
user = null;
|
||||
}
|
||||
if (user !== null) {
|
||||
throw new MonkeyError(
|
||||
400,
|
||||
"This Discord account is already linked to a different account"
|
||||
);
|
||||
}
|
||||
await UsersDAO.linkDiscord(uid, did);
|
||||
await BotDAO.linkDiscord(uid, did);
|
||||
Logger.log("user_discord_link", `linked to ${did}`, uid);
|
||||
return res.status(200).json({
|
||||
message: "Discord account linked",
|
||||
did,
|
||||
});
|
||||
}
|
||||
|
||||
static async clearPb(req, res, next) {
|
||||
static async unlinkDiscord(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
let userInfo;
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
await UsersDAO.clearPb(uid);
|
||||
Logger.log("user_cleared_pbs", "", uid);
|
||||
return res.sendStatus(200);
|
||||
userInfo = await UsersDAO.getUser(uid);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
throw new MonkeyError(400, "User not found.");
|
||||
}
|
||||
if (!userInfo.discordId) {
|
||||
throw new MonkeyError(400, "User does not have a linked Discord account");
|
||||
}
|
||||
await BotDAO.unlinkDiscord(uid, userInfo.discordId);
|
||||
await UsersDAO.unlinkDiscord(uid);
|
||||
Logger.log("user_discord_unlinked", userInfo.discordId, uid);
|
||||
return res.status(200).send();
|
||||
}
|
||||
|
||||
static async checkName(req, res, next) {
|
||||
try {
|
||||
const { name } = req.body;
|
||||
if (!isUsernameValid(name))
|
||||
return next({
|
||||
status: 400,
|
||||
message:
|
||||
"Username invalid. Name cannot contain special characters or contain more than 14 characters. Can include _ . and -",
|
||||
});
|
||||
const available = await UsersDAO.isNameAvailable(name);
|
||||
if (!available)
|
||||
return res.status(400).json({ message: "Username unavailable" });
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
|
||||
static async updateEmail(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
const { newEmail } = req.body;
|
||||
try {
|
||||
await UsersDAO.updateEmail(uid, newEmail);
|
||||
} catch (e) {
|
||||
throw new MonkeyError(400, e.message, "update email", uid);
|
||||
}
|
||||
Logger.log("user_email_updated", `changed email to ${newEmail}`, uid);
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
|
||||
static async getUser(req, res, next) {
|
||||
try {
|
||||
const { email, uid } = req.decodedToken;
|
||||
let userInfo;
|
||||
try {
|
||||
userInfo = await UsersDAO.getUser(uid);
|
||||
} catch (e) {
|
||||
if (email && uid) {
|
||||
userInfo = await UsersDAO.addUser(undefined, email, uid);
|
||||
} else {
|
||||
throw new MonkeyError(
|
||||
400,
|
||||
"User not found. Could not recreate user document.",
|
||||
"Tried to recreate user document but either email or uid is nullish",
|
||||
uid
|
||||
);
|
||||
}
|
||||
}
|
||||
let agent = uaparser(req.headers["user-agent"]);
|
||||
let logobj = {
|
||||
ip:
|
||||
req.headers["cf-connecting-ip"] ||
|
||||
req.headers["x-forwarded-for"] ||
|
||||
req.ip ||
|
||||
"255.255.255.255",
|
||||
agent:
|
||||
agent.os.name +
|
||||
" " +
|
||||
agent.os.version +
|
||||
" " +
|
||||
agent.browser.name +
|
||||
" " +
|
||||
agent.browser.version,
|
||||
};
|
||||
if (agent.device.vendor) {
|
||||
logobj.device =
|
||||
agent.device.vendor +
|
||||
" " +
|
||||
agent.device.model +
|
||||
" " +
|
||||
agent.device.type;
|
||||
}
|
||||
Logger.log("user_data_requested", logobj, uid);
|
||||
return res.status(200).json(userInfo);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
|
||||
static async linkDiscord(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
|
||||
let requser;
|
||||
try {
|
||||
requser = await UsersDAO.getUser(uid);
|
||||
} catch (e) {
|
||||
requser = null;
|
||||
}
|
||||
if (requser?.banned === true) {
|
||||
throw new MonkeyError(403, "Banned accounts cannot link with Discord");
|
||||
}
|
||||
|
||||
let discordFetch = await fetch("https://discord.com/api/users/@me", {
|
||||
headers: {
|
||||
authorization: `${req.body.data.tokenType} ${req.body.data.accessToken}`,
|
||||
},
|
||||
static async addTag(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
const { tagName } = req.body;
|
||||
if (!isTagPresetNameValid(tagName))
|
||||
return res.status(400).json({
|
||||
message:
|
||||
"Tag name invalid. Name cannot contain special characters or more than 16 characters. Can include _ . and -",
|
||||
});
|
||||
discordFetch = await discordFetch.json();
|
||||
const did = discordFetch.id;
|
||||
if (!did) {
|
||||
throw new MonkeyError(
|
||||
500,
|
||||
"Could not get Discord account info",
|
||||
"did is undefined"
|
||||
);
|
||||
}
|
||||
let user;
|
||||
try {
|
||||
user = await UsersDAO.getUserByDiscordId(did);
|
||||
} catch (e) {
|
||||
user = null;
|
||||
}
|
||||
if (user !== null) {
|
||||
throw new MonkeyError(
|
||||
400,
|
||||
"This Discord account is already linked to a different account"
|
||||
);
|
||||
}
|
||||
await UsersDAO.linkDiscord(uid, did);
|
||||
await BotDAO.linkDiscord(uid, did);
|
||||
Logger.log("user_discord_link", `linked to ${did}`, uid);
|
||||
return res.status(200).json({
|
||||
message: "Discord account linked",
|
||||
did,
|
||||
let tag = await UsersDAO.addTag(uid, tagName);
|
||||
return res.status(200).json(tag);
|
||||
}
|
||||
|
||||
static async clearTagPb(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
const { tagid } = req.body;
|
||||
await UsersDAO.removeTagPb(uid, tagid);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async editTag(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
const { tagid, newname } = req.body;
|
||||
if (!isTagPresetNameValid(newname))
|
||||
return res.status(400).json({
|
||||
message:
|
||||
"Tag name invalid. Name cannot contain special characters or more than 16 characters. Can include _ . and -",
|
||||
});
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
await UsersDAO.editTag(uid, tagid, newname);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async unlinkDiscord(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
let userInfo;
|
||||
try {
|
||||
userInfo = await UsersDAO.getUser(uid);
|
||||
} catch (e) {
|
||||
throw new MonkeyError(400, "User not found.");
|
||||
}
|
||||
if (!userInfo.discordId) {
|
||||
throw new MonkeyError(
|
||||
400,
|
||||
"User does not have a linked Discord account"
|
||||
);
|
||||
}
|
||||
await BotDAO.unlinkDiscord(uid, userInfo.discordId);
|
||||
await UsersDAO.unlinkDiscord(uid);
|
||||
Logger.log("user_discord_unlinked", userInfo.discordId, uid);
|
||||
return res.status(200).send();
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
static async removeTag(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
const { tagid } = req.body;
|
||||
await UsersDAO.removeTag(uid, tagid);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async addTag(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
const { tagName } = req.body;
|
||||
if (!isTagPresetNameValid(tagName))
|
||||
return res.status(400).json({
|
||||
message:
|
||||
"Tag name invalid. Name cannot contain special characters or more than 16 characters. Can include _ . and -",
|
||||
});
|
||||
let tag = await UsersDAO.addTag(uid, tagName);
|
||||
return res.status(200).json(tag);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
static async getTags(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
let tags = await UsersDAO.getTags(uid);
|
||||
if (tags == undefined) tags = [];
|
||||
return res.status(200).json(tags);
|
||||
}
|
||||
|
||||
static async clearTagPb(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
const { tagid } = req.body;
|
||||
await UsersDAO.removeTagPb(uid, tagid);
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
|
||||
static async editTag(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
const { tagid, newname } = req.body;
|
||||
if (!isTagPresetNameValid(newname))
|
||||
return res.status(400).json({
|
||||
message:
|
||||
"Tag name invalid. Name cannot contain special characters or more than 16 characters. Can include _ . and -",
|
||||
});
|
||||
await UsersDAO.editTag(uid, tagid, newname);
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
|
||||
static async removeTag(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
const { tagid } = req.body;
|
||||
await UsersDAO.removeTag(uid, tagid);
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
|
||||
static async getTags(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
let tags = await UsersDAO.getTags(uid);
|
||||
if (tags == undefined) tags = [];
|
||||
return res.status(200).json(tags);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
}
|
||||
|
||||
static async updateLbMemory(req, res, next) {
|
||||
try {
|
||||
const { uid } = req.decodedToken;
|
||||
const { mode, mode2, language, rank } = req.body;
|
||||
await UsersDAO.updateLbMemory(uid, mode, mode2, language, rank);
|
||||
return res.sendStatus(200);
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
}
|
||||
static async updateLbMemory(req, res) {
|
||||
const { uid } = req.decodedToken;
|
||||
const { mode, mode2, language, rank } = req.body;
|
||||
await UsersDAO.updateLbMemory(uid, mode, mode2, language, rank);
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,10 @@ const { authenticateRequest } = require("../../middlewares/auth");
|
|||
const { Router } = require("express");
|
||||
const UserController = require("../controllers/user");
|
||||
const RateLimit = require("../../middlewares/rate-limit");
|
||||
const {
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
} = require("../../middlewares/api-utils");
|
||||
|
||||
const router = Router();
|
||||
|
||||
|
@ -9,100 +13,104 @@ router.get(
|
|||
"/",
|
||||
RateLimit.userGet,
|
||||
authenticateRequest,
|
||||
UserController.getUser
|
||||
asyncHandlerWrapper(UserController.getUser)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/signup",
|
||||
RateLimit.userSignup,
|
||||
authenticateRequest,
|
||||
UserController.createNewUser
|
||||
asyncHandlerWrapper(UserController.createNewUser)
|
||||
);
|
||||
|
||||
router.post("/checkName", RateLimit.userCheckName, UserController.checkName);
|
||||
router.post(
|
||||
"/checkName",
|
||||
RateLimit.userCheckName,
|
||||
asyncHandlerWrapper(UserController.checkName)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/delete",
|
||||
RateLimit.userDelete,
|
||||
authenticateRequest,
|
||||
UserController.deleteUser
|
||||
asyncHandlerWrapper(UserController.deleteUser)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateName",
|
||||
RateLimit.userUpdateName,
|
||||
authenticateRequest,
|
||||
UserController.updateName
|
||||
asyncHandlerWrapper(UserController.updateName)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateLbMemory",
|
||||
RateLimit.userUpdateLBMemory,
|
||||
authenticateRequest,
|
||||
UserController.updateLbMemory
|
||||
asyncHandlerWrapper(UserController.updateLbMemory)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateEmail",
|
||||
RateLimit.userUpdateEmail,
|
||||
authenticateRequest,
|
||||
UserController.updateEmail
|
||||
asyncHandlerWrapper(UserController.updateEmail)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/clearPb",
|
||||
RateLimit.userClearPB,
|
||||
authenticateRequest,
|
||||
UserController.clearPb
|
||||
asyncHandlerWrapper(UserController.clearPb)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/add",
|
||||
RateLimit.userTagsAdd,
|
||||
authenticateRequest,
|
||||
UserController.addTag
|
||||
asyncHandlerWrapper(UserController.addTag)
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/tags",
|
||||
RateLimit.userTagsGet,
|
||||
authenticateRequest,
|
||||
UserController.getTags
|
||||
asyncHandlerWrapper(UserController.getTags)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/clearPb",
|
||||
RateLimit.userTagsClearPB,
|
||||
authenticateRequest,
|
||||
UserController.clearTagPb
|
||||
asyncHandlerWrapper(UserController.clearTagPb)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/remove",
|
||||
RateLimit.userTagsRemove,
|
||||
authenticateRequest,
|
||||
UserController.removeTag
|
||||
asyncHandlerWrapper(UserController.removeTag)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/edit",
|
||||
RateLimit.userTagsEdit,
|
||||
authenticateRequest,
|
||||
UserController.editTag
|
||||
asyncHandlerWrapper(UserController.editTag)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/discord/link",
|
||||
RateLimit.userDiscordLink,
|
||||
authenticateRequest,
|
||||
UserController.linkDiscord
|
||||
asyncHandlerWrapper(UserController.linkDiscord)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/discord/unlink",
|
||||
RateLimit.userDiscordUnlink,
|
||||
authenticateRequest,
|
||||
UserController.unlinkDiscord
|
||||
asyncHandlerWrapper(UserController.unlinkDiscord)
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
Loading…
Add table
Reference in a new issue