Files
2026-10-24 20:14:46 +00:00

51 lines
2.2 KiB
PHP

<?php
declare(strict_types=1);
/**
* Öffentliche Webhook-Adresse für Plugins: POST /api/public/v1/plugin_webhook.php?p=<plugin>&e=<name>
* Das Plugin muss die Berechtigung "api.public" anfordern und prüft die Echtheit jeder Anfrage selbst (siehe plugin_register_webhook()).
* Hier gibt es nur: Methode POST, höchstens 256 KB, Aufruf des Handlers, Antwort als JSON oder Text.
*/
require_once __DIR__ . '/../../../includes/bootstrap.php';
header('Cache-Control: no-store');
header('X-Content-Type-Options: nosniff');
function webhook_fail(int $status, string $message): never
{
http_response_code($status);
header('Content-Type: application/json; charset=utf-8');
echo json_encode(['error' => $message], JSON_UNESCAPED_UNICODE);
exit;
}
if (($_SERVER['REQUEST_METHOD'] ?? '') !== 'POST') {
header('Allow: POST');
webhook_fail(405, 'Nur POST.');
}
$slug = (string) ($_GET['p'] ?? '');
$endpoint = (string) ($_GET['e'] ?? '');
$handler = plugin_state()['webhooks'][$slug][$endpoint] ?? null;
if (!is_callable($handler)) webhook_fail(404, 'Unbekannte Adresse.');
$body = (string) file_get_contents('php://input', false, null, 0, 262145);
if (strlen($body) > 262144) webhook_fail(413, 'Anfrage zu groß.');
$headers = [];
foreach ($_SERVER as $k => $v) {
if (str_starts_with($k, 'HTTP_')) $headers[strtolower(str_replace('_', '-', substr($k, 5)))] = (string) $v;
}
if (isset($_SERVER['CONTENT_TYPE'])) $headers['content-type'] = (string) $_SERVER['CONTENT_TYPE'];
$result = plugin_guard($slug, fn() => $handler(['method' => 'POST', 'headers' => $headers, 'body' => $body, 'query' => $_GET, 'ip' => client_ip()]), null);
if (!is_array($result)) webhook_fail(500, 'Fehler im Plugin.');
http_response_code((int) ($result['status'] ?? 200));
foreach ((array) ($result['headers'] ?? []) as $name => $value) {
if (preg_match('/^[A-Za-z0-9-]+$/', (string) $name) && !preg_match('/[\r\n]/', (string) $value)) header($name . ': ' . $value);
}
if (isset($result['json'])) {
header('Content-Type: application/json; charset=utf-8');
echo json_encode($result['json'], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
} else {
echo (string) ($result['body'] ?? '');
}