aboutsummaryrefslogtreecommitdiffstats
path: root/routes/users.ts
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-11-04 14:31:51 -0700
committerAdam Soltys <[email protected]>2026-11-04 14:31:51 -0700
commitc0a0f5c1ac6bbcfddc5ce15800483f1e2d7226a5 (patch)
tree3c93de6ea611496d744c23de28b2aa1497603f6d /routes/users.ts
parent8375e8fa57d5c2c99573f011144457774b4b6161 (diff)
downloadcoinos-server-c0a0f5c1ac6bbcfddc5ce15800483f1e2d7226a5.tar.gz
coinos-server-c0a0f5c1ac6bbcfddc5ce15800483f1e2d7226a5.zip
login: tell the client when an account's password was resetHEADmaster
A rekeyed account holds the literal "reset" instead of a hash, so no password can match. Return "account reset" so the client can send the owner to support. The check runs after the captcha and the per-IP failure cap, and counts as a failure. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Diffstat (limited to 'routes/users.ts')
-rw-r--r--routes/users.ts11
1 files changed, 11 insertions, 0 deletions
diff --git a/routes/users.ts b/routes/users.ts
index 400b554b..77ddbdc6 100644
--- a/routes/users.ts
+++ b/routes/users.ts
@@ -559,6 +559,17 @@ export default {
let user = await getUser(username);
if (!isAdmin) {
+ // changeid leaves the literal "reset" in place of a hash, so no
+ // password can ever match. Say so, letting the client point the
+ // owner at support instead of a generic login failure. This runs
+ // after the captcha and the per-IP failure cap, and counts as a
+ // failure itself.
+ if (user?.password === "reset") {
+ await db.incrBy(ipFailKey, 1);
+ if ((await db.ttl(ipFailKey)) < 0) await db.expire(ipFailKey, 600);
+ return res.code(401).send("account reset");
+ }
+
let verified = false;
try {
if (user?.password)