express-rate-limiter-ts
Version:
A powerful, flexible and modern rate limiter middleware for Express.js written in TypeScript.
194 lines (193 loc) • 7.34 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.startAdminPanel = startAdminPanel;
exports.getRateLimiterStats = getRateLimiterStats;
const express_1 = __importDefault(require("express"));
function startAdminPanel(store) {
const app = (0, express_1.default)();
app.use(express_1.default.json());
// JSON API endpointleri
app.get('/api/stats', (_req, res) => __awaiter(this, void 0, void 0, function* () {
res.json(yield store.getStats());
}));
app.get('/api/banned', (_req, res) => __awaiter(this, void 0, void 0, function* () {
res.json(yield store.getBanned());
}));
app.post('/api/unban', (req, res) => __awaiter(this, void 0, void 0, function* () {
const { key } = req.body;
if (key) {
yield store.unban(key);
res.json({ success: true });
}
else {
res.status(400).json({ success: false, message: 'Anahtar belirtilmedi.' });
}
}));
app.get('/', (_req, res) => __awaiter(this, void 0, void 0, function* () {
const stats = yield getRateLimiterStats(store);
const bannedKeys = Object.keys(stats.banned);
res.send(`
<html lang="tr">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WAFGuard - Rate Limiter - Management Panel</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@700;400&display=swap" rel="stylesheet">
<style>
body {
background: #fff;
color: #111;
font-family: 'Montserrat', Arial, sans-serif;
margin: 0;
padding: 0;
}
.header {
display: flex;
align-items: center;
background: #111;
color: #fff;
padding: 24px 32px 18px 32px;
font-size: 2.2rem;
font-weight: 700;
letter-spacing: 1px;
}
.logo {
width: 48px;
height: 48px;
margin-right: 18px;
background: #fff;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 2rem;
font-weight: bold;
color: #111;
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
}
.container {
max-width: 900px;
margin: 32px auto;
padding: 24px;
background: #fff;
border-radius: 16px;
box-shadow: 0 2px 16px rgba(0,0,0,0.07);
}
h2 {
color: #111;
margin-top: 32px;
margin-bottom: 12px;
font-size: 1.3rem;
font-weight: 700;
letter-spacing: 0.5px;
}
.stat-box, .ban-box {
background: #f7f7f7;
border-radius: 8px;
padding: 16px;
font-size: 1rem;
margin-bottom: 24px;
font-family: 'Fira Mono', 'Consolas', monospace;
color: #222;
overflow-x: auto;
border: 1px solid #ccc;
}
.ban-box {
border-left: 4px solid #111;
}
.refresh-btn {
background: #111;
color: #fff;
border: none;
border-radius: 6px;
padding: 10px 22px;
font-size: 1rem;
font-weight: 600;
cursor: pointer;
margin-bottom: 18px;
transition: background 0.2s;
}
.refresh-btn:hover {
background: #333;
}
.unban-btn {
background: #e53935;
color: #fff;
border: none;
border-radius: 6px;
padding: 6px 18px;
font-size: 1rem;
font-weight: 700;
cursor: pointer;
margin-left: auto;
margin-bottom: 4px;
transition: background 0.2s, color 0.2s;
box-shadow: 0 2px 8px rgba(229,57,53,0.08);
display: inline-block;
}
.unban-btn:hover {
background: #b71c1c;
color: #fff;
}
</style>
</head>
<body>
<div class="header">
<img class="logo" src="https://wafguard.com/logo.png" alt="WAFGuard Logo" />
WAFGuard <span style="font-size:1.1rem;font-weight:400;margin-left:12px;opacity:0.7;">Rate Limiter - Management Panel</span>
</div>
<div class="container">
<button class="refresh-btn" onclick="window.location.reload()">Yenile</button>
<h2>İstatistikler</h2>
<div class="stat-box">${Object.keys(stats.stats).length ? `<pre>${JSON.stringify(stats.stats, null, 2)}</pre>` : 'Veri bulunamadı.'}</div>
<h2>Banlananlar</h2>
<div class="ban-box">
${bannedKeys.length ? bannedKeys.map(key => `
<div style="margin-bottom:8px;display:flex;align-items:center;justify-content:space-between;">
<pre style="margin:0;display:inline-block;">${key}: ${JSON.stringify(stats.banned[key], null, 2)}</pre>
<button class="unban-btn" onclick="unban('${key}')">Banı Kaldır</button>
</div>
`).join('') : 'Şu anda banlanan yok.'}
</div>
</div>
<script>
function unban(key) {
fetch('/api/unban', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ key })
}).then(() => window.location.reload());
}
</script>
</body>
</html>
`);
}));
app.listen(9222, () => {
// eslint-disable-next-line no-console
console.log('Rate Limiter Admin Paneli http://localhost:9222 adresinde çalışıyor');
});
}
function getRateLimiterStats(store) {
return __awaiter(this, void 0, void 0, function* () {
return {
stats: yield store.getStats(),
banned: yield store.getBanned(),
};
});
}