Banlist by key with expires and many backends for NodeJS
Supported backends:
- Local process RAM
- pdzGlobalCache ( https://www.npmjs.com/package/@pdz/gc )
- MongoDB ( https://www.npmjs.com/package/mongodb )
- Redis ( https://www.npmjs.com/package/redis ) v4
Example:
'use strict';
const pdzGC = require('@pdz/gc');
const redis = require('redis');
const mongodb = require('mongodb');
const pdzBan = require('@pdz/ban');
const { createHash } = require('crypto');
const md5 = (data) => createHash('md5').update(String(data)).digest('hex'); // for keys hashing
const banConf = {
try_max: 3, // Maximum number of attempts before getting banned
try_period: 1000, // After this period, the attempts counter is reset. The countdown is carried out from the last attempt.
ban_period: 3600000, // Ban time.
ban_extend: false, // If true - the ban period is extended if attempts are not stopped. If false - the ban is removed after the ban period is expired, regardless of additional attempts during the ban.
ns: 'pdzban', // For Redis is prefix (pdzban:*), for MongoDB is collection name, for pdzGlobalCache is main key.
keyHashFunc: md5 // For some backends using some characters in key name is unacceptable. Hashing is simple way to support any key names.
}
const gc = pdzGC.create().start();
const mo = new mongodb.MongoClient('mongodb://localhost:27017');
const red = redis.createClient();
const main = async () => {
// Connect backends
await mo.connect();
await red.connect();
// Start ban system for many backends
const ban = new pdzBan(banConf);
const gcBan = new pdzBan(banConf, gc);
const moBan = new pdzBan(banConf, mo);
const redBan = new pdzBan(banConf, red);
for(let i = 0; i < 5; i++) {
// Add new attempt to banlist
await ban.add('127.0.0.1');
await gcBan.add('127.0.0.1');
await redBan.add('127.0.0.1');
await moBan.add('127.0.0.1');
// Wait 300ms
await new Promise(pres => setTimeout(pres, 300));
// Check ban - if key is banned - returns milliseconds until ban removing, if key is not banned - returns undefined
console.log(
await ban.get('127.0.0.1'),
await gcBan.get('127.0.0.1'),
await redBan.get('127.0.0.1'),
await moBan.get('127.0.0.1'),
);
}
// Clear all bans
await ban.clear();
await gcBan.clear();
await moBan.clear();
await redBan.clear();
// Stop backends
await mo.close();
await red.disconnect();
}
main();
Result:
undefined undefined undefined undefined
undefined undefined undefined undefined
3599693 3599693 3599694 3599694
3599387 3599387 3599388 3599388
3599082 3599082 3599082 3599083