aboutsummaryrefslogtreecommitdiffstats
path: root/routes
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 /routes
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 'routes')
-rw-r--r--routes/payments.ts15
1 files changed, 11 insertions, 4 deletions
diff --git a/routes/payments.ts b/routes/payments.ts
index 9bdcc2eb..67243a12 100644
--- a/routes/payments.ts
+++ b/routes/payments.ts
@@ -6,7 +6,7 @@ import { generate, getUserOffer } from "$lib/invoices";
import { replay } from "$lib/lightning";
import ln from "$lib/ln";
import { platformFee, quoteMax, quoteRoutingFee } from "$lib/lnquote";
-import { err, l, shortError, warn } from "$lib/logging";
+import { err, l, quiet, shortError, suppressed, warn } from "$lib/logging";
import mqtt from "$lib/mqtt";
import {
build,
@@ -105,8 +105,13 @@ export default {
res.send(p);
} catch (e) {
- warn(user.username, "payment failed", amount, balance, hash, payreq);
- err(shortError(e.message));
+ // One line per account per 5 min: frozen/empty throwaway accounts retry
+ // failed sends in a loop and otherwise dominate the log.
+ const n = quiet(`payfail:${user.id}`, 5 * 60 * 1000);
+ if (n !== null) {
+ warn(user.username, "payment failed", amount, balance, hash, payreq, suppressed(n));
+ err(shortError(e.message));
+ }
bail(res, e.message);
}
},
@@ -710,7 +715,9 @@ export default {
res.send(p);
} catch (e) {
- warn(user.username, "payment failed", shortError(e.message));
+ const n = quiet(`payfail:${user.id}`, 5 * 60 * 1000);
+ if (n !== null)
+ warn(user.username, "payment failed", shortError(e.message), suppressed(n));
res.code(500).send(e.message);
}
},