Skip to content

Commit 9ff2bca

Browse files
committed
Elo rank endpoint return 404 on restricted accounts
1 parent 062c3ec commit 9ff2bca

File tree

2 files changed

+23
-15
lines changed

2 files changed

+23
-15
lines changed

api/eloRank.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,26 @@ export default async function handler(req, res) {
3333
try {
3434

3535
let user;
36-
if(username && typeof username === 'string') {
37-
// Prevent NoSQL injection - username must be a string
38-
user = await User.findOne({ username: username }).collation(USERNAME_COLLATION).cache(120);
39-
} else if(secret && typeof secret === 'string') {
36+
let foundBySecret = false;
37+
38+
if(secret && typeof secret === 'string') {
4039
// Prevent NoSQL injection - secret must be a string
4140
user = await User.findOne({ secret }).cache(120);
41+
if (user) foundBySecret = true;
42+
} else if(username && typeof username === 'string') {
43+
// Prevent NoSQL injection - username must be a string
44+
user = await User.findOne({ username: username }).collation(USERNAME_COLLATION).cache(120);
4245
}
4346

4447
if (!user) {
4548
return res.status(404).json({ message: 'User not found' });
4649
}
4750

51+
// If not found by their own secret, hide banned or pending-name-change users
52+
if (!foundBySecret && (user.banned || user.pendingNameChange)) {
53+
return res.status(404).json({ message: 'User not found' });
54+
}
55+
4856
const rank = (await User.countDocuments({
4957
elo: { $gt: user.elo },
5058
banned: false

components/home.js

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ export default function Home({ }) {
322322

323323
// Fetch fresh data when account modal opens (to get updated elo after games)
324324
if (accountModalOpen) {
325-
fetch(clientConfig().apiUrl + "/api/eloRank?username=" + session.token.username)
325+
fetch(clientConfig().apiUrl + "/api/eloRank?username=" + session.token.username+"&secret=" + session.token.secret)
326326
.then((res) => res.json())
327327
.then((data) => {
328328
if (data && data.elo !== undefined) {
@@ -1270,15 +1270,15 @@ export default function Home({ }) {
12701270

12711271
// Use the passed options directly to avoid stale state issues
12721272
const options = args[0] || multiplayerState.createOptions;
1273-
ws.send(JSON.stringify({
1274-
type: "setPrivateGameOptions",
1275-
rounds: options.rounds,
1276-
timePerRound: options.timePerRound,
1277-
nm: options.nm,
1278-
npz: options.npz,
1279-
showRoadName: options.showRoadName,
1280-
location: options.location,
1281-
displayLocation: options.displayLocation
1273+
ws.send(JSON.stringify({
1274+
type: "setPrivateGameOptions",
1275+
rounds: options.rounds,
1276+
timePerRound: options.timePerRound,
1277+
nm: options.nm,
1278+
npz: options.npz,
1279+
showRoadName: options.showRoadName,
1280+
location: options.location,
1281+
displayLocation: options.displayLocation
12821282
}));
12831283
}
12841284

@@ -1773,7 +1773,7 @@ export default function Home({ }) {
17731773
// Game was cancelled before it started (opponent left during countdown)
17741774
// No ELO was lost - just return to home and optionally re-queue
17751775
toast.info(text("opponentLeftBeforeStart") || "Opponent left before the game started. Returning to queue...");
1776-
1776+
17771777
setScreen("home")
17781778
setMultiplayerChatEnabled(false)
17791779

0 commit comments

Comments
 (0)