From 51e01eb2dc6e7976963c31b9349c4e621c535874 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 28 Feb 2026 22:06:55 -0800 Subject: disable rate limiting in dev --- lib/app.ts | 91 +++++++++++++++++++++++++++++---------------------------- lib/payments.ts | 8 ++--- 2 files changed, 50 insertions(+), 49 deletions(-) (limited to 'lib') diff --git a/lib/app.ts b/lib/app.ts index e2b8d49e..a6ea315f 100644 --- a/lib/app.ts +++ b/lib/app.ts @@ -20,63 +20,66 @@ app.use( // Static files app.use("/public/*", serveStatic({ root: "/home/bun/app/data/uploads", rewriteRequestPath: (p) => p.replace("/public", "") })); -// Rate limiting +// Rate limiting (disabled in development) +const prod = process.env.NODE_ENV === "production"; const rateLimits = new Map(); const strictLimits = new Map(); -app.use("*", async (c, next) => { - const url = c.req.path; +if (prod) { + app.use("*", async (c, next) => { + const url = c.req.path; - // Skip rate limiting for public assets - if (url.includes("public")) return next(); - - const ip = (c.req.header("cf-connecting-ip") as string) || (c.env as any)?.ip || "unknown"; - const ua = c.req.header("user-agent") || "unknown-ua"; - const rateLimitBy = c.req.header("rate-limit-by"); - const key = rateLimitBy === "ua" ? ua : ip; - const now = Date.now(); - - // General rate limit: 2000 req / 2s - const gen = rateLimits.get(key); - if (gen && now < gen.reset) { - gen.count++; - if (gen.count > 2000) { - return c.json( - { statusCode: 429, error: "Too Many Requests", message: "Rate limit exceeded, retry in 2 seconds" }, - 429, - ); - } - } else { - rateLimits.set(key, { count: 1, reset: now + 2000 }); - } + // Skip rate limiting for public assets + if (url.includes("public")) return next(); + + const ip = (c.req.header("cf-connecting-ip") as string) || (c.env as any)?.ip || "unknown"; + const ua = c.req.header("user-agent") || "unknown-ua"; + const rateLimitBy = c.req.header("rate-limit-by"); + const key = rateLimitBy === "ua" ? ua : ip; + const now = Date.now(); - // Strict rate limit for /login and /send: 10 req / 10s - const isStrict = url.includes("/login") || url.includes("/send"); - if (isStrict) { - const strictKey = `strict:${ua}`; - const s = strictLimits.get(strictKey); - if (s && now < s.reset) { - s.count++; - if (s.count > 10) { + // General rate limit: 2000 req / 2s + const gen = rateLimits.get(key); + if (gen && now < gen.reset) { + gen.count++; + if (gen.count > 2000) { return c.json( - { statusCode: 429, error: "Too Many Requests", message: "Rate limit exceeded" }, + { statusCode: 429, error: "Too Many Requests", message: "Rate limit exceeded, retry in 2 seconds" }, 429, ); } } else { - strictLimits.set(strictKey, { count: 1, reset: now + 10000 }); + rateLimits.set(key, { count: 1, reset: now + 2000 }); } - } - return next(); -}); + // Strict rate limit for /login and /send: 10 req / 10s + const isStrict = url.includes("/login") || url.includes("/send"); + if (isStrict) { + const strictKey = `strict:${ua}`; + const s = strictLimits.get(strictKey); + if (s && now < s.reset) { + s.count++; + if (s.count > 10) { + return c.json( + { statusCode: 429, error: "Too Many Requests", message: "Rate limit exceeded" }, + 429, + ); + } + } else { + strictLimits.set(strictKey, { count: 1, reset: now + 10000 }); + } + } + + return next(); + }); -// Clean up rate limit maps periodically -setInterval(() => { - const now = Date.now(); - for (const [k, v] of rateLimits) if (now >= v.reset) rateLimits.delete(k); - for (const [k, v] of strictLimits) if (now >= v.reset) strictLimits.delete(k); -}, 5000); + // Clean up rate limit maps periodically + setInterval(() => { + const now = Date.now(); + for (const [k, v] of rateLimits) if (now >= v.reset) rateLimits.delete(k); + for (const [k, v] of strictLimits) if (now >= v.reset) strictLimits.delete(k); + }, 5000); +} // Request logging app.use("*", async (c, next) => { diff --git a/lib/payments.ts b/lib/payments.ts index 52319c8d..66f536bc 100644 --- a/lib/payments.ts +++ b/lib/payments.ts @@ -371,11 +371,9 @@ export const completePayment = async (inv, p, user) => { inv.forwarded = true; await s(`invoice:${inv.id}`, inv); - // Skip forward if destination is the same user's own Lightning invoice - if (inv.forward.startsWith("ln")) { - const destInv = await getInvoice(inv.forward).catch(() => null); - if (destInv?.uid === id) return; - } + // Skip forward if destination belongs to the same user + const destInv = await getInvoice(inv.forward).catch(() => null); + if (destInv?.uid === id) return; await pay({ amount: p.amount, to: inv.forward, user }); } catch (e) { -- cgit v1.2.3