Primer commit del sistema separado falta mejorar mucho
This commit is contained in:
91
discord/webhook/index.php
Executable file
91
discord/webhook/index.php
Executable file
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
/**
|
||||
* Webhook Principal de Discord
|
||||
* Punto de entrada para interacciones de Discord que redirige al daemon
|
||||
*/
|
||||
|
||||
// Habilitar logging de errores en archivo, no en salida
|
||||
ini_set('display_errors', 0);
|
||||
ini_set('log_errors', 1);
|
||||
ini_set('error_log', __DIR__ . '/../../logs/webhook_errors.log');
|
||||
|
||||
require_once __DIR__ . '/../../shared/utils/helpers.php';
|
||||
|
||||
// Cargar variables de entorno
|
||||
if (file_exists(__DIR__ . '/../../.env')) {
|
||||
$lines = file(__DIR__ . '/../../.env', FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
||||
foreach ($lines as $line) {
|
||||
if (strpos(trim($line), '#') === 0) continue;
|
||||
if (strpos($line, '=') === false) continue;
|
||||
list($key, $value) = explode('=', $line, 2);
|
||||
$_ENV[trim($key)] = trim($value);
|
||||
}
|
||||
}
|
||||
|
||||
// Constantes de Discord
|
||||
define('DISCORD_PUBLIC_KEY', $_ENV['DISCORD_PUBLIC_KEY'] ?? getenv('DISCORD_PUBLIC_KEY'));
|
||||
|
||||
// Verificar firma de seguridad (Ed25519)
|
||||
function verifySignature($body, $headers) {
|
||||
$signature = $headers['x-signature-ed25519'] ?? '';
|
||||
$timestamp = $headers['x-signature-timestamp'] ?? '';
|
||||
$publicKey = DISCORD_PUBLIC_KEY;
|
||||
|
||||
if (\!$signature || \!$timestamp || \!$publicKey) {
|
||||
error_log("Faltan parámetros de firma");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (function_exists('sodium_crypto_sign_verify_detached')) {
|
||||
try {
|
||||
$sig = hex2bin($signature);
|
||||
$msg = $timestamp . $body;
|
||||
$key = hex2bin($publicKey);
|
||||
return sodium_crypto_sign_verify_detached($sig, $msg, $key);
|
||||
} catch (Exception $e) {
|
||||
error_log("Error verificando firma (sodium): " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
error_log("ADVERTENCIA: La extensión 'sodium' de PHP no está instalada. La verificación de firma de Discord es INSEGURA.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Obtener headers y body
|
||||
$headers = array_change_key_case(getallheaders(), CASE_LOWER);
|
||||
$body = file_get_contents('php://input');
|
||||
|
||||
// Registrar la solicitud para depuración
|
||||
error_log("Solicitud recibida: " . json_encode([
|
||||
'headers' => array_intersect_key($headers, ['x-signature-ed25519' => true, 'x-signature-timestamp' => true]),
|
||||
'body' => $body
|
||||
]));
|
||||
|
||||
// Verificar firma
|
||||
if (\!verifySignature($body, $headers)) {
|
||||
http_response_code(401);
|
||||
error_log("Firma no válida");
|
||||
echo 'Invalid Signature';
|
||||
exit;
|
||||
}
|
||||
|
||||
// Decodificar JSON para verificar si es un PING
|
||||
$data = json_decode($body, true);
|
||||
$type = $data['type'] ?? 0;
|
||||
|
||||
// Manejar PING (requerido por Discord para validar la URL del webhook)
|
||||
if ($type === 1) {
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['type' => 1]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Para otras interacciones, redirigir al daemon
|
||||
$interactionId = $data['id'] ?? 'unknown';
|
||||
error_log("Interacción recibida (ID: $interactionId). El daemon debería manejar esto.");
|
||||
|
||||
// NO responder aquí. El daemon se encargará de la respuesta completa.
|
||||
// Simplemente terminamos el script del webhook con un 200 OK.
|
||||
http_response_code(200);
|
||||
exit;
|
||||
Reference in New Issue
Block a user