UNPKG

nehonix-uri-processor

Version:

A powerful URI processor for encoding, decoding, and analyzing URI data securely.

212 lines 7.81 kB
import { createDatabaseAdapter } from "./express.middleware"; import { Pool } from "pg"; import { setDatabaseAdapter } from "./NEHONIX.LocalMemory"; /** * Example PostgreSQL database adapter implementation */ async function createPostgresSecurityAdapter(connectionString) { // Create database connection pool const pool = new Pool({ connectionString, max: 20, }); // Test connection try { const client = await pool.connect(); client.release(); console.log("Connected to PostgreSQL database"); // Ensure tables exist await setupTables(pool); } catch (error) { console.error("Failed to connect to PostgreSQL:", error); throw error; } // Create and return database adapter return createDatabaseAdapter({ // Track suspicious IP implementation async trackSuspiciousIP(ip, details) { const client = await pool.connect(); try { // Check if IP already exists const checkResult = await client.query("SELECT id, count FROM suspicious_ips WHERE ip = $1", [ip]); const detailsJson = JSON.stringify(details || {}); if (checkResult.rows.length > 0) { // Update existing record await client.query("UPDATE suspicious_ips SET count = count + 1, last_seen = NOW(), details = $2 WHERE ip = $1", [ip, detailsJson]); } else { // Insert new record await client.query("INSERT INTO suspicious_ips (ip, count, last_seen, details) VALUES ($1, 1, NOW(), $2)", [ip, detailsJson]); } } finally { client.release(); } }, // Get suspicious IPs implementation async getSuspiciousIPs() { const client = await pool.connect(); try { const result = await client.query("SELECT ip, count, extract(epoch from last_seen) * 1000 as last_seen, details FROM suspicious_ips ORDER BY count DESC"); return result.rows.map((row) => ({ ip: row.ip, count: row.count, lastSeen: parseInt(row.last_seen), details: row.details, })); } finally { client.release(); } }, // Block IP implementation async blockIP(ip, reason) { const client = await pool.connect(); try { await client.query("INSERT INTO blocked_ips (ip, reason, blocked_at) VALUES ($1, $2, NOW()) ON CONFLICT (ip) DO UPDATE SET reason = $2, blocked_at = NOW()", [ip, reason]); return true; } catch (error) { console.error("Error blocking IP:", error); return false; } finally { client.release(); } }, // Check if IP is blocked implementation async isIPBlocked(ip) { const client = await pool.connect(); try { const result = await client.query("SELECT 1 FROM blocked_ips WHERE ip = $1", [ip]); return result.rows.length > 0; } finally { client.release(); } }, // Save security event implementation async saveSecurityEvent(event) { const client = await pool.connect(); try { await client.query(`INSERT INTO security_events (timestamp, type, ip, url, method, score, patterns, details) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, [ new Date(event.timestamp), event.type, event.ip, event.url || null, event.method || null, event.score || null, event.patterns ? JSON.stringify(event.patterns) : null, event.details ? JSON.stringify(event.details) : null, ]); } finally { client.release(); } }, // Get security events implementation async getSecurityEvents(options) { const client = await pool.connect(); try { const result = await client.query(`SELECT extract(epoch from timestamp) * 1000 as timestamp, type, ip, url, method, score, patterns, details FROM security_events WHERE timestamp BETWEEN $1 AND $2 ORDER BY timestamp DESC`, [options.startDate, options.endDate]); return result.rows.map((row) => ({ timestamp: parseInt(row.timestamp), type: row.type, ip: row.ip, url: row.url, method: row.method, score: row.score, patterns: row.patterns, details: row.details, })); } finally { client.release(); } }, }); } /** * Create required database tables if they don't exist */ async function setupTables(pool) { const client = await pool.connect(); try { // Create tables in a transaction await client.query("BEGIN"); // Create suspicious IPs table await client.query(` CREATE TABLE IF NOT EXISTS suspicious_ips ( id SERIAL PRIMARY KEY, ip VARCHAR(45) NOT NULL, count INTEGER NOT NULL DEFAULT 1, last_seen TIMESTAMP NOT NULL DEFAULT NOW(), details JSONB, UNIQUE(ip) ) `); // Create blocked IPs table await client.query(` CREATE TABLE IF NOT EXISTS blocked_ips ( id SERIAL PRIMARY KEY, ip VARCHAR(45) NOT NULL, reason TEXT, blocked_at TIMESTAMP NOT NULL DEFAULT NOW(), UNIQUE(ip) ) `); // Create security events table await client.query(` CREATE TABLE IF NOT EXISTS security_events ( id SERIAL PRIMARY KEY, timestamp TIMESTAMP NOT NULL, type VARCHAR(20) NOT NULL, ip VARCHAR(45) NOT NULL, url TEXT, method VARCHAR(10), score FLOAT, patterns JSONB, details JSONB ) `); // Create indexes for better performance await client.query("CREATE INDEX IF NOT EXISTS idx_security_events_timestamp ON security_events(timestamp)"); await client.query("CREATE INDEX IF NOT EXISTS idx_security_events_ip ON security_events(ip)"); await client.query("CREATE INDEX IF NOT EXISTS idx_security_events_type ON security_events(type)"); await client.query("COMMIT"); } catch (error) { await client.query("ROLLBACK"); throw error; } finally { client.release(); } } /** * Example usage: */ async function setupSecurityDatabase() { try { // Create a PostgreSQL adapter const postgresAdapter = await createPostgresSecurityAdapter("postgresql://username:password@localhost:5432/security_db"); // Set as the active database adapter setDatabaseAdapter(postgresAdapter); console.log("PostgreSQL security database adapter configured successfully"); } catch (error) { console.error("Failed to setup security database:", error); // Fall back to in-memory adapter console.log("Falling back to in-memory security database"); } } export { createPostgresSecurityAdapter, setupSecurityDatabase }; //# sourceMappingURL=b.private.js.map