aboutsummaryrefslogtreecommitdiffstats
path: root/lib/auth.ts
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-09-29 08:37:39 -0700
committerAdam Soltys <[email protected]>2026-09-29 08:37:47 -0700
commit4900ecb19ab9c6d279c8771b834fcb29e526a1e0 (patch)
treea8e1067d3cadbd8eacc9d111da2507d7babadfbd /lib/auth.ts
parente96ad1cea4192a608a7f15896e4b690b57bf8fc9 (diff)
downloadcoinos-server-4900ecb19ab9c6d279c8771b834fcb29e526a1e0.tar.gz
coinos-server-4900ecb19ab9c6d279c8771b834fcb29e526a1e0.zip
logging: throttle log lines that clients can trigger at will
Evicted-JWT replays, blocked sends from frozen or limited accounts and failed payment retries each logged one line per request, so a looping client could flood the log, and an evicted token replayed across a proxy pool made atk-autoban.sh block every IP it saw. Add quiet()/suppressed() in lib/logging.ts: the first occurrence per key logs as before, repeats within the window are counted and reported on the next line that gets through. The evicted-auth summary line is worded so the auto-banner ignores it. Co-Authored-By: Claude Fable 5.1 <[email protected]>
Diffstat (limited to 'lib/auth.ts')
-rw-r--r--lib/auth.ts16
1 files changed, 13 insertions, 3 deletions
diff --git a/lib/auth.ts b/lib/auth.ts
index 915dcdc8..107c44f4 100644
--- a/lib/auth.ts
+++ b/lib/auth.ts
@@ -1,6 +1,7 @@
import config from "$config";
import { db } from "$lib/db";
import { fail, getUser } from "$lib/utils";
+import { quiet, suppressed } from "$lib/logging";
import fastifyPassport from "@fastify/passport";
import jwt from "passport-jwt";
@@ -70,9 +71,18 @@ export const jwtStrategy = new jwt.Strategy(
) {
// Distinctive, greppable line carrying the real source IP so the realtime
// auto-banner (scripts/atk-autoban.sh) can insta-ban it at Cloudflare.
- console.error(
- `EVICTED_AUTH ${user.username} ${req.headers["cf-connecting-ip"] || req.ip}`,
- );
+ // Throttled per account. An evicted JWT replayed from a rotating proxy
+ // pool otherwise emits one line per request and
+ // has atk-autoban.sh place a Cloudflare block on every residential IP it
+ // sees, which protects nothing. First hit logs with its IP; afterwards
+ // one summary per 10 minutes, worded so the auto-banner ignores it.
+ const n = quiet(`evicted:${user.id}`);
+ if (n !== null)
+ console.error(
+ n
+ ? `evicted-auth ${user.username} ${suppressed(n)}`
+ : `EVICTED_AUTH ${user.username} ${req.headers["cf-connecting-ip"] || req.ip}`,
+ );
return next(null, false);
}