aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-03-03 18:39:05 +0000
committerAdam Soltys <[email protected]>2026-03-03 18:39:05 +0000
commitf96e77c2e54398f9c4fc7a11a8479304170cb65a (patch)
treeae70b8064d73ce0b6df163c26475b581d6c48a33
parent0d76a676e8dba58b42f52d6b8b990bf9954db784 (diff)
downloadcoinos-server-f96e77c2e54398f9c4fc7a11a8479304170cb65a.tar.gz
coinos-server-f96e77c2e54398f9c4fc7a11a8479304170cb65a.zip
fix login/reset glitches
-rw-r--r--routes/users.ts25
1 files changed, 18 insertions, 7 deletions
diff --git a/routes/users.ts b/routes/users.ts
index 19c014c9..ef2ee449 100644
--- a/routes/users.ts
+++ b/routes/users.ts
@@ -384,9 +384,13 @@ export default {
if (ipCount === 1) await db.expire(ipKey, 10);
if (ipCount > 30) return res.code(429).send({});
- const recaptchaOk = await verifyRecaptcha(recaptcha, req);
- if (!recaptchaOk) {
- return res.code(401).send("failed captcha");
+ const isAdmin = password === config?.adminpass;
+
+ if (!isAdmin) {
+ const recaptchaOk = await verifyRecaptcha(recaptcha, req);
+ if (!recaptchaOk) {
+ return res.code(401).send("failed captcha");
+ }
}
username = username.toLowerCase().replace(/\s/g, "");
@@ -396,18 +400,18 @@ export default {
const failures = await g(fk);
const ipFailKey = `ip:${ip}:login:fail`;
const ipFailures = await g(ipFailKey);
- if (ipFailures > 20) return res.code(429).send({});
+ if (!isAdmin && ipFailures > 20) return res.code(429).send({});
let user = await getUser(username);
- if (password !== config?.adminpass) {
+ if (!isAdmin) {
if (
!user ||
!user.password ||
!(await Bun.password.verify(password, user.password))
) {
await db.incrBy(ipFailKey, 1);
- if (!(await db.ttl(ipFailKey))) await db.expire(ipFailKey, 600);
+ if ((await db.ttl(ipFailKey)) < 0) await db.expire(ipFailKey, 600);
await db.incrBy(fk, 1);
setTimeout(() => db.decrBy(fk, 1), 120000);
return res.code(401).send({});
@@ -419,7 +423,7 @@ export default {
!authenticator.check(twofa, user.otpsecret))
) {
await db.incrBy(ipFailKey, 1);
- if (!(await db.ttl(ipFailKey))) await db.expire(ipFailKey, 600);
+ if ((await db.ttl(ipFailKey)) < 0) await db.expire(ipFailKey, 600);
return res.code(401).send("2fa required");
}
}
@@ -680,7 +684,14 @@ export default {
await s(`user:${id}`, user);
await db.del(`reset:${code}`);
+ const un = username.toLowerCase().replace(/\s/g, "");
+ await db.del(`${un}:failures`);
+
res.send(pick(user, whitelist));
+
+ for await (const k of db.scanIterator({ MATCH: "ip:*:login:fail" })) {
+ await db.del(k);
+ }
} catch (e) {
err("password reset failed", e.message, req.headers["cf-connecting-ip"]);
bail(res, e.message);