monkeytype/backend/dao/user.js

314 lines
8 KiB
JavaScript
Raw Normal View History

2021-06-07 01:26:12 +08:00
const MonkeyError = require("../handlers/error");
2021-06-07 00:32:37 +08:00
const { mongoDB } = require("../init/mongodb");
2021-07-10 00:21:16 +08:00
const { ObjectID } = require("mongodb");
const { checkAndUpdatePb } = require("../handlers/pb");
const { updateAuthEmail } = require("../handlers/auth");
2021-06-07 00:32:37 +08:00
class UsersDAO {
static async addUser(name, email, uid) {
return await mongoDB()
.collection("users")
.insertOne({ name, email, uid, addedAt: Date.now() });
}
static async deleteUser(uid) {
return await mongoDB().collection("users").deleteOne({ uid });
}
2021-06-07 00:32:37 +08:00
static async updateName(uid, name) {
const nameDoc = await mongoDB()
.collection("users")
.findOne({ name: { $regex: new RegExp(`^${name}$`, "i") } });
2021-06-07 01:26:12 +08:00
if (nameDoc) throw new MonkeyError(409, "Username already taken");
2021-06-07 00:32:37 +08:00
return await mongoDB()
.collection("users")
.updateOne({ uid }, { $set: { name } });
}
2021-07-13 06:34:55 +08:00
static async clearPb(uid) {
return await mongoDB()
.collection("users")
.updateOne({ uid }, { $set: { personalBests: {} } });
}
2021-06-16 07:45:28 +08:00
static async isNameAvailable(name) {
const nameDoc = await mongoDB().collection("users").findOne({ name });
if (nameDoc) {
2021-06-16 07:45:28 +08:00
return false;
} else {
return true;
}
}
static async updateEmail(uid, email) {
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
2021-07-13 06:12:03 +08:00
await updateAuthEmail(uid, email);
await mongoDB().collection("users").updateOne({ uid }, { $set: { email } });
return true;
}
2021-06-07 00:32:37 +08:00
static async getUser(uid) {
const user = await mongoDB().collection("users").findOne({ uid });
2021-06-07 01:26:12 +08:00
if (!user) throw new MonkeyError(404, "User not found");
2021-06-07 00:32:37 +08:00
return user;
}
2021-06-09 05:57:58 +08:00
static async getUserByDiscordId(discordId) {
const user = await mongoDB().collection("users").findOne({ discordId });
if (!user) throw new MonkeyError(404, "User not found");
return user;
}
2021-06-09 05:57:58 +08:00
static async addTag(uid, name) {
2021-07-10 00:21:16 +08:00
let _id = ObjectID();
2021-07-09 06:27:47 +08:00
await mongoDB()
2021-06-09 05:57:58 +08:00
.collection("users")
2021-07-10 00:21:16 +08:00
.updateOne({ uid }, { $push: { tags: { _id, name } } });
2021-07-09 06:27:47 +08:00
return {
2021-07-10 00:21:16 +08:00
_id,
2021-07-09 06:27:47 +08:00
name,
};
2021-06-09 05:57:58 +08:00
}
static async getTags(uid) {
2021-06-13 00:51:58 +08:00
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
return user.tags;
}
2021-07-10 00:21:16 +08:00
static async editTag(uid, _id, name) {
2021-06-09 05:57:58 +08:00
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
if (
user.tags === undefined ||
2021-07-10 00:21:16 +08:00
user.tags.filter((t) => t._id == _id).length === 0
2021-06-09 05:57:58 +08:00
)
throw new MonkeyError(404, "Tag not found");
return await mongoDB()
.collection("users")
.updateOne(
{
uid: uid,
2021-07-10 00:21:16 +08:00
"tags._id": ObjectID(_id),
2021-06-09 05:57:58 +08:00
},
2021-07-08 23:03:52 +08:00
{ $set: { "tags.$.name": name } }
2021-06-09 05:57:58 +08:00
);
}
2021-07-10 00:21:16 +08:00
static async removeTag(uid, _id) {
2021-06-09 05:57:58 +08:00
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
if (
user.tags === undefined ||
2021-07-10 00:21:16 +08:00
user.tags.filter((t) => t._id == _id).length === 0
2021-06-09 05:57:58 +08:00
)
throw new MonkeyError(404, "Tag not found");
return await mongoDB()
.collection("users")
2021-07-08 23:03:52 +08:00
.updateOne(
{
uid: uid,
2021-07-10 00:21:16 +08:00
"tags._id": ObjectID(_id),
2021-07-08 23:03:52 +08:00
},
2021-07-10 00:21:16 +08:00
{ $pull: { tags: { _id: ObjectID(_id) } } }
2021-07-08 23:03:52 +08:00
);
2021-06-09 05:57:58 +08:00
}
2021-07-10 00:21:16 +08:00
static async removeTagPb(uid, _id) {
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
if (
user.tags === undefined ||
2021-07-10 00:21:16 +08:00
user.tags.filter((t) => t._id == _id).length === 0
)
throw new MonkeyError(404, "Tag not found");
return await mongoDB()
.collection("users")
.updateOne(
{
uid: uid,
2021-07-10 00:21:16 +08:00
"tags._id": ObjectID(_id),
},
2021-07-08 23:03:52 +08:00
{ $set: { "tags.$.personalBests": {} } }
);
}
static async checkIfPb(uid, result) {
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
const {
mode,
mode2,
acc,
consistency,
difficulty,
language,
punctuation,
rawWpm,
wpm,
2021-07-09 05:19:34 +08:00
funbox,
} = result;
2021-07-09 05:19:34 +08:00
if (funbox !== "none" && funbox !== "plus_one" && funbox !== "plus_two") {
return false;
}
let pb = checkAndUpdatePb(
user.personalBests,
mode,
mode2,
acc,
consistency,
difficulty,
language,
punctuation,
rawWpm,
wpm
);
if (pb.isPb) {
await mongoDB()
.collection("users")
.updateOne({ uid }, { $set: { personalBests: pb.obj } });
return true;
} else {
return false;
}
}
static async checkIfTagPb(uid, result) {
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
if (user.tags === undefined || user.tags.length === 0) {
return [];
}
const {
mode,
mode2,
acc,
consistency,
difficulty,
language,
punctuation,
rawWpm,
2021-06-14 03:18:23 +08:00
wpm,
tags,
2021-07-10 04:41:33 +08:00
funbox,
} = result;
2021-07-10 04:41:33 +08:00
if (funbox !== "none" && funbox !== "plus_one" && funbox !== "plus_two") {
return [];
}
2021-07-08 23:03:52 +08:00
if (mode === "quote") {
return [];
}
let tagsToCheck = [];
user.tags.forEach((tag) => {
2021-07-10 04:41:33 +08:00
tags.forEach((resultTag) => {
if (resultTag == tag._id) {
tagsToCheck.push(tag);
}
});
2021-07-08 23:03:52 +08:00
});
let ret = [];
2021-07-08 23:03:52 +08:00
tagsToCheck.forEach(async (tag) => {
let tagpb = checkAndUpdatePb(
tag.personalBests,
mode,
mode2,
acc,
consistency,
difficulty,
language,
punctuation,
rawWpm,
wpm
);
if (tagpb.isPb) {
2021-07-10 00:21:16 +08:00
ret.push(tag._id);
await mongoDB()
.collection("users")
2021-07-08 23:03:52 +08:00
.updateOne(
2021-07-10 00:21:16 +08:00
{ uid, "tags._id": ObjectID(tag._id) },
2021-07-08 23:03:52 +08:00
{ $set: { "tags.$.personalBests": tagpb.obj } }
);
}
});
return ret;
}
static async resetPb(uid) {
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
return await mongoDB()
.collection("users")
.updateOne({ uid }, { $set: { personalBests: {} } });
}
static async updateTypingStats(uid, restartCount, timeTyping) {
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
return await mongoDB()
.collection("users")
.updateOne(
{ uid },
{
$inc: {
startedTests: restartCount + 1,
completedTests: 1,
timeTyping,
},
}
);
}
static async linkDiscord(uid, discordId) {
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
return await mongoDB()
.collection("users")
.updateOne({ uid }, { $set: { discordId } });
}
static async unlinkDiscord(uid) {
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
return await mongoDB()
.collection("users")
.updateOne({ uid }, { $set: { discordId: null } });
}
2021-06-12 20:33:23 +08:00
static async incrementBananas(uid, wpm) {
2021-06-12 20:33:23 +08:00
const user = await mongoDB().collection("users").findOne({ uid });
if (!user) throw new MonkeyError(404, "User not found");
let best60;
try {
2021-06-12 20:33:23 +08:00
best60 = Math.max(...user.personalBests.time[60].map((best) => best.wpm));
} catch (e) {
2021-06-12 20:33:23 +08:00
best60 = undefined;
}
if (best60 === undefined || wpm >= best60 - best60 * 0.25) {
2021-06-12 20:33:23 +08:00
//increment when no record found or wpm is within 25% of the record
return await mongoDB()
.collection("users")
.updateOne({ uid }, { $inc: { bananas: 1 } });
} else {
2021-06-12 20:33:23 +08:00
return null;
}
}
2021-06-07 00:32:37 +08:00
}
module.exports = UsersDAO;