#!/usr/bin/env node /** * Monitor authentication health after deployment * Run this after activating enhanced auth to watch for issues */ const { db } = require('../src/database/db'); console.log('=== Authentication Health Monitor ===\n'); console.log('Monitoring auth system... (Press Ctrl+C to stop)\n'); // Color codes const GREEN = '\x1b[32m'; const RED = '\x1b[31m'; const YELLOW = '\x1b[33m'; const RESET = '\x1b[0m'; let previousStats = { totalAttempts: 0, failedAttempts: 0, lockedAccounts: 0 }; async function getAuthStats() { try { const stats = {}; // Total login attempts in last hour const totalAttempts = await db('login_attempts') .where('attempt_time', '>', new Date(Date.now() - 60 * 60 * 1000).toISOString()) .count('id as count') .first(); stats.totalAttempts = totalAttempts.count || 0; // Failed attempts in last hour const failedAttempts = await db('login_attempts') .where('attempt_time', '>', new Date(Date.now() - 60 * 60 * 1000).toISOString()) .where('success', false) .count('id as count') .first(); stats.failedAttempts = failedAttempts.count || 0; // Currently locked accounts const recentWindow = new Date(Date.now() - 15 * 60 * 1000); const lockedAccounts = await db('login_attempts') .select('identifier') .where('success', false) .where('attempt_time', '>=', recentWindow.toISOString()) .groupBy('identifier') .havingRaw('COUNT(*) >= 5'); stats.lockedAccounts = lockedAccounts.length; // Success rate stats.successRate = stats.totalAttempts > 0 ? ((stats.totalAttempts - stats.failedAttempts) / stats.totalAttempts * 100).toFixed(1) : 100; // Recent failures (last 5 minutes) const recentFailures = await db('login_attempts') .where('success', false) .where('attempt_time', '>', new Date(Date.now() - 5 * 60 * 1000).toISOString()) .orderBy('attempt_time', 'desc') .limit(5) .select('identifier', 'ip_address', 'attempt_time'); stats.recentFailures = recentFailures; return stats; } catch (error) { return { error: error.message }; } } async function displayStats() { const stats = await getAuthStats(); if (stats.error) { console.log(`${RED}Error: ${stats.error}${RESET}`); console.log('Enhanced auth might not be active yet.\n'); return; } // Clear console for clean display console.clear(); console.log('=== Authentication Health Monitor ===\n'); console.log(new Date().toLocaleString()); console.log('─'.repeat(50)); // Display metrics console.log(`\n📊 Last Hour Statistics:`); console.log(` Total Login Attempts: ${stats.totalAttempts}`); console.log(` Failed Attempts: ${stats.failedAttempts}`); console.log(` Success Rate: ${stats.successRate}%`); console.log(` Currently Locked: ${stats.lockedAccounts} accounts`); // Alerts if (stats.failedAttempts > previousStats.failedAttempts + 10) { console.log(`\n${RED}⚠️ ALERT: Spike in failed login attempts!${RESET}`); } if (stats.lockedAccounts > 5) { console.log(`\n${YELLOW}⚠️ WARNING: Multiple accounts locked (${stats.lockedAccounts})${RESET}`); } if (stats.successRate < 50) { console.log(`\n${RED}⚠️ ALERT: Low success rate (${stats.successRate}%)${RESET}`); } // Recent failures if (stats.recentFailures && stats.recentFailures.length > 0) { console.log(`\n📋 Recent Failed Attempts (last 5 min):`); stats.recentFailures.forEach(failure => { const time = new Date(failure.attempt_time).toLocaleTimeString(); console.log(` ${time} - ${failure.identifier} from ${failure.ip_address}`); }); } // Health status console.log(`\n✅ Status: ${stats.failedAttempts === 0 ? 'Healthy' : 'Active'}`); console.log('\nPress Ctrl+C to stop monitoring\n'); previousStats = stats; } // Monitor every 10 seconds setInterval(displayStats, 10000); // Initial display displayStats(); // Graceful shutdown process.on('SIGINT', async () => { console.log('\nStopping monitor...'); await db.destroy(); process.exit(0); });