diff options
| author | Adam Soltys <[email protected]> | 2026-10-04 13:38:24 -0700 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2026-10-04 13:38:24 -0700 |
| commit | 41018c30a2e03f5ab05be64d419542be0cff7943 (patch) | |
| tree | 71035492551fd360aa48e90143403a129e9f80f5 | |
| parent | 1ff2623dbb43148267eac5cbe68c76d2c0639805 (diff) | |
| download | coinos-server-41018c30a2e03f5ab05be64d419542be0cff7943.tar.gz coinos-server-41018c30a2e03f5ab05be64d419542be0cff7943.zip | |
Evicted accounts can't receive or log in; limit errors say what's happening
An evicted account no longer gets lightning-address invoices (stops a
scam page's address from minting new ones) or a login token. A send
over the server limit now says withdrawals are temporarily limited
instead of a generic "Problem sending payment" that read as a frozen
account. (Already live since the 2026-10-01 restart.)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_011bvzKaZosXGHkigcGcSzAR
| -rw-r--r-- | lib/payments.ts | 8 | ||||
| -rw-r--r-- | routes/lnurl.ts | 8 | ||||
| -rw-r--r-- | routes/users.ts | 5 |
3 files changed, 18 insertions, 3 deletions
diff --git a/lib/payments.ts b/lib/payments.ts index 58dabc0d..09cf2cf6 100644 --- a/lib/payments.ts +++ b/lib/payments.ts @@ -178,7 +178,13 @@ export const debit = async ({ const n = quiet(`block:${user.id}:server`, 5 * 60 * 1000); if (n !== null) warn("Blocking", user.username, amount, hash, user.id, type, "serverLimit", serverLimit, suppressed(n)); - fail("Problem sending payment"); + // Say what's happening (users read the generic error as "account + // frozen") without revealing the limit or the hot-wallet balance. + fail( + type === PaymentType.bitcoin || type === PaymentType.liquid + ? "On-chain withdrawals are temporarily limited. Please try a smaller amount, send over Lightning, or try again later." + : "Payments are temporarily limited. Please try a smaller amount or try again later.", + ); } await db.decrBy(`${type}:limit`, amount); }); diff --git a/routes/lnurl.ts b/routes/lnurl.ts index 0472d758..7f04db5d 100644 --- a/routes/lnurl.ts +++ b/routes/lnurl.ts @@ -138,7 +138,10 @@ export default { if (v3) return res.send(v3); const user = await getUser(name); - if (!user) fail(`User ${username} not found`); + // Evicted accounts can't receive either: stops a lightning address that + // a scam page points victims at from issuing new invoices. + if (!user || (await db.sIsMember("evicted", user.id))) + fail(`User ${username} not found`); const { id: uid } = user; const metadata = JSON.stringify([ @@ -179,7 +182,8 @@ export default { const uid = await g(`lnurl:${id}`); const user = await getUser(uid); - if (!user) fail("user not found"); + if (!user || (await db.sIsMember("evicted", user.id))) + fail("user not found"); let { username } = user; username = username.replace(/\s/g, "").toLowerCase(); diff --git a/routes/users.ts b/routes/users.ts index 431425b4..347b7dd4 100644 --- a/routes/users.ts +++ b/routes/users.ts @@ -482,6 +482,11 @@ export default { } } + // Evicted accounts can't use a token anyway (see lib/auth.ts), so don't + // mint one — checked after the password so it can't be used to probe. + if (!isAdmin && (await db.sIsMember("evicted", user.id))) + return res.code(403).send("account disabled"); + if (username !== "coinos") l("logged in", username, req.headers["cf-connecting-ip"]); |
