feat(auth): Story 2.1 — In-Memory Rate-Limiter (pro Key)
This commit is contained in:
parent
07f1bccff0
commit
08c32bcf0f
2 changed files with 41 additions and 0 deletions
23
server/ratelimit.js
Normal file
23
server/ratelimit.js
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// In-Memory Rate-Limiter pro Key (Sliding Fixed-Window).
|
||||
// ponytail: per-Prozess, resettet bei Container-Restart — bei Magic-Link (kein
|
||||
// Passwort-Brute-Force) akzeptierte Ceiling; Persistenz = YAGNI.
|
||||
const buckets = new Map();
|
||||
|
||||
/**
|
||||
* Zählt einen Treffer für `key`. Gibt true zurück, solange das Limit im Fenster
|
||||
* nicht überschritten ist, sonst false (→ Aufrufer antwortet 429).
|
||||
*/
|
||||
function hit(key, limit, windowMin) {
|
||||
const now = Date.now();
|
||||
let b = buckets.get(key);
|
||||
if (!b || now >= b.resetAt) {
|
||||
b = { count: 0, resetAt: now + windowMin * 60 * 1000 };
|
||||
buckets.set(key, b);
|
||||
}
|
||||
b.count += 1;
|
||||
return b.count <= limit;
|
||||
}
|
||||
|
||||
function _reset() { buckets.clear(); } // nur für Tests
|
||||
|
||||
module.exports = { hit, _reset };
|
||||
18
server/ratelimit.test.js
Normal file
18
server/ratelimit.test.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
const { test } = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const { hit, _reset } = require('./ratelimit');
|
||||
|
||||
test('erlaubt bis zum Limit, blockt danach', () => {
|
||||
_reset();
|
||||
assert.strictEqual(hit('a@x.de', 3, 15), true);
|
||||
assert.strictEqual(hit('a@x.de', 3, 15), true);
|
||||
assert.strictEqual(hit('a@x.de', 3, 15), true);
|
||||
assert.strictEqual(hit('a@x.de', 3, 15), false, '4. Anfrage geblockt');
|
||||
});
|
||||
|
||||
test('verschiedene Keys sind unabhängig (E-Mail vs IP)', () => {
|
||||
_reset();
|
||||
assert.strictEqual(hit('email:a@x.de', 1, 15), true);
|
||||
assert.strictEqual(hit('email:a@x.de', 1, 15), false);
|
||||
assert.strictEqual(hit('ip:1.2.3.4', 100, 15), true, 'anderer Key unberührt');
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue