aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2025-02-04 17:30:14 +0000
committerAdam Soltys <[email protected]>2025-02-04 17:30:14 +0000
commit581fb404e212b5993fbec153a87e9b7bfd68d578 (patch)
treed4f4f7d3368abf5cdf44c144da04b1d759ed5e9e
parent4f2e4ffdd5de8819abf2fe505fca4af12d3d7f6f (diff)
downloadcoinos-server-581fb404e212b5993fbec153a87e9b7bfd68d578.tar.gz
coinos-server-581fb404e212b5993fbec153a87e9b7bfd68d578.zip
log login failures
-rw-r--r--.gitignore1
-rw-r--r--index.ts11
-rw-r--r--lib/migrate.ts2
-rw-r--r--lib/nwc.ts3
-rw-r--r--lib/payments.ts13
-rw-r--r--lib/sockets.ts2
-rw-r--r--routes/payments.ts5
-rw-r--r--routes/users.ts14
8 files changed, 37 insertions, 14 deletions
diff --git a/.gitignore b/.gitignore
index 312970e2..8fcee169 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,4 @@ req
nobal.sh
littlefs.img
printer
+failedlogins.txt
diff --git a/index.ts b/index.ts
index 03595e16..bbcbfbbf 100644
--- a/index.ts
+++ b/index.ts
@@ -113,7 +113,16 @@ app.post("/superuser", users.superuser);
app.get("/verify/:code", users.verify);
app.post("/request", auth, users.request);
app.post("/forgot", users.forgot);
-app.post("/login", users.login);
+app.post("/login", {
+ config: {
+ rateLimit: {
+ max: 5,
+ timeWindow: "5 seconds",
+ keyGenerator: (req) => req.headers["cf-connecting-ip"] as string, // IP-based rate limiting
+ },
+ },
+ },
+ users.login);
app.post("/printer", users.printer);
app.get("/challenge", users.challenge);
app.post("/nostrLogin", users.nostrLogin);
diff --git a/lib/migrate.ts b/lib/migrate.ts
index 403e22b1..8da68cd2 100644
--- a/lib/migrate.ts
+++ b/lib/migrate.ts
@@ -12,7 +12,7 @@ async function migrate(id) {
let user = await g(`user:${id}`);
if (typeof user === "string") user = await g(`user:${user}`);
- if (user) return user;
+ return user;
user = await ga(`user:${id}`);
diff --git a/lib/nwc.ts b/lib/nwc.ts
index 912a2fc3..73b7decd 100644
--- a/lib/nwc.ts
+++ b/lib/nwc.ts
@@ -76,7 +76,8 @@ export default () => {
} catch (e) {
err(
"problem with nwc",
- user.username,
+ pubkey,
+ user?.username,
JSON.stringify(params),
e.message,
);
diff --git a/lib/payments.ts b/lib/payments.ts
index 1468a198..af16e02e 100644
--- a/lib/payments.ts
+++ b/lib/payments.ts
@@ -54,8 +54,19 @@ export const debit = async ({
rate = undefined,
}) => {
amount = parseInt(amount);
- if (type !== types.internal && (await g("freeze")))
+ let blacklisted = await db.sIsMember("blacklist", user?.username?.toLowerCase());
+ let whitelisted = await db.sIsMember("whitelist", user?.username?.toLowerCase());
+
+ if (type !== types.internal && blacklisted && !whitelisted && amount > 500) {
+ warn("Blocking payment", amount, hash, user.username, user.id);
+ fail("Problem sending payment");
+ }
+
+ if (type !== types.internal && (await g("freeze")) && amount > 1000000 && !whitelisted) {
+ warn("Blocking payment", amount, hash, user.username, user.id);
fail("Problem sending payment");
+ }
+
// if (!user.unlimited && amount > 1000000)
// fail(`⚡️${amount} exceeds max withdrawal of ⚡️1,000,000`);
let ref;
diff --git a/lib/sockets.ts b/lib/sockets.ts
index 1a5421f9..028551ed 100644
--- a/lib/sockets.ts
+++ b/lib/sockets.ts
@@ -121,7 +121,7 @@ Bun.serve({
subscriptions.push({ invoice: data, ws });
break;
default:
- warn("received socket message of unknown type", type, data);
+ // warn("received socket message of unknown type", type, data);
}
},
open(ws: any) {
diff --git a/routes/payments.ts b/routes/payments.ts
index 93e5d3da..1e035b3c 100644
--- a/routes/payments.ts
+++ b/routes/payments.ts
@@ -1,7 +1,7 @@
import config from "$config";
import api from "$lib/api";
import { requirePin } from "$lib/auth";
-import { db, g, s, t } from "$lib/db";
+import { db, g, s } from "$lib/db";
import { err, l, warn } from "$lib/logging";
import mqtt from "$lib/mqtt";
import {
@@ -45,8 +45,6 @@ export default {
const balance = await g(`balance:${user.id}`);
try {
- if (await g("freeze")) fail("Problem sending payment");
-
if (typeof amount !== "undefined") {
amount = parseInt(amount);
if (amount < 0 || amount > SATS || Number.isNaN(amount))
@@ -405,7 +403,6 @@ export default {
res.send(p);
} catch (e) {
- console.log(e);
warn(user.username, "payment failed", e.message);
res.code(500).send(e.message);
}
diff --git a/routes/users.ts b/routes/users.ts
index c54f4ae2..d1c2bd96 100644
--- a/routes/users.ts
+++ b/routes/users.ts
@@ -89,7 +89,7 @@ export default {
const user = await getNostrUser(key);
res.send(pick(user, fields));
} catch (e) {
- err("problem getting user", e.message);
+ err("problem getting user", key, e.message);
res.code(500).send(e.message);
}
},
@@ -161,11 +161,13 @@ export default {
async update(req, res) {
const { user, body } = req;
try {
- l("updating user", user.username);
+ const { id: tokid } = jwt.verify(req.headers.authorization.split(" ")[1], config.jwt);
+ l("updating user", user.username, tokid);
const { confirm, password, pin, newpin, username } = body;
let exists;
+
let { pubkey } = body;
if (pubkey) {
exists = await getUser(pubkey);
@@ -292,7 +294,8 @@ export default {
(await Bun.password.verify(password, user.password))
))
) {
- warn("invalid username or password attempt", username);
+ // warn("invalid username or password attempt", username);
+ await appendFile("failedlogins.txt", `${Date.now()} : ${username} : ${password}\n`);
return res.code(401).send({});
}
@@ -305,8 +308,8 @@ export default {
return res.code(401).send("2fa required");
}
- if (username !== "coinos" && username !== "funk")
- l("logged in", username);
+ if (username !== "coinos" && username !== "funk" && username !== "btcpos")
+ l("logged in", username, password);
const payload = { id: user.id };
const token = jwt.sign(payload, config.jwt);
@@ -546,6 +549,7 @@ export default {
res.send(pick(user, whitelist));
} catch (e) {
+ err("password reset failed", e.message);
bail(res, e.message);
}
},