🔱 Enhanced backdoor with Redis + Directus checks
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
*
|
||||
* Endpoints:
|
||||
* GET /api/god/health - Full system health check
|
||||
* GET /api/god/services - Quick service status (all 4 containers)
|
||||
* GET /api/god/db-status - Database connection test
|
||||
* POST /api/god/sql - Execute raw SQL (dangerous!)
|
||||
* GET /api/god/tables - List all tables
|
||||
@@ -14,6 +15,7 @@
|
||||
|
||||
import type { APIRoute } from 'astro';
|
||||
import { Pool } from 'pg';
|
||||
import Redis from 'ioredis';
|
||||
|
||||
// Direct PostgreSQL connection (bypasses Directus)
|
||||
const pool = new Pool({
|
||||
@@ -27,6 +29,9 @@ const pool = new Pool({
|
||||
connectionTimeoutMillis: 5000,
|
||||
});
|
||||
|
||||
// Directus URL
|
||||
const DIRECTUS_URL = process.env.PUBLIC_DIRECTUS_URL || 'http://directus:8055';
|
||||
|
||||
// God Mode Token validation
|
||||
function validateGodToken(request: Request): boolean {
|
||||
const token = request.headers.get('X-God-Token') ||
|
||||
@@ -63,6 +68,8 @@ export const GET: APIRoute = async ({ request, url }) => {
|
||||
switch (action) {
|
||||
case 'health':
|
||||
return await getHealth();
|
||||
case 'services':
|
||||
return await getServices();
|
||||
case 'db-status':
|
||||
return await getDbStatus();
|
||||
case 'tables':
|
||||
@@ -72,8 +79,10 @@ export const GET: APIRoute = async ({ request, url }) => {
|
||||
default:
|
||||
return json({
|
||||
message: '🔱 God Mode Backdoor Active',
|
||||
frontend: 'RUNNING ✅',
|
||||
endpoints: {
|
||||
'GET /api/god/health': 'Full system health check',
|
||||
'GET /api/god/services': 'Quick status of all 4 containers',
|
||||
'GET /api/god/db-status': 'Database connection test',
|
||||
'GET /api/god/tables': 'List all tables',
|
||||
'GET /api/god/logs': 'Recent work_log entries',
|
||||
@@ -121,14 +130,103 @@ export const POST: APIRoute = async ({ request, url }) => {
|
||||
}
|
||||
};
|
||||
|
||||
// Quick service status check
|
||||
async function getServices() {
|
||||
const services: Record<string, any> = {
|
||||
timestamp: new Date().toISOString(),
|
||||
frontend: { status: '✅ RUNNING', note: 'You are seeing this response' }
|
||||
};
|
||||
|
||||
// Check PostgreSQL
|
||||
try {
|
||||
const start = Date.now();
|
||||
await pool.query('SELECT 1');
|
||||
services.postgresql = {
|
||||
status: '✅ RUNNING',
|
||||
latency_ms: Date.now() - start
|
||||
};
|
||||
} catch (error: any) {
|
||||
services.postgresql = {
|
||||
status: '❌ DOWN',
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
|
||||
// Check Redis
|
||||
try {
|
||||
const redis = new Redis({
|
||||
host: process.env.REDIS_HOST || 'redis',
|
||||
port: 6379,
|
||||
connectTimeout: 3000,
|
||||
maxRetriesPerRequest: 1
|
||||
});
|
||||
const start = Date.now();
|
||||
await redis.ping();
|
||||
services.redis = {
|
||||
status: '✅ RUNNING',
|
||||
latency_ms: Date.now() - start
|
||||
};
|
||||
redis.disconnect();
|
||||
} catch (error: any) {
|
||||
services.redis = {
|
||||
status: '❌ DOWN',
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
|
||||
// Check Directus
|
||||
try {
|
||||
const start = Date.now();
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 5000);
|
||||
|
||||
const response = await fetch(`${DIRECTUS_URL}/server/health`, {
|
||||
signal: controller.signal
|
||||
});
|
||||
clearTimeout(timeout);
|
||||
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
services.directus = {
|
||||
status: '✅ RUNNING',
|
||||
latency_ms: Date.now() - start,
|
||||
health: data.status
|
||||
};
|
||||
} else {
|
||||
services.directus = {
|
||||
status: '⚠️ UNHEALTHY',
|
||||
http_status: response.status
|
||||
};
|
||||
}
|
||||
} catch (error: any) {
|
||||
services.directus = {
|
||||
status: '❌ DOWN',
|
||||
error: error.name === 'AbortError' ? 'Timeout (5s)' : error.message
|
||||
};
|
||||
}
|
||||
|
||||
// Summary
|
||||
const allUp = services.postgresql.status.includes('✅') &&
|
||||
services.redis.status.includes('✅') &&
|
||||
services.directus.status.includes('✅');
|
||||
|
||||
services.summary = allUp ? '✅ ALL SERVICES HEALTHY' : '⚠️ SOME SERVICES DOWN';
|
||||
|
||||
return json(services);
|
||||
}
|
||||
|
||||
// Health check implementation
|
||||
async function getHealth() {
|
||||
const start = Date.now();
|
||||
|
||||
const checks: Record<string, any> = {
|
||||
timestamp: new Date().toISOString(),
|
||||
uptime: process.uptime(),
|
||||
memory: process.memoryUsage(),
|
||||
uptime_seconds: Math.round(process.uptime()),
|
||||
memory: {
|
||||
rss_mb: Math.round(process.memoryUsage().rss / 1024 / 1024),
|
||||
heap_used_mb: Math.round(process.memoryUsage().heapUsed / 1024 / 1024),
|
||||
heap_total_mb: Math.round(process.memoryUsage().heapTotal / 1024 / 1024),
|
||||
},
|
||||
};
|
||||
|
||||
// PostgreSQL check
|
||||
@@ -136,24 +234,70 @@ async function getHealth() {
|
||||
const dbStart = Date.now();
|
||||
const result = await pool.query('SELECT NOW() as time, current_database() as db, current_user as user');
|
||||
checks.postgresql = {
|
||||
status: 'healthy',
|
||||
status: '✅ healthy',
|
||||
latency_ms: Date.now() - dbStart,
|
||||
...result.rows[0]
|
||||
};
|
||||
} catch (error: any) {
|
||||
checks.postgresql = {
|
||||
status: 'unhealthy',
|
||||
status: '❌ unhealthy',
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
|
||||
// Connection pool status
|
||||
checks.pool = {
|
||||
checks.pg_pool = {
|
||||
total: pool.totalCount,
|
||||
idle: pool.idleCount,
|
||||
waiting: pool.waitingCount
|
||||
};
|
||||
|
||||
// Redis check
|
||||
try {
|
||||
const redis = new Redis({
|
||||
host: process.env.REDIS_HOST || 'redis',
|
||||
port: 6379,
|
||||
connectTimeout: 3000,
|
||||
maxRetriesPerRequest: 1
|
||||
});
|
||||
const redisStart = Date.now();
|
||||
const info = await redis.info('server');
|
||||
checks.redis = {
|
||||
status: '✅ healthy',
|
||||
latency_ms: Date.now() - redisStart,
|
||||
version: info.match(/redis_version:([^\r\n]+)/)?.[1]
|
||||
};
|
||||
redis.disconnect();
|
||||
} catch (error: any) {
|
||||
checks.redis = {
|
||||
status: '❌ unhealthy',
|
||||
error: error.message
|
||||
};
|
||||
}
|
||||
|
||||
// Directus check
|
||||
try {
|
||||
const directusStart = Date.now();
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => controller.abort(), 5000);
|
||||
|
||||
const response = await fetch(`${DIRECTUS_URL}/server/health`, {
|
||||
signal: controller.signal
|
||||
});
|
||||
clearTimeout(timeout);
|
||||
|
||||
checks.directus = {
|
||||
status: response.ok ? '✅ healthy' : '⚠️ unhealthy',
|
||||
latency_ms: Date.now() - directusStart,
|
||||
http_status: response.status
|
||||
};
|
||||
} catch (error: any) {
|
||||
checks.directus = {
|
||||
status: '❌ unreachable',
|
||||
error: error.name === 'AbortError' ? 'Timeout (5s)' : error.message
|
||||
};
|
||||
}
|
||||
|
||||
// Directus tables check
|
||||
try {
|
||||
const tables = await pool.query(`
|
||||
@@ -163,12 +307,9 @@ async function getHealth() {
|
||||
AND table_name LIKE 'directus_%'
|
||||
ORDER BY table_name
|
||||
`);
|
||||
checks.directus = {
|
||||
system_tables: tables.rows.length,
|
||||
tables: tables.rows.map(r => r.table_name)
|
||||
};
|
||||
checks.directus_tables = tables.rows.length;
|
||||
} catch (error: any) {
|
||||
checks.directus = { status: 'error', error: error.message };
|
||||
checks.directus_tables = 0;
|
||||
}
|
||||
|
||||
// Custom tables check
|
||||
@@ -185,7 +326,7 @@ async function getHealth() {
|
||||
tables: tables.rows.map(r => r.table_name)
|
||||
};
|
||||
} catch (error: any) {
|
||||
checks.custom_tables = { status: 'error', error: error.message };
|
||||
checks.custom_tables = { count: 0, error: error.message };
|
||||
}
|
||||
|
||||
checks.total_latency_ms = Date.now() - start;
|
||||
|
||||
Reference in New Issue
Block a user