| |
| |
| import { getSetting, setSetting } from "./db"; |
|
|
| export const FAIL_LIMIT = 3; |
|
|
| export type BanEntry = { ip: string; at: number; reason: string }; |
|
|
| function readList(key: string): string[] { |
| try { const v = getSetting(key); return v ? (JSON.parse(v) as string[]) : []; } catch { return []; } |
| } |
| function writeList(key: string, list: string[]): void { |
| setSetting(key, JSON.stringify(Array.from(new Set(list.filter(Boolean))))); |
| } |
| function readBanned(): BanEntry[] { |
| try { const v = getSetting("ip.banned"); return v ? (JSON.parse(v) as BanEntry[]) : []; } catch { return []; } |
| } |
| function writeBanned(list: BanEntry[]): void { setSetting("ip.banned", JSON.stringify(list)); } |
| function readFails(): Record<string, number> { |
| try { const v = getSetting("ip.fails"); return v ? (JSON.parse(v) as Record<string, number>) : {}; } catch { return {}; } |
| } |
| function writeFails(m: Record<string, number>): void { setSetting("ip.fails", JSON.stringify(m)); } |
|
|
| |
| |
| |
| export function getClientIp(req: any): string { |
| return req.ip || "unknown"; |
| } |
|
|
| export function isWhitelisted(ip: string): boolean { return readList("ip.whitelist").includes(ip); } |
| export function isBlocked(ip: string): boolean { |
| if (isWhitelisted(ip)) return false; |
| if (readList("ip.blacklist").includes(ip)) return true; |
| return readBanned().some((b) => b.ip === ip); |
| } |
|
|
| export function recordFail(ip: string): number { |
| if (isWhitelisted(ip)) return 0; |
| const m = readFails(); |
| m[ip] = (m[ip] || 0) + 1; |
| writeFails(m); |
| if (m[ip] >= FAIL_LIMIT) banIp(ip, `登录失败 ${m[ip]} 次自动封禁`); |
| return m[ip]; |
| } |
| export function clearFails(ip: string): void { |
| const m = readFails(); |
| if (m[ip] !== undefined) { delete m[ip]; writeFails(m); } |
| } |
| export function banIp(ip: string, reason: string): void { |
| const list = readBanned(); |
| if (!list.some((b) => b.ip === ip)) { list.push({ ip, at: Date.now(), reason }); writeBanned(list); } |
| } |
| export function unbanIp(ip: string): void { |
| writeBanned(readBanned().filter((b) => b.ip !== ip)); |
| clearFails(ip); |
| } |
| export function addWhitelist(ip: string): void { writeList("ip.whitelist", [...readList("ip.whitelist"), ip]); unbanIp(ip); } |
| export function delWhitelist(ip: string): void { writeList("ip.whitelist", readList("ip.whitelist").filter((x) => x !== ip)); } |
| export function addBlacklist(ip: string): void { writeList("ip.blacklist", [...readList("ip.blacklist"), ip]); } |
| export function delBlacklist(ip: string): void { writeList("ip.blacklist", readList("ip.blacklist").filter((x) => x !== ip)); } |
|
|
| export function accessState() { |
| return { |
| failLimit: FAIL_LIMIT, |
| whitelist: readList("ip.whitelist"), |
| blacklist: readList("ip.blacklist"), |
| banned: readBanned(), |
| fails: readFails() |
| }; |
| } |
|
|