diff --git a/server/src/external/mongo/db.ts b/server/src/external/mongo/db.ts index bd601ec90..af1f11eda 100644 --- a/server/src/external/mongo/db.ts +++ b/server/src/external/mongo/db.ts @@ -156,6 +156,7 @@ const db = { "orphan-scores": monkDB.get("orphan-scores"), "import-locks": monkDB.get<{ userID: integer; locked: boolean }>("import-locks"), tables: monkDB.get("tables"), + "invite-locks": monkDB.get<{ userID: integer; locked: boolean }>("invite-locks"), "game-settings": monkDB.get("game-settings"), "game-stats-snapshots": monkDB.get("game-stats-snapshots"), "session-view-cache": monkDB.get("session-view-cache"), diff --git a/server/src/server/router/api/v1/users/_userID/invites/router.ts b/server/src/server/router/api/v1/users/_userID/invites/router.ts index 49d7890b1..3ba7e9110 100644 --- a/server/src/server/router/api/v1/users/_userID/invites/router.ts +++ b/server/src/server/router/api/v1/users/_userID/invites/router.ts @@ -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 }, + } + ); } });