From 37c3764c41a7bbd33dccf11fc51079fdc0c70f42 Mon Sep 17 00:00:00 2001 From: flashwave Date: Wed, 21 Feb 2024 16:08:45 +0000 Subject: [PATCH] Index framework updates. --- composer.lock | 130 ++++++++++++++++---------------------- public/index.php | 8 +-- src/AccountLinkInfo.php | 25 ++++---- src/AccountLinks.php | 5 +- src/AuthorisationInfo.php | 33 +++++----- src/Authorisations.php | 15 ++--- src/CapeInfo.php | 18 ++++-- src/Capes.php | 5 +- src/ClientsRoutes.php | 21 +++--- src/HomeRoutes.php | 29 +++++---- src/MojangInterop.php | 6 +- src/RpcRoutes.php | 11 ++-- src/ServerInfo.php | 42 ++++++------ src/Servers.php | 13 +--- src/SkinInfo.php | 22 ++++--- src/Skins.php | 5 +- src/SkinsRoutes.php | 25 ++++---- src/UserInfo.php | 21 +++--- src/Users.php | 5 +- src/VerificationInfo.php | 29 +++++---- src/Verifications.php | 5 +- 21 files changed, 226 insertions(+), 247 deletions(-) diff --git a/composer.lock b/composer.lock index 22290ff..aeb7060 100644 --- a/composer.lock +++ b/composer.lock @@ -67,7 +67,7 @@ "source": { "type": "git", "url": "https://patchii.net/flash/index.git", - "reference": "e31781c69f0b13fe251771c8e7e529222630a44f" + "reference": "73051dc71ee2d0045e5dbe5d846bb665a8b1c39c" }, "require": { "ext-mbstring": "*", @@ -105,7 +105,7 @@ ], "description": "Composer package for the common library for my projects.", "homepage": "https://railgun.sh/index", - "time": "2023-11-20T19:01:19+00:00" + "time": "2024-02-06T23:52:46+00:00" }, { "name": "flashwave/sasae", @@ -113,7 +113,7 @@ "source": { "type": "git", "url": "https://patchii.net/flash/sasae.git", - "reference": "b56dd222acb8f138729e6258d4a90bbb8401ff52" + "reference": "c8a9f2974e6591215b3f898dd5525de1e8367f66" }, "require": { "flashwave/index": "dev-master", @@ -146,7 +146,7 @@ ], "description": "A wrapper for Twig with added common functionality.", "homepage": "https://railgun.sh/sasae", - "time": "2023-11-20T19:09:35+00:00" + "time": "2024-01-04T02:13:42+00:00" }, { "name": "flashwave/syokuhou", @@ -154,7 +154,7 @@ "source": { "type": "git", "url": "https://patchii.net/flash/syokuhou.git", - "reference": "fdf3c38cc216bf7024af331cbe1758532355c22f" + "reference": "c1fe9371ada20fcea51c225cc53b9ceae4642bc4" }, "require": { "flashwave/index": "dev-master", @@ -185,7 +185,7 @@ ], "description": "Configuration library for PHP.", "homepage": "https://railgun.sh/syokuhou", - "time": "2023-11-20T19:10:04+00:00" + "time": "2024-01-04T02:12:49+00:00" }, { "name": "guzzlehttp/psr7", @@ -802,16 +802,16 @@ }, { "name": "sentry/sentry", - "version": "4.1.0", + "version": "4.6.0", "source": { "type": "git", "url": "https://github.com/getsentry/sentry-php.git", - "reference": "89666f297891ff937fceb2f3d1fb967a6848cf37" + "reference": "30d98a460ab10f7b7032d76c62da5b1ce6c0765d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/89666f297891ff937fceb2f3d1fb967a6848cf37", - "reference": "89666f297891ff937fceb2f3d1fb967a6848cf37", + "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/30d98a460ab10f7b7032d76c62da5b1ce6c0765d", + "reference": "30d98a460ab10f7b7032d76c62da5b1ce6c0765d", "shasum": "" }, "require": { @@ -835,7 +835,7 @@ "phpbench/phpbench": "^1.0", "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^8.5.14|^9.4", - "symfony/phpunit-bridge": "^5.2|^6.0", + "symfony/phpunit-bridge": "^5.2|^6.0|^7.0", "vimeo/psalm": "^4.17" }, "suggest": { @@ -875,7 +875,7 @@ ], "support": { "issues": "https://github.com/getsentry/sentry-php/issues", - "source": "https://github.com/getsentry/sentry-php/tree/4.1.0" + "source": "https://github.com/getsentry/sentry-php/tree/4.6.0" }, "funding": [ { @@ -887,7 +887,7 @@ "type": "custom" } ], - "time": "2023-12-04T12:41:21+00:00" + "time": "2024-02-13T11:32:56+00:00" }, { "name": "symfony/deprecation-contracts", @@ -958,16 +958,16 @@ }, { "name": "symfony/mime", - "version": "v7.0.0", + "version": "v7.0.3", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "0a2fff95c1a10df97f571d67e76c7ae0f0d4f535" + "reference": "c1ffe24ba6fdc3e3f0f3fcb93519103b326a3716" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/0a2fff95c1a10df97f571d67e76c7ae0f0d4f535", - "reference": "0a2fff95c1a10df97f571d67e76c7ae0f0d4f535", + "url": "https://api.github.com/repos/symfony/mime/zipball/c1ffe24ba6fdc3e3f0f3fcb93519103b326a3716", + "reference": "c1ffe24ba6fdc3e3f0f3fcb93519103b326a3716", "shasum": "" }, "require": { @@ -1021,7 +1021,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.0.0" + "source": "https://github.com/symfony/mime/tree/v7.0.3" }, "funding": [ { @@ -1037,7 +1037,7 @@ "type": "tidelift" } ], - "time": "2023-10-19T14:20:43+00:00" + "time": "2024-01-30T08:34:29+00:00" }, { "name": "symfony/options-resolver", @@ -1108,16 +1108,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", "shasum": "" }, "require": { @@ -1131,9 +1131,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1170,7 +1167,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" }, "funding": [ { @@ -1186,20 +1183,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919", + "reference": "a287ed7475f85bf6f61890146edbc932c0fff919", "shasum": "" }, "require": { @@ -1212,9 +1209,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1257,7 +1251,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0" }, "funding": [ { @@ -1273,20 +1267,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:30:37+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", "shasum": "" }, "require": { @@ -1297,9 +1291,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1341,7 +1332,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" }, "funding": [ { @@ -1357,20 +1348,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", "shasum": "" }, "require": { @@ -1384,9 +1375,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1424,7 +1412,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" }, "funding": [ { @@ -1440,20 +1428,20 @@ "type": "tidelift" } ], - "time": "2023-07-28T09:04:16+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25", "shasum": "" }, "require": { @@ -1461,9 +1449,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1500,7 +1485,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0" }, "funding": [ { @@ -1516,20 +1501,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", "shasum": "" }, "require": { @@ -1537,9 +1522,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1583,7 +1565,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" }, "funding": [ { @@ -1599,7 +1581,7 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "twig/html-extra", @@ -1749,5 +1731,5 @@ "prefer-lowest": false, "platform": [], "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/public/index.php b/public/index.php index 7b4c847..1047d00 100644 --- a/public/index.php +++ b/public/index.php @@ -50,10 +50,10 @@ $router->setDefaultErrorHandler(function($response, $request, $code, $text) use ])); }); -(new RpcRoutes($users, $accountLinks, $authorisations, $verifications, $cfg->getString('rpc:secret'), $cfg->getString('urls:clients')))->register($router); -(new HomeRoutes($templating, new Servers($db), $authInfo, $cfg->getString('site:login')))->register($router); -(new ClientsRoutes($templating, $accountLinks, $authorisations, $verifications, $csrfp, $authInfo))->register($router); -(new SkinsRoutes($templating, $accountLinks, new Skins($db), new Capes($db), $csrfp, $authInfo, $cfg->getString('urls:skins_base')))->register($router); +$router->register(new RpcRoutes($users, $accountLinks, $authorisations, $verifications, $cfg->getString('rpc:secret'), $cfg->getString('urls:clients'))); +$router->register(new HomeRoutes($templating, new Servers($db), $authInfo, $cfg->getString('site:login'))); +$router->register(new ClientsRoutes($templating, $accountLinks, $authorisations, $verifications, $csrfp, $authInfo)); +$router->register(new SkinsRoutes($templating, $accountLinks, new Skins($db), new Capes($db), $csrfp, $authInfo, $cfg->getString('urls:skins_base'))); MojangInterop::registerRoutes($router); diff --git a/src/AccountLinkInfo.php b/src/AccountLinkInfo.php index 2c9232c..1744823 100644 --- a/src/AccountLinkInfo.php +++ b/src/AccountLinkInfo.php @@ -3,20 +3,23 @@ namespace Mince; use Index\DateTime; use Index\Data\IDbResult; -use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; +use Ramsey\Uuid\{Uuid,UuidInterface}; class AccountLinkInfo { - private string $userId; - private string $uuid; - private string $name; - private int $created; + public function __construct( + private string $userId, + private string $uuid, + private string $name, + private int $created + ) {} - public function __construct(IDbResult $result) { - $this->userId = $result->getString(0); - $this->uuid = $result->getString(1); - $this->name = $result->getString(2); - $this->created = $result->getInteger(3); + public static function fromResult(IDbResult $result): self { + return new AccountLinkInfo( + userId: $result->getString(0), + uuid: $result->getString(1), + name: $result->getString(2), + created: $result->getInteger(3), + ); } public function getUserId(): string { diff --git a/src/AccountLinks.php b/src/AccountLinks.php index 2ae4504..abd4145 100644 --- a/src/AccountLinks.php +++ b/src/AccountLinks.php @@ -3,8 +3,7 @@ namespace Mince; use InvalidArgumentException; use RuntimeException; -use Index\Data\DbStatementCache; -use Index\Data\IDbConnection; +use Index\Data\{DbStatementCache,IDbConnection}; use Ramsey\Uuid\UuidInterface; class AccountLinks { @@ -64,7 +63,7 @@ class AccountLinks { if(!$result->next()) throw new RuntimeException('Link info not found.'); - return new AccountLinkInfo($result); + return AccountLinkInfo::fromResult($result); } public function createLink( diff --git a/src/AuthorisationInfo.php b/src/AuthorisationInfo.php index 61a9808..496650b 100644 --- a/src/AuthorisationInfo.php +++ b/src/AuthorisationInfo.php @@ -4,24 +4,27 @@ namespace Mince; use Index\DateTime; use Index\Data\IDbResult; use Index\Net\IPAddress; -use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; +use Ramsey\Uuid\{Uuid,UuidInterface}; class AuthorisationInfo { - private string $id; - private string $uuid; - private string $addr; - private int $requested; - private ?int $granted; - private ?int $used; + public function __construct( + private string $id, + private string $uuid, + private string $addr, + private int $requested, + private ?int $granted, + private ?int $used, + ) {} - public function __construct(IDbResult $result) { - $this->id = $result->getString(0); - $this->uuid = $result->getString(1); - $this->addr = $result->getString(2); - $this->requested = $result->getInteger(3); - $this->granted = $result->isNull(4) ? null : $result->getInteger(4); - $this->used = $result->isNull(5) ? null : $result->getInteger(5); + public static function fromResult(IDbResult $result): self { + return new AuthorisationInfo( + id: $result->getString(0), + uuid: $result->getString(1), + addr: $result->getString(2), + requested: $result->getInteger(3), + granted: $result->getIntegerOrNull(4), + used: $result->getIntegerOrNull(5), + ); } public function getId(): string { diff --git a/src/Authorisations.php b/src/Authorisations.php index ca37da0..9f586ff 100644 --- a/src/Authorisations.php +++ b/src/Authorisations.php @@ -3,8 +3,7 @@ namespace Mince; use InvalidArgumentException; use RuntimeException; -use Index\Data\DbStatementCache; -use Index\Data\IDbConnection; +use Index\Data\{DbStatementCache,IDbConnection}; use Index\Net\IPAddress; use Ramsey\Uuid\UuidInterface; @@ -23,7 +22,7 @@ class Authorisations { public function getAuthorisations( AccountLinkInfo|UuidInterface|string $uuid - ): array { + ): iterable { if($uuid instanceof AccountLinkInfo) $uuid = $uuid->getUUIDRaw(); elseif($uuid instanceof UuidInterface) @@ -33,13 +32,7 @@ class Authorisations { $stmt->addParameter(1, $uuid); $stmt->execute(); - $clients = []; - $result = $stmt->getResult(); - - while($result->next()) - $clients[] = new AuthorisationInfo($result); - - return $clients; + return $stmt->getResult()->getIterator(AuthorisationInfo::fromResult(...)); } public function getAuthorisation( @@ -92,7 +85,7 @@ class Authorisations { if(!$result->next()) throw new RuntimeException('Authorisation info not found.'); - return new AuthorisationInfo($result); + return AuthorisationInfo::fromResult($result); } public function createAuthorisation( diff --git a/src/CapeInfo.php b/src/CapeInfo.php index 8c389be..f2e6a5f 100644 --- a/src/CapeInfo.php +++ b/src/CapeInfo.php @@ -5,14 +5,18 @@ use Index\DateTime; use Index\Data\IDbResult; class CapeInfo { - private string $userId; - private string $hash; - private int $updated; + public function __construct( + private string $userId, + private string $hash, + private int $updated, + ) {} - public function __construct(IDbResult $result) { - $this->userId = $result->getString(0); - $this->hash = $result->getString(1); - $this->updated = $result->getInteger(2); + public static function fromResult(IDbResult $result): self { + return new CapeInfo( + userId: $result->getString(0), + hash: $result->getString(1), + updated: $result->getInteger(2), + ); } public function getUserId(): string { diff --git a/src/Capes.php b/src/Capes.php index 66fcf88..3fbba61 100644 --- a/src/Capes.php +++ b/src/Capes.php @@ -3,8 +3,7 @@ namespace Mince; use InvalidArgumentException; use RuntimeException; -use Index\Data\DbStatementCache; -use Index\Data\IDbConnection; +use Index\Data\{DbStatementCache,IDbConnection}; class Capes { private DbStatementCache $cache; @@ -35,7 +34,7 @@ class Capes { $stmt->execute(); $result = $stmt->getResult(); - return $result->next() ? new CapeInfo($result) : null; + return $result->next() ? CapeInfo::fromResult($result) : null; } public function updateCape(AccountLinkInfo|UserInfo|string $userInfo, string $hash): void { diff --git a/src/ClientsRoutes.php b/src/ClientsRoutes.php index c06aa2c..8559398 100644 --- a/src/ClientsRoutes.php +++ b/src/ClientsRoutes.php @@ -3,12 +3,12 @@ namespace Mince; use InvalidArgumentException; use RuntimeException; -use Index\Routing\IRouter; +use Index\Routing\{Route,RouteHandler}; use Index\Security\CSRFP; use Ramsey\Uuid\Uuid; use Sasae\SasaeEnvironment; -class ClientsRoutes { +class ClientsRoutes extends RouteHandler { public function __construct( private SasaeEnvironment $templating, private AccountLinks $accountLinks, @@ -18,15 +18,7 @@ class ClientsRoutes { private object $authInfo ) {} - public function register(IRouter $router): void { - $router->use('/clients', [$this, 'verifyRequest']); - $router->get('/clients', [$this, 'getClients']); - $router->post('/clients/link', [$this, 'postLink']); - $router->post('/clients/unlink', [$this, 'postUnlink']); - $router->post('/clients/authorise', [$this, 'postAuthorise']); - $router->post('/clients/deauthorise', [$this, 'postDeauthorise']); - } - + #[Route('/clients')] public function verifyRequest($response, $request) { if(!$this->authInfo->success) return 403; @@ -49,6 +41,7 @@ class ClientsRoutes { ], ]; + #[Route('GET', '/clients')] public function getClients($response, $request) { $template = $this->templating->load('clients/index'); @@ -69,7 +62,7 @@ class ClientsRoutes { try { $linkInfo = $this->accountLinks->getLink(userInfo: $this->authInfo->user_id); - $clients = $this->authorisations->getAuthorisations($linkInfo); + $clients = iterator_to_array($this->authorisations->getAuthorisations($linkInfo)); $template->setVars([ 'link' => $linkInfo, @@ -80,6 +73,7 @@ class ClientsRoutes { return $template; } + #[Route('POST', '/clients/link')] public function postLink($response, $request) { if($this->accountLinks->checkHasLink($this->authInfo->user_id)) { $response->redirect('/clients?error=link:already'); @@ -109,11 +103,13 @@ class ClientsRoutes { $response->redirect('/clients'); } + #[Route('POST', '/clients/unlink')] public function postUnlink($response) { $this->accountLinks->deleteLink(userInfo: $this->authInfo->user_id); $response->redirect('/clients'); } + #[Route('POST', '/clients/authorise')] public function postAuthorise($response, $request) { $body = $request->getContent(); $authId = (string)$body->getParam('auth'); @@ -142,6 +138,7 @@ class ClientsRoutes { $response->redirect('/clients'); } + #[Route('POST', '/clients/deauthorise')] public function postDeauthorise($response, $request) { $body = $request->getContent(); $authId = (string)$body->getParam('auth'); diff --git a/src/HomeRoutes.php b/src/HomeRoutes.php index dfdaa5c..2aa4e07 100644 --- a/src/HomeRoutes.php +++ b/src/HomeRoutes.php @@ -1,10 +1,10 @@ get('/', [$this, 'getIndex']); - $router->get('/downloads', [$this, 'getDownloads']); - $router->get('/guide', [$this, 'getGuide']); - $router->get('/login', fn($response) => $response->redirect($this->userInfo->success ? '/' : $this->loginUrl)); - $router->get('/index.php', function($response) { - $response->redirect('/', true); - }); - } - + #[Route('GET', '/')] public function getIndex($response, $request) { return $this->templating->render('index', [ - 'servers' => $this->servers->getServers(deleted: false), + 'servers' => iterator_to_array($this->servers->getServers(deleted: false)), ]); } + #[Route('GET', '/login')] + public function getLogin($response) { + $response->redirect($this->userInfo->success ? '/' : $this->loginUrl); + } + + #[Route('GET', '/downloads')] public function getDownloads() { return $this->templating->render('downloads'); } + #[Route('GET', '/guide')] public function getGuide() { return $this->templating->render('guide'); } + + #[Route('GET', '/index.php')] + public function getRedirect($response) { + $response->redirect('/', true); + } } diff --git a/src/MojangInterop.php b/src/MojangInterop.php index 53ac87e..6234549 100644 --- a/src/MojangInterop.php +++ b/src/MojangInterop.php @@ -2,11 +2,9 @@ namespace Mince; use stdClass; -use Index\Http\HttpResponseBuilder; -use Index\Http\HttpRequest; +use Index\Http\{HttpResponseBuilder,HttpRequest}; use Index\Routing\IRouter; -use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; +use Ramsey\Uuid\{Uuid,UuidInterface}; final class MojangInterop { private const API_SERVER = 'https://api.mojang.com'; diff --git a/src/RpcRoutes.php b/src/RpcRoutes.php index 1ee5f30..5390a42 100644 --- a/src/RpcRoutes.php +++ b/src/RpcRoutes.php @@ -5,10 +5,10 @@ use stdClass; use InvalidArgumentException; use RuntimeException; use Stringable; -use Index\Routing\IRouter; +use Index\Routing\{Route,RouteHandler}; use Ramsey\Uuid\Uuid; -class RpcRoutes { +class RpcRoutes extends RouteHandler { public function __construct( private Users $users, private AccountLinks $accountLinks, @@ -18,11 +18,6 @@ class RpcRoutes { private string $clientsUrl ) {} - public function register(IRouter $router): void { - $router->use('/rpc', [$this, 'verifyRequest']); - $router->post('/rpc/auth', [$this, 'postAuth']); - } - private static function createPayload(string $name, array $attrs = []): object { $payload = new stdClass; $payload->name = $name; @@ -46,6 +41,7 @@ class RpcRoutes { return self::createPayload('error', $attrs); } + #[Route('/rpc')] public function verifyRequest($response, $request) { $userTime = (int)$request->getHeaderLine('X-Mince-Time'); $userHash = base64_decode((string)$request->getHeaderLine('X-Mince-Hash')); @@ -72,6 +68,7 @@ class RpcRoutes { return self::createErrorPayload('verification', 'Request verification failed.'); } + #[Route('POST', '/rpc/auth')] public function postAuth($response, $request) { $body = $request->getContent(); diff --git a/src/ServerInfo.php b/src/ServerInfo.php index 256c96b..8899ac3 100644 --- a/src/ServerInfo.php +++ b/src/ServerInfo.php @@ -5,26 +5,30 @@ use Index\DateTime; use Index\Data\IDbResult; class ServerInfo { - private string $id; - private string $name; - private string $details; - private ?string $javaAddress; - private ?string $javaVersion; - private ?string $bedrockAddress; - private ?string $bedrockVersion; - private int $created; - private ?int $deleted; + public function __construct( + private string $id, + private string $name, + private string $details, + private ?string $javaAddress, + private ?string $javaVersion, + private ?string $bedrockAddress, + private ?string $bedrockVersion, + private int $created, + private ?int $deleted, + ) {} - public function __construct(IDbResult $result) { - $this->id = $result->getString(0); - $this->name = $result->getString(1); - $this->details = $result->getString(2); - $this->javaAddress = $result->isNull(3) ? null : $result->getString(3); - $this->javaVersion = $result->isNull(4) ? null : $result->getString(4); - $this->bedrockAddress = $result->isNull(5) ? null : $result->getString(5); - $this->bedrockVersion = $result->isNull(6) ? null : $result->getString(6); - $this->created = $result->getInteger(7); - $this->deleted = $result->isNull(8) ? null : $result->getInteger(8); + public static function fromResult(IDbResult $result): self { + return new ServerInfo( + id: $result->getString(0), + name: $result->getString(1), + details: $result->getString(2), + javaAddress: $result->getStringOrNull(3), + javaVersion: $result->getStringOrNull(4), + bedrockAddress: $result->getStringOrNull(5), + bedrockVersion: $result->getStringOrNull(6), + created: $result->getInteger(7), + deleted: $result->getIntegerOrNull(8), + ); } public function getId(): string { diff --git a/src/Servers.php b/src/Servers.php index 45f0d25..efe19e6 100644 --- a/src/Servers.php +++ b/src/Servers.php @@ -1,8 +1,7 @@ cache->get($query); $stmt->execute(); - $result = $stmt->getResult(); - $servers = []; - - while($result->next()) - $servers[] = new ServerInfo($result); - - return $servers; + return $stmt->getResult()->getIterator(ServerInfo::fromResult(...)); } } diff --git a/src/SkinInfo.php b/src/SkinInfo.php index 1b238c5..6da1a28 100644 --- a/src/SkinInfo.php +++ b/src/SkinInfo.php @@ -5,16 +5,20 @@ use Index\DateTime; use Index\Data\IDbResult; class SkinInfo { - private string $userId; - private string $hash; - private string $model; - private int $updated; + public function __construct( + private string $userId, + private string $hash, + private string $model, + private int $updated, + ) {} - public function __construct(IDbResult $result) { - $this->userId = $result->getString(0); - $this->hash = $result->getString(1); - $this->model = $result->getString(2); - $this->updated = $result->getInteger(3); + public static function fromResult(IDbResult $result): self { + return new SkinInfo( + userId: $result->getString(0), + hash: $result->getString(1), + model: $result->getString(2), + updated: $result->getInteger(3), + ); } public function getUserId(): string { diff --git a/src/Skins.php b/src/Skins.php index 5a8cf2a..b99267f 100644 --- a/src/Skins.php +++ b/src/Skins.php @@ -3,8 +3,7 @@ namespace Mince; use InvalidArgumentException; use RuntimeException; -use Index\Data\DbStatementCache; -use Index\Data\IDbConnection; +use Index\Data\{DbStatementCache,IDbConnection}; class Skins { public const MODELS = ['classic', 'slim']; @@ -37,7 +36,7 @@ class Skins { $stmt->execute(); $result = $stmt->getResult(); - return $result->next() ? new SkinInfo($result) : null; + return $result->next() ? SkinInfo::fromResult($result) : null; } public function updateSkin(AccountLinkInfo|UserInfo|string $userInfo, string $hash, string $model): void { diff --git a/src/SkinsRoutes.php b/src/SkinsRoutes.php index 09a38f1..baa186d 100644 --- a/src/SkinsRoutes.php +++ b/src/SkinsRoutes.php @@ -7,12 +7,12 @@ use ImagickPixel; use InvalidArgumentException; use RuntimeException; use Index\XString; -use Index\Routing\IRouter; +use Index\Routing\{Route,RouteHandler}; use Index\Security\CSRFP; use Ramsey\Uuid\Uuid; use Sasae\SasaeEnvironment; -class SkinsRoutes { +class SkinsRoutes extends RouteHandler { private const TEXTURES_DIR = '/textures'; private const TEXTURES_PATH = MCR_DIR_PUB . self::TEXTURES_DIR; @@ -33,18 +33,6 @@ class SkinsRoutes { throw new RuntimeException('Textures directory is not writable.'); } - public function register(IRouter $router): void { - $router->use('/skins', [$this, 'verifyRequest']); - $router->get('/skins', [$this, 'getSkins']); - $router->post('/skins/upload-skin', [$this, 'postUploadSkin']); - $router->post('/skins/delete-skin', [$this, 'postDeleteSkin']); - $router->post('/skins/upload-cape', [$this, 'postUploadCape']); - $router->post('/skins/delete-cape', [$this, 'postDeleteCape']); - $router->post('/skins/import', [$this, 'postImport']); - $router->get('/session/minecraft/profile/:id', [$this, 'getSessionMinecraftProfile']); - $router->get('/users/profiles/minecraft/:name', [$this, 'getUsersMinecraftProfile']); - } - public function checkHash(string $hash): bool { return $this->skins->checkHash($hash) || $this->capes->checkHash($hash); @@ -64,6 +52,7 @@ class SkinsRoutes { unlink($path); } + #[Route('/skins')] public function verifyRequest($response, $request) { if(!$this->authInfo->success) return 403; @@ -97,6 +86,7 @@ class SkinsRoutes { ], ]; + #[Route('GET', '/skins')] public function getSkins($response, $request) { $skinInfo = $this->skins->getSkin($this->linkInfo); $skinPath = $skinInfo === null ? null : $this->getRemotePath($skinInfo->getHash(), false); @@ -129,6 +119,7 @@ class SkinsRoutes { return $template; } + #[Route('POST', '/skins/upload-skin')] public function postUploadSkin($response, $request) { $body = $request->getContent(); if(!$body->hasUploadedFile('texture')) @@ -191,6 +182,7 @@ class SkinsRoutes { $response->redirect('/skins'); } + #[Route('POST', '/skins/delete-skin')] public function postDeleteSkin($response) { $skinInfo = $this->skins->getSkin($this->linkInfo); if($skinInfo !== null) { @@ -201,6 +193,7 @@ class SkinsRoutes { $response->redirect('/skins'); } + #[Route('POST', '/skins/upload-cape')] public function postUploadCape($response, $request) { $body = $request->getContent(); if(!$body->hasUploadedFile('texture')) @@ -252,6 +245,7 @@ class SkinsRoutes { $response->redirect('/skins'); } + #[Route('POST', '/skins/delete-cape')] public function postDeleteCape($response) { $capeInfo = $this->capes->getCape($this->linkInfo); if($capeInfo !== null) { @@ -262,6 +256,7 @@ class SkinsRoutes { $response->redirect('/skins'); } + #[Route('POST', '/skins/import')] public function postImport($response, $request) { $body = $request->getContent(); $userAgent = $request->getHeaderLine('User-Agent'); @@ -331,6 +326,7 @@ class SkinsRoutes { $response->redirect('/skins'); } + #[Route('GET', '/session/minecraft/profile/:id')] public function getSessionMinecraftProfile($response, $request, string $id) { try { $uuid = Uuid::fromString($id); @@ -390,6 +386,7 @@ class SkinsRoutes { ]; } + #[Route('GET', '/users/profiles/minecraft/:name')] public function getUsersMinecraftProfile($response, $request, string $name) { try { $linkInfo = $this->accountLinks->getLink(name: $name); diff --git a/src/UserInfo.php b/src/UserInfo.php index 204b307..b737b36 100644 --- a/src/UserInfo.php +++ b/src/UserInfo.php @@ -1,19 +1,22 @@ id = $result->getString(0); - $this->name = $result->getString(1); - $this->colour = $result->isNull(2) ? null : $result->getInteger(2); + public static function fromResult(IDbResult $result): self { + return new UserInfo( + id: $result->getString(0), + name: $result->getString(1), + colour: $result->getIntegerOrNull(2), + ); } public function getId(): string { diff --git a/src/Users.php b/src/Users.php index 5b5ae9f..0b9af02 100644 --- a/src/Users.php +++ b/src/Users.php @@ -2,8 +2,7 @@ namespace Mince; use RuntimeException; -use Index\Data\DbStatementCache; -use Index\Data\IDbConnection; +use Index\Data\{DbStatementCache,IDbConnection}; class Users { private DbStatementCache $cache; @@ -35,6 +34,6 @@ class Users { if(!$result->next()) throw new RuntimeException('User info not found.'); - return new UserInfo($result); + return UserInfo::fromResult($result); } } diff --git a/src/VerificationInfo.php b/src/VerificationInfo.php index f175242..71f8546 100644 --- a/src/VerificationInfo.php +++ b/src/VerificationInfo.php @@ -4,22 +4,25 @@ namespace Mince; use Index\DateTime; use Index\Data\IDbResult; use Index\Net\IPAddress; -use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; +use Ramsey\Uuid\{Uuid,UuidInterface}; class VerificationInfo { - private string $code; - private string $uuid; - private string $name; - private string $addr; - private int $created; + public function __construct( + private string $code, + private string $uuid, + private string $name, + private string $addr, + private int $created, + ) {} - public function __construct(IDbResult $result) { - $this->code = $result->getString(0); - $this->uuid = $result->getString(1); - $this->name = $result->getString(2); - $this->addr = $result->getString(3); - $this->created = $result->getInteger(4); + public static function fromResult(IDbResult $result): self { + return new VerificationInfo( + code: $result->getString(0), + uuid: $result->getString(1), + name: $result->getString(2), + addr: $result->getString(3), + created: $result->getInteger(4), + ); } public function getCode(): string { diff --git a/src/Verifications.php b/src/Verifications.php index b017fb5..be5501b 100644 --- a/src/Verifications.php +++ b/src/Verifications.php @@ -3,8 +3,7 @@ namespace Mince; use InvalidArgumentException; use RuntimeException; -use Index\Data\DbStatementCache; -use Index\Data\IDbConnection; +use Index\Data\{DbStatementCache,IDbConnection}; use Index\Net\IPAddress; use Index\Serialisation\Base32; use Ramsey\Uuid\UuidInterface; @@ -74,7 +73,7 @@ class Verifications { if(!$result->next()) throw new RuntimeException('Verification info not found.'); - return new VerificationInfo($result); + return VerificationInfo::fromResult($result); } public function createVerification(