92 lines
3.0 KiB
PHP
Executable File
92 lines
3.0 KiB
PHP
Executable File
<?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;
|