all
Some checks failed
Publish Docker Image / build-and-push (push) Failing after 2m13s

This commit is contained in:
Sam Kintop
2026-04-30 09:44:02 -05:00
parent 0a30837e3d
commit bf3870ccca
111 changed files with 8383 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\LogContentParser;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Api\Response\CodexLogResponse;
use Aternos\Mclogs\Log;
class AnalyseLogAction extends ApiAction
{
public function runApi(): ApiResponse
{
$data = new LogContentParser()->getContent();
if ($data instanceof ApiError) {
return $data;
}
$content = $data['content'];
$log = new Log()->setContent($content);
return new CodexLogResponse($log->getCodexLog());
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\ContentParser;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Router\Action;
abstract class ApiAction extends Action
{
abstract protected function runApi(): ApiResponse;
protected function getAllowedOrigin(): string
{
return '*';
}
protected function shouldAllowCredentials(): bool
{
return false;
}
public function run(): bool
{
header('Access-Control-Allow-Origin: ' . $this->getAllowedOrigin());
header('Access-Control-Allow-Headers: *');
if ($this->shouldAllowCredentials()) {
header('Access-Control-Allow-Credentials: true');
}
header("Accept-Encoding: " . implode(",", ContentParser::getSupportedEncodings()));
$response = $this->runApi();
$response->output();
return true;
}
}

View File

@@ -0,0 +1,77 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\ContentParser;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Api\Response\MultiResponse;
use Aternos\Mclogs\Id;
use Aternos\Mclogs\Log;
use Aternos\Mclogs\Storage\MongoDBClient;
class BulkDeleteLogsAction extends ApiAction
{
public const int MAX_IDS = 256;
/**
* @return ApiResponse
*/
protected function runApi(): ApiResponse
{
$data = new ContentParser()->getContent();
if ($data instanceof ApiError) {
return $data;
}
if (count($data) === 0) {
return new ApiError(400, "No logs provided.");
}
if (count($data) > static::MAX_IDS) {
return new ApiError(400, "Too many logs. Maximum is " . static::MAX_IDS . ".");
}
$ids = [];
foreach ($data as $log) {
if (!is_array($log)) {
return new ApiError(400, "Each entry must be an object with 'id' and 'token' fields.");
}
if (!isset($log["id"]) || !is_string($log["id"]) ||
!preg_match("/^" . Id::PATTERN . "$/", $log["id"])) {
return new ApiError(400, "Each log must have a valid 'id' field.");
}
if (!isset($log["token"]) || !is_string($log["token"])) {
return new ApiError(400, "Each log must have a valid 'token' field.");
}
$ids[] = $log["id"];
}
$logs = Log::findAll($ids, false);
$deleteIds = [];
$response = new MultiResponse();
foreach ($data as $log) {
$id = $log["id"];
$token = $log["token"];
$log = $logs[$id] ?? null;
if (!$log) {
$response->addResponse($id, new ApiError(404, "Log not found."));
continue;
}
$logToken = $log->getToken();
if (!$logToken || !$logToken->matches($token)) {
$response->addResponse($id, new ApiError(403, "Invalid token."));
continue;
}
$deleteIds[] = $id;
$response->addResponse($id, new ApiResponse());
}
MongoDBClient::getInstance()->deleteLogs($deleteIds);
return $response;
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\LogContentParser;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Api\Response\LogResponse;
use Aternos\Mclogs\Data\MetadataEntry;
use Aternos\Mclogs\Log;
class CreateLogAction extends ApiAction
{
protected bool $includeCookie = false;
protected bool $includeToken = true;
public function runApi(): ApiResponse
{
$data = new LogContentParser()->getContent();
if ($data instanceof ApiError) {
return $data;
}
$content = $data['content'];
$metadata = [];
if (isset($data['metadata']) && is_array($data['metadata'])) {
$metadata = MetadataEntry::allFromArray($data['metadata']);
}
$source = null;
if (isset($data['source']) && is_string($data['source'])) {
$source = $data['source'];
}
$log = Log::create($content, $metadata, $source);
if ($this->includeCookie) {
$log->setTokenCookie();
}
return new LogResponse($log, $this->includeToken);
}
}

View File

@@ -0,0 +1,60 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Id;
use Aternos\Mclogs\Log;
use Aternos\Mclogs\Util\URL;
class DeleteLogAction extends ApiAction
{
protected function getRequestToken(): ?string
{
$authorizationHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? null;
if (!$authorizationHeader) {
return null;
}
$parts = explode(" ", $authorizationHeader);
return $parts[1] ?? null;
}
/**
* @return ApiResponse
*/
protected function runApi(): ApiResponse
{
$requestToken = $this->getRequestToken();
if (!$requestToken) {
return new ApiError(400, "Missing token.");
}
$id = new Id(URL::getLastPathPart());
$log = Log::find($id);
if (!$log) {
return new ApiError(404, "Log not found.");
}
$token = $log->getToken();
if (!$token || !$token->matches($requestToken)) {
return new ApiError(403, "Invalid token.");
}
$deleted = $log->delete();
if (!$deleted) {
return new ApiError(500, "Failed to delete log.");
}
$this->handleDeletedLog($log);
return new ApiResponse();
}
protected function handleDeletedLog(Log $log): void
{
}
}

View File

@@ -0,0 +1,13 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Router\Action;
class EmptyAction extends Action
{
public function run(): bool
{
return true;
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
class EndpointNotFoundAction extends ApiAction
{
protected function runApi(): ApiResponse
{
return new ApiError(404, "Could not find endpoint.");
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Api\Response\FiltersResponse;
class GetFiltersAction extends ApiAction
{
protected function runApi(): ApiResponse
{
return new FiltersResponse();
}
}

View File

@@ -0,0 +1,14 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Api\Response\LimitsResponse;
class GetLimitsAction extends ApiAction
{
protected function runApi(): ApiResponse
{
return new LimitsResponse();
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Api\Response\LogResponse;
use Aternos\Mclogs\Id;
use Aternos\Mclogs\Log;
use Aternos\Mclogs\Util\URL;
class LogInfoAction extends ApiAction
{
/**
* @return ApiResponse
*/
protected function runApi(): ApiResponse
{
$id = new Id(URL::getLastPathPart());
$log = Log::find($id);
if (!$log) {
return new ApiError(404, "Log not found.");
}
return new LogResponse($log);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Api\Response\CodexLogResponse;
use Aternos\Mclogs\Id;
use Aternos\Mclogs\Log;
use Aternos\Mclogs\Util\URL;
class LogInsightsAction extends ApiAction
{
/**
* @return ApiResponse
*/
protected function runApi(): ApiResponse
{
$id = new Id(URL::getLastPathPart());
$log = Log::find($id);
if (!$log) {
return new ApiError(404, "Log not found.");
}
$codexLog = $log->getCodexLog();
$codexLog->setIncludeEntries(false);
return new CodexLogResponse($codexLog);
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
class RateLimitErrorAction extends ApiAction
{
protected function runApi(): ApiResponse
{
return new ApiError(
429,
"Unfortunately you have exceeded the rate limit for the current time period. Please try again later."
);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Aternos\Mclogs\Api\Action;
use Aternos\Mclogs\Api\Response\ApiError;
use Aternos\Mclogs\Api\Response\ApiResponse;
use Aternos\Mclogs\Api\Response\RawLogResponse;
use Aternos\Mclogs\Id;
use Aternos\Mclogs\Log;
use Aternos\Mclogs\Util\URL;
class RawLogAction extends ApiAction
{
/**
* @return ApiResponse
*/
protected function runApi(): ApiResponse
{
$id = new Id(URL::getLastPathPart());
$log = Log::find($id);
if (!$log) {
return new ApiError(404, "Log not found.");
}
return new RawLogResponse($log);
}
}