mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-06 13:40:16 +08:00
Add request validation to user endpoints (#2423) by Bruception
* Add request validation to user endpoints * Remove tag id log * Remove verbs from endpoints * Remove old code * Remove uid * Fix * Remove name from URI * Rename utils * Fix
This commit is contained in:
parent
0907e964db
commit
76bcc4bd56
16 changed files with 261 additions and 301 deletions
|
@ -1,3 +0,0 @@
|
|||
class CoreController {
|
||||
static async handleTestResult() {}
|
||||
}
|
|
@ -9,79 +9,93 @@ const fetch = require("node-fetch");
|
|||
const Logger = require("./../../handlers/logger.js");
|
||||
const uaparser = require("ua-parser-js");
|
||||
|
||||
// import UsersDAO from "../../dao/user";
|
||||
// import BotDAO from "../../dao/bot";
|
||||
// import { isUsernameValid } from "../../handlers/validation";
|
||||
|
||||
class UserController {
|
||||
static async createNewUser(req, res) {
|
||||
const { name } = req.body;
|
||||
const { email, uid } = req.ctx.decodedToken;
|
||||
|
||||
await UsersDAO.addUser(name, email, uid);
|
||||
Logger.log("user_created", `${name} ${email}`, uid);
|
||||
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async deleteUser(req, res) {
|
||||
const { uid } = req.ctx.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) {
|
||||
const { uid } = req.ctx.decodedToken;
|
||||
const { name } = req.body;
|
||||
if (!isUsernameValid(name))
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const 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.ctx.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))
|
||||
const { name } = req.params;
|
||||
|
||||
if (!isUsernameValid(name)) {
|
||||
throw new MonkeyError(
|
||||
400,
|
||||
"Username invalid. Name cannot contain special characters or contain more than 14 characters. Can include _ . and -"
|
||||
);
|
||||
}
|
||||
|
||||
const available = await UsersDAO.isNameAvailable(name);
|
||||
if (!available)
|
||||
if (!available) {
|
||||
return res.status(400).json({ message: "Username unavailable" });
|
||||
}
|
||||
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async updateEmail(req, res) {
|
||||
const { uid } = req.ctx.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);
|
||||
}
|
||||
|
||||
static async getUser(req, res) {
|
||||
static async getUser(req, _res) {
|
||||
const { email, uid } = req.ctx.decodedToken;
|
||||
|
||||
let userInfo;
|
||||
try {
|
||||
userInfo = await UsersDAO.getUser(uid);
|
||||
|
@ -122,10 +136,11 @@ class UserController {
|
|||
agent.device.type;
|
||||
}
|
||||
Logger.log("user_data_requested", logobj, uid);
|
||||
return res.status(200).json(userInfo);
|
||||
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
static async linkDiscord(req, res) {
|
||||
static async linkDiscord(req, _res) {
|
||||
const { uid } = req.ctx.decodedToken;
|
||||
|
||||
let requser;
|
||||
|
@ -167,14 +182,16 @@ class UserController {
|
|||
await UsersDAO.linkDiscord(uid, did);
|
||||
await BotDAO.linkDiscord(uid, did);
|
||||
Logger.log("user_discord_link", `linked to ${did}`, uid);
|
||||
return res.status(200).json({
|
||||
|
||||
return {
|
||||
message: "Discord account linked",
|
||||
did,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
static async unlinkDiscord(req, res) {
|
||||
const { uid } = req.ctx.decodedToken;
|
||||
|
||||
let userInfo;
|
||||
try {
|
||||
userInfo = await UsersDAO.getUser(uid);
|
||||
|
@ -187,58 +204,56 @@ class UserController {
|
|||
await BotDAO.unlinkDiscord(uid, userInfo.discordId);
|
||||
await UsersDAO.unlinkDiscord(uid);
|
||||
Logger.log("user_discord_unlinked", userInfo.discordId, uid);
|
||||
return res.status(200).send();
|
||||
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async addTag(req, res) {
|
||||
static async addTag(req, _res) {
|
||||
const { uid } = req.ctx.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);
|
||||
|
||||
return await UsersDAO.addTag(uid, tagName);
|
||||
}
|
||||
|
||||
static async clearTagPb(req, res) {
|
||||
const { uid } = req.ctx.decodedToken;
|
||||
const { tagid } = req.body;
|
||||
await UsersDAO.removeTagPb(uid, tagid);
|
||||
const { tagId } = req.params;
|
||||
|
||||
await UsersDAO.removeTagPb(uid, tagId);
|
||||
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async editTag(req, res) {
|
||||
const { uid } = req.ctx.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);
|
||||
const { tagId, newName } = req.body;
|
||||
|
||||
await UsersDAO.editTag(uid, tagId, newName);
|
||||
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async removeTag(req, res) {
|
||||
const { uid } = req.ctx.decodedToken;
|
||||
const { tagid } = req.body;
|
||||
await UsersDAO.removeTag(uid, tagid);
|
||||
const { tagId } = req.params;
|
||||
|
||||
await UsersDAO.removeTag(uid, tagId);
|
||||
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
|
||||
static async getTags(req, res) {
|
||||
static async getTags(req, _res) {
|
||||
const { uid } = req.ctx.decodedToken;
|
||||
let tags = await UsersDAO.getTags(uid);
|
||||
if (tags == undefined) tags = [];
|
||||
return res.status(200).json(tags);
|
||||
|
||||
return await UsersDAO.getTags(uid);
|
||||
}
|
||||
|
||||
static async updateLbMemory(req, res) {
|
||||
const { uid } = req.ctx.decodedToken;
|
||||
const { mode, mode2, language, rank } = req.body;
|
||||
|
||||
await UsersDAO.updateLbMemory(uid, mode, mode2, language, rank);
|
||||
|
||||
return res.sendStatus(200);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
const { Router } = require("express");
|
||||
const { authenticateRequest } = require("../../middlewares/auth");
|
||||
const {
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
asyncHandler,
|
||||
validateRequest,
|
||||
} = require("../../middlewares/api-utils");
|
||||
const configSchema = require("../schemas/config-schema");
|
||||
const ConfigController = require("../controllers/config");
|
||||
|
@ -14,19 +14,19 @@ router.get(
|
|||
"/",
|
||||
RateLimit.configGet,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(ConfigController.getConfig)
|
||||
asyncHandler(ConfigController.getConfig)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/save",
|
||||
RateLimit.configUpdate,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
config: configSchema,
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(ConfigController.saveConfig)
|
||||
asyncHandler(ConfigController.saveConfig)
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
const { authenticateRequest } = require("../../middlewares/auth");
|
||||
const { Router } = require("express");
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.post("/test", authenticateRequest);
|
|
@ -3,8 +3,8 @@ const { authenticateRequest } = require("../../middlewares/auth");
|
|||
const LeaderboardsController = require("../controllers/leaderboards");
|
||||
const RateLimit = require("../../middlewares/rate-limit");
|
||||
const {
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
asyncHandler,
|
||||
validateRequest,
|
||||
} = require("../../middlewares/api-utils");
|
||||
|
||||
const { Router } = require("express");
|
||||
|
@ -15,7 +15,7 @@ router.get(
|
|||
"/",
|
||||
RateLimit.leaderboardsGet,
|
||||
authenticateRequest({ isPublic: true }),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
query: {
|
||||
language: joi.string().required(),
|
||||
mode: joi.string().required(),
|
||||
|
@ -25,14 +25,14 @@ router.get(
|
|||
},
|
||||
validationErrorMessage: "Missing parameters",
|
||||
}),
|
||||
asyncHandlerWrapper(LeaderboardsController.get)
|
||||
asyncHandler(LeaderboardsController.get)
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/rank",
|
||||
RateLimit.leaderboardsGet,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
query: {
|
||||
language: joi.string().required(),
|
||||
mode: joi.string().required(),
|
||||
|
@ -40,7 +40,7 @@ router.get(
|
|||
},
|
||||
validationErrorMessage: "Missing parameters",
|
||||
}),
|
||||
asyncHandlerWrapper(LeaderboardsController.getRank)
|
||||
asyncHandler(LeaderboardsController.getRank)
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -4,8 +4,8 @@ const PresetController = require("../controllers/preset");
|
|||
const RateLimit = require("../../middlewares/rate-limit");
|
||||
const configSchema = require("../schemas/config-schema");
|
||||
const {
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
asyncHandler,
|
||||
validateRequest,
|
||||
} = require("../../middlewares/api-utils");
|
||||
|
||||
const { Router } = require("express");
|
||||
|
@ -26,14 +26,14 @@ router.get(
|
|||
"/",
|
||||
RateLimit.presetsGet,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(PresetController.getPresets)
|
||||
asyncHandler(PresetController.getPresets)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/add",
|
||||
RateLimit.presetsAdd,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
name: presetNameSchema,
|
||||
config: configSchema.keys({
|
||||
|
@ -41,14 +41,14 @@ router.post(
|
|||
}),
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(PresetController.addPreset)
|
||||
asyncHandler(PresetController.addPreset)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/edit",
|
||||
RateLimit.presetsEdit,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
_id: joi.string().required(),
|
||||
name: presetNameSchema,
|
||||
|
@ -59,19 +59,19 @@ router.post(
|
|||
.allow(null),
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(PresetController.editPreset)
|
||||
asyncHandler(PresetController.editPreset)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/remove",
|
||||
RateLimit.presetsRemove,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
_id: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(PresetController.removePreset)
|
||||
asyncHandler(PresetController.removePreset)
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
const PsaController = require("../controllers/psa");
|
||||
const RateLimit = require("../../middlewares/rate-limit");
|
||||
const {
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
} = require("../../middlewares/api-utils");
|
||||
const { asyncHandler } = require("../../middlewares/api-utils");
|
||||
|
||||
const { Router } = require("express");
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get("/", RateLimit.psaGet, asyncHandlerWrapper(PsaController.get));
|
||||
router.get("/", RateLimit.psaGet, asyncHandler(PsaController.get));
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -6,8 +6,8 @@ const QuoteRatingsController = require("../controllers/quote-ratings");
|
|||
const QuotesController = require("../controllers/quotes");
|
||||
const RateLimit = require("../../middlewares/rate-limit");
|
||||
const {
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
asyncHandler,
|
||||
validateRequest,
|
||||
validateConfiguration,
|
||||
} = require("../../middlewares/api-utils");
|
||||
const SUPPORTED_QUOTE_LANGUAGES = require("../../constants/quote-languages");
|
||||
|
@ -18,7 +18,7 @@ quotesRouter.get(
|
|||
"/",
|
||||
RateLimit.newQuotesGet,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(NewQuotesController.getQuotes)
|
||||
asyncHandler(NewQuotesController.getQuotes)
|
||||
);
|
||||
|
||||
quotesRouter.post(
|
||||
|
@ -32,7 +32,7 @@ quotesRouter.post(
|
|||
}),
|
||||
RateLimit.newQuotesAdd,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
text: joi.string().min(60).required(),
|
||||
source: joi.string().required(),
|
||||
|
@ -41,14 +41,14 @@ quotesRouter.post(
|
|||
},
|
||||
validationErrorMessage: "Please fill all the fields",
|
||||
}),
|
||||
asyncHandlerWrapper(NewQuotesController.addQuote)
|
||||
asyncHandler(NewQuotesController.addQuote)
|
||||
);
|
||||
|
||||
quotesRouter.post(
|
||||
"/approve",
|
||||
RateLimit.newQuotesAction,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
quoteId: joi.string().required(),
|
||||
editText: joi.string().required(),
|
||||
|
@ -56,46 +56,46 @@ quotesRouter.post(
|
|||
},
|
||||
validationErrorMessage: "Please fill all the fields",
|
||||
}),
|
||||
asyncHandlerWrapper(NewQuotesController.approve)
|
||||
asyncHandler(NewQuotesController.approve)
|
||||
);
|
||||
|
||||
quotesRouter.post(
|
||||
"/reject",
|
||||
RateLimit.newQuotesAction,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
quoteId: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(NewQuotesController.refuse)
|
||||
asyncHandler(NewQuotesController.refuse)
|
||||
);
|
||||
|
||||
quotesRouter.get(
|
||||
"/rating",
|
||||
RateLimit.quoteRatingsGet,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
query: {
|
||||
quoteId: joi.string().regex(/^\d+$/).required(),
|
||||
language: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(QuoteRatingsController.getRating)
|
||||
asyncHandler(QuoteRatingsController.getRating)
|
||||
);
|
||||
|
||||
quotesRouter.post(
|
||||
"/rating",
|
||||
RateLimit.quoteRatingsSubmit,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
quoteId: joi.number().required(),
|
||||
rating: joi.number().min(1).max(5).required(),
|
||||
language: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(QuoteRatingsController.submitRating)
|
||||
asyncHandler(QuoteRatingsController.submitRating)
|
||||
);
|
||||
|
||||
quotesRouter.post(
|
||||
|
@ -108,7 +108,7 @@ quotesRouter.post(
|
|||
}),
|
||||
RateLimit.quoteReportSubmit,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
quoteId: joi.string().required(),
|
||||
quoteLanguage: joi
|
||||
|
@ -128,7 +128,7 @@ quotesRouter.post(
|
|||
captcha: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(QuotesController.reportQuote)
|
||||
asyncHandler(QuotesController.reportQuote)
|
||||
);
|
||||
|
||||
module.exports = quotesRouter;
|
||||
|
|
|
@ -4,8 +4,8 @@ const { Router } = require("express");
|
|||
const ResultController = require("../controllers/result");
|
||||
const RateLimit = require("../../middlewares/rate-limit");
|
||||
const {
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
asyncHandler,
|
||||
validateRequest,
|
||||
} = require("../../middlewares/api-utils");
|
||||
const resultSchema = require("../schemas/result-schema");
|
||||
|
||||
|
@ -15,39 +15,39 @@ router.get(
|
|||
"/",
|
||||
RateLimit.resultsGet,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(ResultController.getResults)
|
||||
asyncHandler(ResultController.getResults)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/add",
|
||||
RateLimit.resultsAdd,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
result: resultSchema,
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(ResultController.addResult)
|
||||
asyncHandler(ResultController.addResult)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateTags",
|
||||
RateLimit.resultsTagsUpdate,
|
||||
authenticateRequest(),
|
||||
requestValidation({
|
||||
validateRequest({
|
||||
body: {
|
||||
tags: joi.array().items(joi.string()).required(),
|
||||
resultid: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandlerWrapper(ResultController.updateTags)
|
||||
asyncHandler(ResultController.updateTags)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/deleteAll",
|
||||
RateLimit.resultsDeleteAll,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(ResultController.deleteAll)
|
||||
asyncHandler(ResultController.deleteAll)
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -1,116 +1,193 @@
|
|||
const joi = require("joi");
|
||||
const { authenticateRequest } = require("../../middlewares/auth");
|
||||
const { Router } = require("express");
|
||||
const UserController = require("../controllers/user");
|
||||
const RateLimit = require("../../middlewares/rate-limit");
|
||||
const {
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
asyncHandler,
|
||||
validateRequest,
|
||||
} = require("../../middlewares/api-utils");
|
||||
|
||||
const router = Router();
|
||||
|
||||
const tagNameValidation = joi
|
||||
.string()
|
||||
.required()
|
||||
.regex(/^[0-9a-zA-Z_.-]+$/)
|
||||
.max(16)
|
||||
.messages({
|
||||
"string.pattern.base":
|
||||
"Tag name invalid. Name cannot contain special characters or more than 16 characters. Can include _ . and -",
|
||||
"string.max": "Tag name exceeds maximum of 16 characters",
|
||||
});
|
||||
|
||||
router.get(
|
||||
"/",
|
||||
RateLimit.userGet,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.getUser)
|
||||
asyncHandler(UserController.getUser)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/signup",
|
||||
RateLimit.userSignup,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.createNewUser)
|
||||
validateRequest({
|
||||
body: {
|
||||
email: joi.string().email(),
|
||||
name: joi.string().required(),
|
||||
uid: joi.string(),
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.createNewUser)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/checkName",
|
||||
router.get(
|
||||
"/checkName/:name",
|
||||
RateLimit.userCheckName,
|
||||
asyncHandlerWrapper(UserController.checkName)
|
||||
validateRequest({
|
||||
params: {
|
||||
name: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.checkName)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/delete",
|
||||
router.delete(
|
||||
"/",
|
||||
RateLimit.userDelete,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.deleteUser)
|
||||
asyncHandler(UserController.deleteUser)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateName",
|
||||
router.patch(
|
||||
"/name",
|
||||
RateLimit.userUpdateName,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.updateName)
|
||||
validateRequest({
|
||||
body: {
|
||||
name: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.updateName)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateLbMemory",
|
||||
router.patch(
|
||||
"/leaderboardMemory",
|
||||
RateLimit.userUpdateLBMemory,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.updateLbMemory)
|
||||
validateRequest({
|
||||
body: {
|
||||
mode: joi
|
||||
.string()
|
||||
.valid("time", "words", "quote", "zen", "custom")
|
||||
.required(),
|
||||
mode2: joi.alternatives().try(joi.number(), joi.string()).required(),
|
||||
language: joi.string().required(),
|
||||
rank: joi.number().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.updateLbMemory)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/updateEmail",
|
||||
router.patch(
|
||||
"/email",
|
||||
RateLimit.userUpdateEmail,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.updateEmail)
|
||||
validateRequest({
|
||||
body: {
|
||||
uid: joi.string().required(),
|
||||
newEmail: joi.string().email().required(),
|
||||
previousEmail: joi.string().email().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.updateEmail)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/clearPb",
|
||||
router.delete(
|
||||
"/personalBests",
|
||||
RateLimit.userClearPB,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.clearPb)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/add",
|
||||
RateLimit.userTagsAdd,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.addTag)
|
||||
asyncHandler(UserController.clearPb)
|
||||
);
|
||||
|
||||
router.get(
|
||||
"/tags",
|
||||
RateLimit.userTagsGet,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.getTags)
|
||||
asyncHandler(UserController.getTags)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/clearPb",
|
||||
RateLimit.userTagsClearPB,
|
||||
"/tags",
|
||||
RateLimit.userTagsAdd,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.clearTagPb)
|
||||
validateRequest({
|
||||
body: {
|
||||
tagName: tagNameValidation,
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.addTag)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/remove",
|
||||
RateLimit.userTagsRemove,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.removeTag)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/tags/edit",
|
||||
router.patch(
|
||||
"/tags",
|
||||
RateLimit.userTagsEdit,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.editTag)
|
||||
validateRequest({
|
||||
body: {
|
||||
tagId: joi.string().required(),
|
||||
newName: tagNameValidation,
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.editTag)
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/tags/:tagId",
|
||||
RateLimit.userTagsRemove,
|
||||
authenticateRequest(),
|
||||
validateRequest({
|
||||
params: {
|
||||
tagId: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.removeTag)
|
||||
);
|
||||
|
||||
router.delete(
|
||||
"/tags/:tagId/personalBest",
|
||||
RateLimit.userTagsClearPB,
|
||||
authenticateRequest(),
|
||||
validateRequest({
|
||||
params: {
|
||||
tagId: joi.string().required(),
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.clearTagPb)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/discord/link",
|
||||
RateLimit.userDiscordLink,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.linkDiscord)
|
||||
validateRequest({
|
||||
body: {
|
||||
data: joi.object({
|
||||
tokenType: joi.string().required(),
|
||||
accessToken: joi.string().required(),
|
||||
uid: joi.string().required(),
|
||||
}),
|
||||
},
|
||||
}),
|
||||
asyncHandler(UserController.linkDiscord)
|
||||
);
|
||||
|
||||
router.post(
|
||||
"/discord/unlink",
|
||||
RateLimit.userDiscordUnlink,
|
||||
authenticateRequest(),
|
||||
asyncHandlerWrapper(UserController.unlinkDiscord)
|
||||
asyncHandler(UserController.unlinkDiscord)
|
||||
);
|
||||
|
||||
module.exports = router;
|
||||
|
|
|
@ -30,7 +30,7 @@ function validateConfiguration(options) {
|
|||
* Without this, any errors thrown will not be caught by the error handling middleware, and
|
||||
* the app will hang!
|
||||
*/
|
||||
function asyncHandlerWrapper(handler) {
|
||||
function asyncHandler(handler) {
|
||||
return async (req, res, next) => {
|
||||
try {
|
||||
const handlerData = await handler(req, res);
|
||||
|
@ -49,7 +49,7 @@ function asyncHandlerWrapper(handler) {
|
|||
};
|
||||
}
|
||||
|
||||
function requestValidation(validationSchema) {
|
||||
function validateRequest(validationSchema) {
|
||||
/**
|
||||
* In dev environments, as an alternative to token authentication,
|
||||
* you can pass the authentication middleware by having a user id in the body.
|
||||
|
@ -89,6 +89,6 @@ function requestValidation(validationSchema) {
|
|||
|
||||
module.exports = {
|
||||
validateConfiguration,
|
||||
asyncHandlerWrapper,
|
||||
requestValidation,
|
||||
asyncHandler,
|
||||
validateRequest,
|
||||
};
|
||||
|
|
|
@ -215,7 +215,7 @@ export async function signInWithGoogle() {
|
|||
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/checkName", { name });
|
||||
response = await axiosInstance.get(`/user/checkName/${name}`);
|
||||
} catch (e) {
|
||||
let msg = e?.response?.data?.message ?? e.message;
|
||||
if (e.response.status >= 500) {
|
||||
|
@ -275,7 +275,7 @@ export async function signInWithGoogle() {
|
|||
$(".pageLogin .button").removeClass("disabled");
|
||||
if (signedInUser?.user) {
|
||||
signedInUser.user.delete();
|
||||
axiosInstance.post("/user/delete", { uid: signedInUser.user.uid });
|
||||
await axiosInstance.delete("/user");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -431,9 +431,7 @@ async function signUp() {
|
|||
}
|
||||
|
||||
try {
|
||||
await axiosInstance.post("/user/checkName", {
|
||||
name: nname,
|
||||
});
|
||||
await axiosInstance.get(`/user/checkName/${nname}`);
|
||||
} catch (e) {
|
||||
let txt;
|
||||
if (e.response) {
|
||||
|
@ -465,29 +463,28 @@ async function signUp() {
|
|||
await createdAuthUser.user.sendEmailVerification();
|
||||
AllTimeStats.clear();
|
||||
Notifications.add("Account created", 1, 3);
|
||||
throw "test";
|
||||
// $("#menu .icon-button.account .text").text(nname);
|
||||
// $(".pageLogin .button").removeClass("disabled");
|
||||
// $(".pageLogin .preloader").addClass("hidden");
|
||||
// await loadUser(createdAuthUser.user);
|
||||
// if (TestLogic.notSignedInLastResult !== null) {
|
||||
// TestLogic.setNotSignedInUid(createdAuthUser.user.uid);
|
||||
// axiosInstance
|
||||
// .post("/results/add", {
|
||||
// result: TestLogic.notSignedInLastResult,
|
||||
// })
|
||||
// .then((result) => {
|
||||
// if (result.status === 200) {
|
||||
// DB.getSnapshot().results.push(TestLogic.notSignedInLastResult);
|
||||
// }
|
||||
// });
|
||||
// UI.changePage("account");
|
||||
// }
|
||||
$("#menu .icon-button.account .text").text(nname);
|
||||
$(".pageLogin .button").removeClass("disabled");
|
||||
$(".pageLogin .preloader").addClass("hidden");
|
||||
await loadUser(createdAuthUser.user);
|
||||
if (TestLogic.notSignedInLastResult !== null) {
|
||||
TestLogic.setNotSignedInUid(createdAuthUser.user.uid);
|
||||
axiosInstance
|
||||
.post("/results/add", {
|
||||
result: TestLogic.notSignedInLastResult,
|
||||
})
|
||||
.then((result) => {
|
||||
if (result.status === 200) {
|
||||
DB.getSnapshot().results.push(TestLogic.notSignedInLastResult);
|
||||
}
|
||||
});
|
||||
UI.changePage("account");
|
||||
}
|
||||
} catch (e) {
|
||||
//make sure to do clean up here
|
||||
if (createdAuthUser) {
|
||||
await createdAuthUser.user.delete();
|
||||
axiosInstance.post("/user/delete");
|
||||
axiosInstance.delete("/user");
|
||||
}
|
||||
let txt;
|
||||
if (e.response) {
|
||||
|
@ -502,119 +499,6 @@ async function signUp() {
|
|||
$(".pageLogin .button").removeClass("disabled");
|
||||
return;
|
||||
}
|
||||
|
||||
// return;
|
||||
|
||||
// axiosInstance.get(`/nameCheck/${nname}`).then((d) => {
|
||||
// console.log(d.data);
|
||||
// if (d.data.resultCode === -1) {
|
||||
// Notifications.add("Name unavailable", -1);
|
||||
// $(".pageLogin .preloader").addClass("hidden");
|
||||
// $(".pageLogin .register .button").removeClass("disabled");
|
||||
// return;
|
||||
// } else if (d.data.resultCode === -2) {
|
||||
// Notifications.add(
|
||||
// "Name cannot contain special characters or contain more than 14 characters. Can include _ . and -",
|
||||
// -1
|
||||
// );
|
||||
// $(".pageLogin .preloader").addClass("hidden");
|
||||
// $(".pageLogin .register .button").removeClass("disabled");
|
||||
// return;
|
||||
// } else if (d.data.resultCode === 1) {
|
||||
// firebase
|
||||
// .auth()
|
||||
// .createUserWithEmailAndPassword(email, password)
|
||||
// .then((user) => {
|
||||
// // Account has been created here.
|
||||
// // dontCheckUserName = true;
|
||||
// let usr = user.user;
|
||||
// //maybe there's a better place for the api call
|
||||
// axiosInstance.post("/signUp", {
|
||||
// name: nname,
|
||||
// uid: usr.uid,
|
||||
// email: email,
|
||||
// });
|
||||
// usr
|
||||
// .updateProfile({
|
||||
// displayName: nname,
|
||||
// })
|
||||
// .then(async function () {
|
||||
// // Update successful.
|
||||
// usr.sendEmailVerification();
|
||||
// AllTimeStats.clear();
|
||||
// Notifications.add("Account created", 1, 3);
|
||||
// $("#menu .icon-button.account .text").text(nname);
|
||||
// try {
|
||||
// firebase.analytics().logEvent("accountCreated", usr.uid);
|
||||
// } catch (e) {
|
||||
// console.log("Analytics unavailable");
|
||||
// }
|
||||
// $(".pageLogin .preloader").addClass("hidden");
|
||||
// DB.setSnapshot({
|
||||
// results: [],
|
||||
// personalBests: {},
|
||||
// tags: [],
|
||||
// globalStats: {
|
||||
// time: undefined,
|
||||
// started: undefined,
|
||||
// completed: undefined,
|
||||
// },
|
||||
// });
|
||||
// if (TestLogic.notSignedInLastResult !== null) {
|
||||
// TestLogic.setNotSignedInUid(usr.uid);
|
||||
// axiosInstance
|
||||
// .post("/testCompleted", {
|
||||
// obj: TestLogic.notSignedInLastResult,
|
||||
// })
|
||||
// .then(() => {
|
||||
// DB.getSnapshot().results.push(
|
||||
// TestLogic.notSignedInLastResult
|
||||
// );
|
||||
// });
|
||||
// }
|
||||
// UI.changePage("account");
|
||||
// usr.sendEmailVerification();
|
||||
// $(".pageLogin .register .button").removeClass("disabled");
|
||||
// })
|
||||
// .catch(function (error) {
|
||||
// // An error happened.
|
||||
// $(".pageLogin .register .button").removeClass("disabled");
|
||||
// console.error(error);
|
||||
// usr
|
||||
// .delete()
|
||||
// .then(function () {
|
||||
// // User deleted.
|
||||
// Notifications.add(
|
||||
// "Account not created. " + error.message,
|
||||
// -1
|
||||
// );
|
||||
// $(".pageLogin .preloader").addClass("hidden");
|
||||
// })
|
||||
// .catch(function (error) {
|
||||
// // An error happened.
|
||||
// $(".pageLogin .preloader").addClass("hidden");
|
||||
// Notifications.add(
|
||||
// "Something went wrong. " + error.message,
|
||||
// -1
|
||||
// );
|
||||
// console.error(error);
|
||||
// });
|
||||
// });
|
||||
// })
|
||||
// .catch(function (error) {
|
||||
// // Handle Errors here.
|
||||
// $(".pageLogin .register .button").removeClass("disabled");
|
||||
// Notifications.add(error.message, -1);
|
||||
// $(".pageLogin .preloader").addClass("hidden");
|
||||
// });
|
||||
// } else {
|
||||
// $(".pageLogin .preloader").addClass("hidden");
|
||||
// Notifications.add(
|
||||
// "Something went wrong when checking name: " + d.data.message,
|
||||
// -1
|
||||
// );
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
$(".pageLogin #forgotPasswordButton").click((e) => {
|
||||
|
|
|
@ -10,8 +10,8 @@ let dbSnapshot = null;
|
|||
|
||||
export function updateName(uid, name) {
|
||||
//TODO update
|
||||
axiosInstance.post("/updateName", {
|
||||
name: name,
|
||||
axiosInstance.patch("/user/name", {
|
||||
name,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -559,7 +559,7 @@ export function updateLbMemory(mode, mode2, language, rank, api = false) {
|
|||
let current = dbSnapshot.lbMemory[mode][mode2][language];
|
||||
dbSnapshot.lbMemory[mode][mode2][language] = rank;
|
||||
if (api && current != rank) {
|
||||
axiosInstance.post("/user/updateLbMemory", {
|
||||
axiosInstance.patch("/user/leaderboardMemory", {
|
||||
mode,
|
||||
mode2,
|
||||
language,
|
||||
|
|
|
@ -121,7 +121,7 @@ export async function getDataAndInit() {
|
|||
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/updateName", { name });
|
||||
response = await axiosInstance.patch("/user/name", { name });
|
||||
} catch (e) {
|
||||
let msg = e?.response?.data?.message ?? e.message;
|
||||
if (e.response.status >= 500) {
|
||||
|
|
|
@ -74,7 +74,7 @@ async function apply() {
|
|||
Loader.show();
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/tags/add", {
|
||||
response = await axiosInstance.post("/user/tags", {
|
||||
tagName: inputVal,
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -100,9 +100,9 @@ async function apply() {
|
|||
Loader.show();
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/tags/edit", {
|
||||
tagid,
|
||||
newname: inputVal,
|
||||
response = await axiosInstance.patch("/user/tags", {
|
||||
tagId: tagid,
|
||||
newName: inputVal,
|
||||
});
|
||||
} catch (e) {
|
||||
Loader.hide();
|
||||
|
@ -128,7 +128,7 @@ async function apply() {
|
|||
Loader.show();
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/tags/remove", { tagid });
|
||||
response = await axiosInstance.delete(`/user/tags/${tagid}`);
|
||||
} catch (e) {
|
||||
Loader.hide();
|
||||
let msg = e?.response?.data?.message ?? e.message;
|
||||
|
@ -153,7 +153,7 @@ async function apply() {
|
|||
Loader.show();
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/tags/clearPb", { tagid });
|
||||
response = await axiosInstance.delete(`/user/tags/${tagid}/personalBest`);
|
||||
} catch (e) {
|
||||
Loader.hide();
|
||||
let msg = e?.response?.data?.message ?? e.message;
|
||||
|
|
|
@ -214,7 +214,7 @@ list.updateEmail = new SimplePopup(
|
|||
Loader.show();
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/updateEmail", {
|
||||
response = await axiosInstance.patch("/user/email", {
|
||||
uid: user.uid,
|
||||
previousEmail: user.email,
|
||||
newEmail: email,
|
||||
|
@ -284,9 +284,7 @@ list.updateName = new SimplePopup(
|
|||
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/checkName", {
|
||||
name: newName,
|
||||
});
|
||||
response = await axiosInstance.get(`/user/checkName/${newName}`);
|
||||
} catch (e) {
|
||||
Loader.hide();
|
||||
let msg = e?.response?.data?.message ?? e.message;
|
||||
|
@ -299,7 +297,7 @@ list.updateName = new SimplePopup(
|
|||
return;
|
||||
}
|
||||
try {
|
||||
response = await axiosInstance.post("/user/updateName", {
|
||||
response = await axiosInstance.patch("/user/name", {
|
||||
name: newName,
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -468,7 +466,7 @@ list.deleteAccount = new SimplePopup(
|
|||
Notifications.add("Deleting stats...", 0);
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/delete");
|
||||
response = await axiosInstance.delete("/user");
|
||||
} catch (e) {
|
||||
Loader.hide();
|
||||
let msg = e?.response?.data?.message ?? e.message;
|
||||
|
@ -529,9 +527,7 @@ list.clearTagPb = new SimplePopup(
|
|||
let tagid = eval("this.parameters[0]");
|
||||
Loader.show();
|
||||
axiosInstance
|
||||
.post("/user/tags/clearPb", {
|
||||
tagid: tagid,
|
||||
})
|
||||
.delete(`/user/tags/${tagid}/clearPb`)
|
||||
.then((res) => {
|
||||
Loader.hide();
|
||||
if (res.data.resultCode === 1) {
|
||||
|
@ -605,7 +601,7 @@ list.resetPersonalBests = new SimplePopup(
|
|||
|
||||
let response;
|
||||
try {
|
||||
response = await axiosInstance.post("/user/clearPb");
|
||||
response = await axiosInstance.delete("/user/personalBests");
|
||||
} catch (e) {
|
||||
Loader.hide();
|
||||
let msg = e?.response?.data?.message ?? e.message;
|
||||
|
|
Loading…
Add table
Reference in a new issue