+41
-13
@@ -39,7 +39,7 @@ class Router
|
||||
header('Content-Type: application/json');
|
||||
|
||||
try {
|
||||
$publicPaths = ['/health', '/oauth', '/auth/me', '/auth/logout', '/auth/csrf', '/ingest'];
|
||||
$publicPaths = ['/health', '/oauth', '/auth/me', '/auth/logout', '/auth/csrf'];
|
||||
$isPublic = false;
|
||||
foreach ($publicPaths as $pp) {
|
||||
if ($path === $pp || str_starts_with($path, $pp . '/')) {
|
||||
@@ -63,7 +63,7 @@ class Router
|
||||
|
||||
$path === '/auth/csrf' && $method === 'GET' => $this->csrfToken(),
|
||||
|
||||
$path === '/ingest' && $method === 'POST' => $this->ingest(),
|
||||
$path === '/ingest' && $method === 'POST' => $this->requireCsrf(fn() => $this->ingest()),
|
||||
|
||||
$path === '/auth/me' && $method === 'GET' => $this->getMe(),
|
||||
$path === '/auth/logout' && $method === 'POST' => $this->logout(),
|
||||
@@ -189,10 +189,23 @@ class Router
|
||||
|
||||
private function loginUrl(): string
|
||||
{
|
||||
$redirect = 'https://' . ($_SERVER['HTTP_HOST'] ?? 'localhost') . '/oauth.php';
|
||||
$host = $_SERVER['HTTP_HOST'] ?? 'localhost';
|
||||
if (!$this->isTrustedHost($host)) {
|
||||
$host = 'localhost';
|
||||
}
|
||||
$redirect = 'https://' . $host . '/oauth.php';
|
||||
return 'https://auth.jakach.ch/?send_to=' . urlencode($redirect);
|
||||
}
|
||||
|
||||
private function isTrustedHost(string $host): bool
|
||||
{
|
||||
$host = strtolower(preg_replace('/:\d+$/', '', $host));
|
||||
return $host === 'localhost'
|
||||
|| $host === '127.0.0.1'
|
||||
|| $host === 'jakach.ch'
|
||||
|| str_ends_with($host, '.jakach.ch');
|
||||
}
|
||||
|
||||
private function getMe(): array
|
||||
{
|
||||
$user = $this->auth->requireAuth();
|
||||
@@ -294,8 +307,8 @@ class Router
|
||||
|
||||
private function getAlerts(): mixed
|
||||
{
|
||||
$limit = (int) ($_GET['limit'] ?? 100);
|
||||
$offset = (int) ($_GET['offset'] ?? 0);
|
||||
$limit = $this->boundedInt($_GET['limit'] ?? 100, 1, 500);
|
||||
$offset = $this->boundedInt($_GET['offset'] ?? 0, 0, 100000);
|
||||
$status = $_GET['status'] ?? null;
|
||||
$severity = $_GET['severity'] ?? null;
|
||||
return $this->repo->getAlerts($limit, $offset, $status, $severity, $_GET['since'] ?? null, $_GET['until'] ?? null);
|
||||
@@ -327,7 +340,7 @@ class Router
|
||||
if (empty($query)) {
|
||||
return [];
|
||||
}
|
||||
$limit = (int) ($_GET['limit'] ?? 100);
|
||||
$limit = $this->boundedInt($_GET['limit'] ?? 100, 1, 500);
|
||||
return $this->repo->searchAlerts($query, $limit);
|
||||
}
|
||||
|
||||
@@ -337,8 +350,8 @@ class Router
|
||||
if (empty($query)) {
|
||||
return ['data' => []];
|
||||
}
|
||||
$limit = (int) ($_GET['limit'] ?? 200);
|
||||
$offset = (int) ($_GET['offset'] ?? 0);
|
||||
$limit = $this->boundedInt($_GET['limit'] ?? 200, 1, 1000);
|
||||
$offset = $this->boundedInt($_GET['offset'] ?? 0, 0, 100000);
|
||||
return ['data' => $this->repo->searchLogEntries($query, $limit, $offset, $_GET['since'] ?? null, $_GET['until'] ?? null)];
|
||||
}
|
||||
|
||||
@@ -361,6 +374,10 @@ class Router
|
||||
http_response_code(400);
|
||||
return ['error' => 'Missing "line" field'];
|
||||
}
|
||||
if (strlen($line) > 65535) {
|
||||
http_response_code(413);
|
||||
return ['error' => 'Log line too large'];
|
||||
}
|
||||
|
||||
$alert = $this->engine->evaluate($line, null);
|
||||
|
||||
@@ -378,16 +395,18 @@ class Router
|
||||
? substr($token, 0, 8) . '...'
|
||||
: ($token ? substr($token, 0, 3) . '...' : '');
|
||||
return [
|
||||
'bot_token' => $token,
|
||||
'bot_token_masked' => $masked,
|
||||
'bot_token_configured' => $token !== '',
|
||||
'chat_id' => $this->repo->getConfig('telegram_chat_id', ''),
|
||||
];
|
||||
}
|
||||
|
||||
private function updateTelegramConfig(): array
|
||||
{
|
||||
$body = json_decode(file_get_contents('php://input'), true);
|
||||
$this->repo->setConfig('telegram_bot_token', $body['bot_token'] ?? '');
|
||||
$body = json_decode(file_get_contents('php://input'), true) ?: [];
|
||||
if (array_key_exists('bot_token', $body) && trim((string) $body['bot_token']) !== '') {
|
||||
$this->repo->setConfig('telegram_bot_token', trim((string) $body['bot_token']));
|
||||
}
|
||||
$this->repo->setConfig('telegram_chat_id', $body['chat_id'] ?? '');
|
||||
$this->repo->logAudit('update', 'config', null, 'Telegram config updated', $this->user());
|
||||
return $this->getTelegramConfig();
|
||||
@@ -547,7 +566,16 @@ class Router
|
||||
|
||||
private function getAuditLog(): array
|
||||
{
|
||||
$limit = (int) ($_GET['limit'] ?? 50);
|
||||
$limit = $this->boundedInt($_GET['limit'] ?? 50, 1, 500);
|
||||
return ['data' => $this->repo->getAuditLog($limit)];
|
||||
}
|
||||
}
|
||||
|
||||
private function boundedInt(mixed $value, int $min, int $max): int
|
||||
{
|
||||
$value = filter_var($value, FILTER_VALIDATE_INT);
|
||||
if ($value === false) {
|
||||
return $min;
|
||||
}
|
||||
return max($min, min($max, $value));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user