diff options
| author | Adam Soltys <[email protected]> | 2026-03-03 18:39:05 +0000 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-03-03 18:39:05 +0000 |
| commit | f96e77c2e54398f9c4fc7a11a8479304170cb65a (patch) | |
| tree | ae70b8064d73ce0b6df163c26475b581d6c48a33 | |
| parent | 0d76a676e8dba58b42f52d6b8b990bf9954db784 (diff) | |
| download | coinos-server-f96e77c2e54398f9c4fc7a11a8479304170cb65a.tar.gz coinos-server-f96e77c2e54398f9c4fc7a11a8479304170cb65a.zip | |
fix login/reset glitches
| -rw-r--r-- | routes/users.ts | 25 |
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); |
