mirror of
https://github.com/zkldi/Tachi.git
synced 2026-10-14 01:59:05 +03:00
fix: invite thread safety
This commit is contained in:
Vendored
+1
@@ -156,6 +156,7 @@ const db = {
|
||||
"orphan-scores": monkDB.get<OrphanScoreDocument>("orphan-scores"),
|
||||
"import-locks": monkDB.get<{ userID: integer; locked: boolean }>("import-locks"),
|
||||
tables: monkDB.get<TableDocument>("tables"),
|
||||
"invite-locks": monkDB.get<{ userID: integer; locked: boolean }>("invite-locks"),
|
||||
"game-settings": monkDB.get<UGPTSettings>("game-settings"),
|
||||
"game-stats-snapshots": monkDB.get<UserGameStatsSnapshot>("game-stats-snapshots"),
|
||||
"session-view-cache": monkDB.get<SessionViewDocument>("session-view-cache"),
|
||||
|
||||
@@ -59,8 +59,6 @@ router.get("/limit", async (req, res) => {
|
||||
});
|
||||
});
|
||||
|
||||
const InviteLocks = new Set();
|
||||
|
||||
/**
|
||||
* Create a new invite.
|
||||
*
|
||||
@@ -68,19 +66,39 @@ const InviteLocks = new Set();
|
||||
*/
|
||||
router.post("/create", async (req, res) => {
|
||||
const user = GetTachiData(req, "requestedUser");
|
||||
const userID = user.id;
|
||||
|
||||
try {
|
||||
const lockExists = await db["invite-locks"].findOne({
|
||||
userID,
|
||||
});
|
||||
|
||||
if (!lockExists) {
|
||||
await db["invite-locks"].insert({
|
||||
userID,
|
||||
locked: false,
|
||||
});
|
||||
}
|
||||
|
||||
const isNotLocked = await db["invite-locks"].findOneAndUpdate(
|
||||
{
|
||||
userID,
|
||||
locked: false,
|
||||
},
|
||||
{
|
||||
$set: { locked: true },
|
||||
}
|
||||
);
|
||||
|
||||
// race condition protection
|
||||
// to avoid users double-creating invites.
|
||||
if (InviteLocks.has(user.id)) {
|
||||
if (!isNotLocked) {
|
||||
return res.status(409).json({
|
||||
success: false,
|
||||
description: `You already have an outgoing invite creation request.`,
|
||||
});
|
||||
}
|
||||
|
||||
InviteLocks.add(user.id);
|
||||
|
||||
const existingInvites = await db.invites.count({ createdBy: user.id });
|
||||
|
||||
if (
|
||||
@@ -112,7 +130,14 @@ router.post("/create", async (req, res) => {
|
||||
body: inviteDoc,
|
||||
});
|
||||
} finally {
|
||||
InviteLocks.delete(user.id);
|
||||
await db["invite-locks"].findOneAndUpdate(
|
||||
{
|
||||
userID,
|
||||
},
|
||||
{
|
||||
$set: { locked: false },
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user