Updated to router v3.
This commit is contained in:
parent
d98703ebbe
commit
e38c3fca85
10 changed files with 669 additions and 360 deletions
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"require": {
|
||||
"flashwave/index": "^0.2501",
|
||||
"flashii/apii": "^0.3",
|
||||
"flashwave/index": "^0.2503",
|
||||
"flashii/apii": "^0.4",
|
||||
"ramsey/uuid": "^4.7",
|
||||
"sentry/sdk": "^4.0",
|
||||
"nesbot/carbon": "^3.8"
|
||||
|
|
574
composer.lock
generated
574
composer.lock
generated
|
@ -4,20 +4,20 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "1915d5b83915a823d3d8b39f9b9e06b1",
|
||||
"content-hash": "d44aca0929111efbc72a8ad988f8d9ea",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.12.1",
|
||||
"version": "0.12.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/brick/math.git",
|
||||
"reference": "f510c0a40911935b77b86859eb5223d58d660df1"
|
||||
"reference": "866551da34e9a618e64a819ee1e01c20d8a588ba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/f510c0a40911935b77b86859eb5223d58d660df1",
|
||||
"reference": "f510c0a40911935b77b86859eb5223d58d660df1",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/866551da34e9a618e64a819ee1e01c20d8a588ba",
|
||||
"reference": "866551da34e9a618e64a819ee1e01c20d8a588ba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -26,7 +26,7 @@
|
|||
"require-dev": {
|
||||
"php-coveralls/php-coveralls": "^2.2",
|
||||
"phpunit/phpunit": "^10.1",
|
||||
"vimeo/psalm": "5.16.0"
|
||||
"vimeo/psalm": "6.8.8"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -56,7 +56,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/brick/math/issues",
|
||||
"source": "https://github.com/brick/math/tree/0.12.1"
|
||||
"source": "https://github.com/brick/math/tree/0.12.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -64,7 +64,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-11-29T23:19:16+00:00"
|
||||
"time": "2025-02-28T13:11:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "carbonphp/carbon-doctrine-types",
|
||||
|
@ -137,18 +137,20 @@
|
|||
},
|
||||
{
|
||||
"name": "flashii/apii",
|
||||
"version": "v0.3.0",
|
||||
"version": "v0.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://patchii.net/flashii/apii-php.git",
|
||||
"reference": "2d6c135faddd359341762afcb9c429e279d87059"
|
||||
"reference": "d330e0792515dbae2832bd8e2ac761cc685175e9"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1"
|
||||
"guzzlehttp/guzzle": "~7.9",
|
||||
"php": ">=8.1",
|
||||
"psr/http-client": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.12",
|
||||
"phpunit/phpunit": "^10.5"
|
||||
"phpstan/phpstan": "~2.1",
|
||||
"phpunit/phpunit": "~10.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -170,25 +172,27 @@
|
|||
],
|
||||
"description": "Client library for the Flashii.net API.",
|
||||
"homepage": "https://api.flashii.net",
|
||||
"time": "2024-11-22T21:36:01+00:00"
|
||||
"time": "2025-03-20T17:05:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "flashwave/index",
|
||||
"version": "v0.2501.221237",
|
||||
"version": "v0.2503.201929",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://patchii.net/flash/index.git",
|
||||
"reference": "fee9a65e3bca341be7401fe2e21b795630f15f2a"
|
||||
"reference": "1ba9e8fa34fbd30c84c23b2a9b6beb2152ca54f0"
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=8.4",
|
||||
"twig/html-extra": "^3.18",
|
||||
"twig/twig": "^3.18"
|
||||
"psr/http-message": "^2.0",
|
||||
"psr/http-server-handler": "^1.0",
|
||||
"twig/html-extra": "^3.20",
|
||||
"twig/twig": "^3.20"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^2.1",
|
||||
"phpunit/phpunit": "^11.5"
|
||||
"phpunit/phpunit": "^12.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-memcache": "Support for the Index\\Cache\\Memcached namespace (only if you can't use ext-memcached for some reason).",
|
||||
|
@ -225,7 +229,216 @@
|
|||
],
|
||||
"description": "Composer package for the common library for my projects.",
|
||||
"homepage": "https://railgun.sh/index",
|
||||
"time": "2025-01-22T12:38:11+00:00"
|
||||
"time": "2025-03-20T19:29:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.9.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "d281ed313b989f213357e3be1a179f02196ac99b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/d281ed313b989f213357e3be1a179f02196ac99b",
|
||||
"reference": "d281ed313b989f213357e3be1a179f02196ac99b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"guzzlehttp/promises": "^1.5.3 || ^2.0.3",
|
||||
"guzzlehttp/psr7": "^2.7.0",
|
||||
"php": "^7.2.5 || ^8.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"symfony/deprecation-contracts": "^2.2 || ^3.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/http-client-implementation": "1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"ext-curl": "*",
|
||||
"guzzle/client-integration-tests": "3.0.2",
|
||||
"php-http/message-factory": "^1.1",
|
||||
"phpunit/phpunit": "^8.5.39 || ^9.6.20",
|
||||
"psr/log": "^1.1 || ^2.0 || ^3.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-curl": "Required for CURL handler support",
|
||||
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
|
||||
"psr/log": "Required for using the Log middleware"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions_include.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
},
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
},
|
||||
{
|
||||
"name": "Jeremy Lindblom",
|
||||
"email": "jeremeamia@gmail.com",
|
||||
"homepage": "https://github.com/jeremeamia"
|
||||
},
|
||||
{
|
||||
"name": "George Mponos",
|
||||
"email": "gmponos@gmail.com",
|
||||
"homepage": "https://github.com/gmponos"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/Nyholm"
|
||||
},
|
||||
{
|
||||
"name": "Márk Sági-Kazár",
|
||||
"email": "mark.sagikazar@gmail.com",
|
||||
"homepage": "https://github.com/sagikazarmark"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Schultze",
|
||||
"email": "webmaster@tubo-world.de",
|
||||
"homepage": "https://github.com/Tobion"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle is a PHP HTTP client library",
|
||||
"keywords": [
|
||||
"client",
|
||||
"curl",
|
||||
"framework",
|
||||
"http",
|
||||
"http client",
|
||||
"psr-18",
|
||||
"psr-7",
|
||||
"rest",
|
||||
"web service"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.9.2"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/GrahamCampbell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/Nyholm",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-07-24T11:22:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
"version": "2.0.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/promises.git",
|
||||
"reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/promises/zipball/f9c436286ab2892c7db7be8c8da4ef61ccf7b455",
|
||||
"reference": "f9c436286ab2892c7db7be8c8da4ef61ccf7b455",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2.5 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"bamarni/composer-bin-plugin": "^1.8.2",
|
||||
"phpunit/phpunit": "^8.5.39 || ^9.6.20"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"bamarni-bin": {
|
||||
"bin-links": true,
|
||||
"forward-command": false
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"GuzzleHttp\\Promise\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
},
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/Nyholm"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Schultze",
|
||||
"email": "webmaster@tubo-world.de",
|
||||
"homepage": "https://github.com/Tobion"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle promises library",
|
||||
"keywords": [
|
||||
"promise"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/promises/issues",
|
||||
"source": "https://github.com/guzzle/promises/tree/2.0.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/GrahamCampbell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/Nyholm",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-17T10:06:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/psr7",
|
||||
|
@ -345,16 +558,16 @@
|
|||
},
|
||||
{
|
||||
"name": "jean85/pretty-package-versions",
|
||||
"version": "2.1.0",
|
||||
"version": "2.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Jean85/pretty-package-versions.git",
|
||||
"reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10"
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/3c4e5f62ba8d7de1734312e4fff32f67a8daaf10",
|
||||
"reference": "3c4e5f62ba8d7de1734312e4fff32f67a8daaf10",
|
||||
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"reference": "4d7aa5dab42e2a76d99559706022885de0e18e1a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -364,8 +577,9 @@
|
|||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"jean85/composer-provided-replaced-stub-package": "^1.0",
|
||||
"phpstan/phpstan": "^1.4",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpunit/phpunit": "^7.5|^8.5|^9.6",
|
||||
"rector/rector": "^2.0",
|
||||
"vimeo/psalm": "^4.3 || ^5.0"
|
||||
},
|
||||
"type": "library",
|
||||
|
@ -398,22 +612,22 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Jean85/pretty-package-versions/issues",
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.0"
|
||||
"source": "https://github.com/Jean85/pretty-package-versions/tree/2.1.1"
|
||||
},
|
||||
"time": "2024-11-18T16:19:46+00:00"
|
||||
"time": "2025-03-19T14:43:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.8.4",
|
||||
"version": "3.8.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/CarbonPHP/carbon.git",
|
||||
"reference": "129700ed449b1f02d70272d2ac802357c8c30c58"
|
||||
"reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/129700ed449b1f02d70272d2ac802357c8c30c58",
|
||||
"reference": "129700ed449b1f02d70272d2ac802357c8c30c58",
|
||||
"url": "https://api.github.com/repos/CarbonPHP/carbon/zipball/ff2f20cf83bd4d503720632ce8a426dc747bf7fd",
|
||||
"reference": "ff2f20cf83bd4d503720632ce8a426dc747bf7fd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -489,8 +703,8 @@
|
|||
],
|
||||
"support": {
|
||||
"docs": "https://carbon.nesbot.com/docs",
|
||||
"issues": "https://github.com/briannesbitt/Carbon/issues",
|
||||
"source": "https://github.com/briannesbitt/Carbon"
|
||||
"issues": "https://github.com/CarbonPHP/carbon/issues",
|
||||
"source": "https://github.com/CarbonPHP/carbon"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -506,7 +720,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-27T09:25:35+00:00"
|
||||
"time": "2025-02-20T17:33:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/clock",
|
||||
|
@ -556,6 +770,58 @@
|
|||
},
|
||||
"time": "2022-11-25T14:36:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-client",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-client.git",
|
||||
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||
"reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.0 || ^8.0",
|
||||
"psr/http-message": "^1.0 || ^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Client\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP clients",
|
||||
"homepage": "https://github.com/php-fig/http-client",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-client",
|
||||
"psr",
|
||||
"psr-18"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-client"
|
||||
},
|
||||
"time": "2023-09-23T14:17:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-factory",
|
||||
"version": "1.1.0",
|
||||
|
@ -664,6 +930,62 @@
|
|||
},
|
||||
"time": "2023-04-04T09:54:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-server-handler",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-server-handler.git",
|
||||
"reference": "84c4fb66179be4caaf8e97bd239203245302e7d4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/84c4fb66179be4caaf8e97bd239203245302e7d4",
|
||||
"reference": "84c4fb66179be4caaf8e97bd239203245302e7d4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0",
|
||||
"psr/http-message": "^1.0 || ^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Server\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "https://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP server-side request handler",
|
||||
"keywords": [
|
||||
"handler",
|
||||
"http",
|
||||
"http-interop",
|
||||
"psr",
|
||||
"psr-15",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response",
|
||||
"server"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-server-handler/tree/1.0.2"
|
||||
},
|
||||
"time": "2023-04-10T20:06:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.2",
|
||||
|
@ -760,16 +1082,16 @@
|
|||
},
|
||||
{
|
||||
"name": "ramsey/collection",
|
||||
"version": "2.0.0",
|
||||
"version": "2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ramsey/collection.git",
|
||||
"reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5"
|
||||
"reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ramsey/collection/zipball/a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5",
|
||||
"reference": "a4b48764bfbb8f3a6a4d1aeb1a35bb5e9ecac4a5",
|
||||
"url": "https://api.github.com/repos/ramsey/collection/zipball/3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109",
|
||||
"reference": "3c5990b8a5e0b79cd1cf11c2dc1229e58e93f109",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -777,25 +1099,22 @@
|
|||
},
|
||||
"require-dev": {
|
||||
"captainhook/plugin-composer": "^5.3",
|
||||
"ergebnis/composer-normalize": "^2.28.3",
|
||||
"fakerphp/faker": "^1.21",
|
||||
"ergebnis/composer-normalize": "^2.45",
|
||||
"fakerphp/faker": "^1.24",
|
||||
"hamcrest/hamcrest-php": "^2.0",
|
||||
"jangregor/phpstan-prophecy": "^1.0",
|
||||
"mockery/mockery": "^1.5",
|
||||
"jangregor/phpstan-prophecy": "^2.1",
|
||||
"mockery/mockery": "^1.6",
|
||||
"php-parallel-lint/php-console-highlighter": "^1.0",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3",
|
||||
"phpcsstandards/phpcsutils": "^1.0.0-rc1",
|
||||
"phpspec/prophecy-phpunit": "^2.0",
|
||||
"phpstan/extension-installer": "^1.2",
|
||||
"phpstan/phpstan": "^1.9",
|
||||
"phpstan/phpstan-mockery": "^1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.3",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"psalm/plugin-mockery": "^1.1",
|
||||
"psalm/plugin-phpunit": "^0.18.4",
|
||||
"ramsey/coding-standard": "^2.0.3",
|
||||
"ramsey/conventional-commits": "^1.3",
|
||||
"vimeo/psalm": "^5.4"
|
||||
"php-parallel-lint/php-parallel-lint": "^1.4",
|
||||
"phpspec/prophecy-phpunit": "^2.3",
|
||||
"phpstan/extension-installer": "^1.4",
|
||||
"phpstan/phpstan": "^2.1",
|
||||
"phpstan/phpstan-mockery": "^2.0",
|
||||
"phpstan/phpstan-phpunit": "^2.0",
|
||||
"phpunit/phpunit": "^10.5",
|
||||
"ramsey/coding-standard": "^2.3",
|
||||
"ramsey/conventional-commits": "^1.6",
|
||||
"roave/security-advisories": "dev-latest"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
|
@ -833,19 +1152,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ramsey/collection/issues",
|
||||
"source": "https://github.com/ramsey/collection/tree/2.0.0"
|
||||
"source": "https://github.com/ramsey/collection/tree/2.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/ramsey",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/ramsey/collection",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-12-31T21:50:55+00:00"
|
||||
"time": "2025-03-02T04:48:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ramsey/uuid",
|
||||
|
@ -1226,16 +1535,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v7.2.1",
|
||||
"version": "v7.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mime.git",
|
||||
"reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283"
|
||||
"reference": "87ca22046b78c3feaff04b337f33b38510fd686b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/7f9617fcf15cb61be30f8b252695ed5e2bfac283",
|
||||
"reference": "7f9617fcf15cb61be30f8b252695ed5e2bfac283",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/87ca22046b78c3feaff04b337f33b38510fd686b",
|
||||
"reference": "87ca22046b78c3feaff04b337f33b38510fd686b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1290,7 +1599,7 @@
|
|||
"mime-type"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mime/tree/v7.2.1"
|
||||
"source": "https://github.com/symfony/mime/tree/v7.2.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1306,7 +1615,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-07T08:50:44+00:00"
|
||||
"time": "2025-02-19T08:51:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
|
@ -1698,82 +2007,6 @@
|
|||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"version": "v1.31.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php81.git",
|
||||
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||
"reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"thanks": {
|
||||
"url": "https://github.com/symfony/polyfill",
|
||||
"name": "symfony/polyfill"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"bootstrap.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Polyfill\\Php81\\": ""
|
||||
},
|
||||
"classmap": [
|
||||
"Resources/stubs"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"compatibility",
|
||||
"polyfill",
|
||||
"portable",
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-09T11:45:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php83",
|
||||
"version": "v1.31.0",
|
||||
|
@ -1852,16 +2085,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v7.2.2",
|
||||
"version": "v7.2.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "e2674a30132b7cc4d74540d6c2573aa363f05923"
|
||||
"reference": "283856e6981286cc0d800b53bd5703e8e363f05a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/e2674a30132b7cc4d74540d6c2573aa363f05923",
|
||||
"reference": "e2674a30132b7cc4d74540d6c2573aa363f05923",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/283856e6981286cc0d800b53bd5703e8e363f05a",
|
||||
"reference": "283856e6981286cc0d800b53bd5703e8e363f05a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1927,7 +2160,7 @@
|
|||
"description": "Provides tools to internationalize your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation/tree/v7.2.2"
|
||||
"source": "https://github.com/symfony/translation/tree/v7.2.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1943,7 +2176,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-07T08:18:10+00:00"
|
||||
"time": "2025-02-13T10:27:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation-contracts",
|
||||
|
@ -2025,20 +2258,20 @@
|
|||
},
|
||||
{
|
||||
"name": "twig/html-extra",
|
||||
"version": "v3.18.0",
|
||||
"version": "v3.20.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/html-extra.git",
|
||||
"reference": "c63b28e192c1b7c15bb60f81d2e48b140846239a"
|
||||
"reference": "f7d54d4de1b64182af745cfb66777f699b599734"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/html-extra/zipball/c63b28e192c1b7c15bb60f81d2e48b140846239a",
|
||||
"reference": "c63b28e192c1b7c15bb60f81d2e48b140846239a",
|
||||
"url": "https://api.github.com/repos/twigphp/html-extra/zipball/f7d54d4de1b64182af745cfb66777f699b599734",
|
||||
"reference": "f7d54d4de1b64182af745cfb66777f699b599734",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/mime": "^5.4|^6.4|^7.0",
|
||||
"twig/twig": "^3.13|^4.0"
|
||||
|
@ -2077,7 +2310,7 @@
|
|||
"twig"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/twigphp/html-extra/tree/v3.18.0"
|
||||
"source": "https://github.com/twigphp/html-extra/tree/v3.20.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2089,28 +2322,27 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-29T10:29:59+00:00"
|
||||
"time": "2025-01-31T20:45:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v3.18.0",
|
||||
"version": "v3.20.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/twigphp/Twig.git",
|
||||
"reference": "acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50"
|
||||
"reference": "3468920399451a384bef53cf7996965f7cd40183"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50",
|
||||
"reference": "acffa88cc2b40dbe42eaf3a5025d6c0d4600cc50",
|
||||
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3468920399451a384bef53cf7996965f7cd40183",
|
||||
"reference": "3468920399451a384bef53cf7996965f7cd40183",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1.0",
|
||||
"symfony/deprecation-contracts": "^2.5|^3",
|
||||
"symfony/polyfill-ctype": "^1.8",
|
||||
"symfony/polyfill-mbstring": "^1.3",
|
||||
"symfony/polyfill-php81": "^1.29"
|
||||
"symfony/polyfill-mbstring": "^1.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^2.0",
|
||||
|
@ -2157,7 +2389,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/twigphp/Twig/issues",
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.18.0"
|
||||
"source": "https://github.com/twigphp/Twig/tree/v3.20.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2169,7 +2401,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-12-29T10:51:50+00:00"
|
||||
"time": "2025-02-13T08:34:43+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
|
|
|
@ -5,8 +5,11 @@ use InvalidArgumentException;
|
|||
use RuntimeException;
|
||||
use Flashii\V1\Users\V1User;
|
||||
use Index\CsrfToken;
|
||||
use Index\Http\{FormHttpContent,HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{HttpGet,HttpMiddleware,HttpPost,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
use Index\Templating\TplEnvironment;
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
@ -22,20 +25,6 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
private ?V1User $authInfo
|
||||
) {}
|
||||
|
||||
#[HttpMiddleware('/clients')]
|
||||
public function verifyRequest(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
if($this->authInfo === null)
|
||||
return 403;
|
||||
|
||||
if($request->method === 'POST') {
|
||||
if(!($request->content instanceof FormHttpContent))
|
||||
return 400;
|
||||
|
||||
if(!$request->content->hasParam('csrfp') || !$this->csrfp->verifyToken((string)$request->content->getParam('csrfp')))
|
||||
return 403;
|
||||
}
|
||||
}
|
||||
|
||||
private const CLIENTS_ERRORS = [
|
||||
'link' => [
|
||||
'already' => 'You already have a linked Minecraft username, unlink the other one first.',
|
||||
|
@ -44,9 +33,10 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
],
|
||||
];
|
||||
|
||||
#[HttpGet('/clients')]
|
||||
#[ExactRoute('GET', '/clients')]
|
||||
#[UrlFormat('clients:index', '/clients', ['error' => '<error>'])]
|
||||
public function getClients(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
#[Before('mince:require-authed')]
|
||||
public function getClients(HttpRequest $request) {
|
||||
$template = $this->templating->load('clients/index');
|
||||
|
||||
$errorCode = (string)$request->getParam('error');
|
||||
|
@ -77,15 +67,18 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
return $template->render();
|
||||
}
|
||||
|
||||
#[HttpPost('/clients/link')]
|
||||
#[ExactRoute('POST', '/clients/link')]
|
||||
#[UrlFormat('clients:link', '/clients/link')]
|
||||
public function postLink(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('input:urlencoded')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postLink(HttpResponseBuilder $response, FormContent $content) {
|
||||
if($this->clientsCtx->accountLinks->checkHasLink($this->authInfo->getId())) {
|
||||
$response->redirect($this->urls->format('clients:index', ['error' => 'link:already']));
|
||||
return;
|
||||
}
|
||||
|
||||
$code = (string)$request->content->getParam('code');
|
||||
$code = (string)$content->getParam('code');
|
||||
if(strlen($code) !== 10) {
|
||||
$response->redirect($this->urls->format('clients:index', ['error' => 'link:format']));
|
||||
return;
|
||||
|
@ -107,17 +100,23 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
$response->redirect($this->urls->format('clients:index'));
|
||||
}
|
||||
|
||||
#[HttpPost('/clients/unlink')]
|
||||
#[ExactRoute('POST', '/clients/unlink')]
|
||||
#[UrlFormat('clients:unlink', '/clients/unlink')]
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('input:urlencoded')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postUnlink(HttpResponseBuilder $response) {
|
||||
$this->clientsCtx->accountLinks->deleteLink(userInfo: $this->authInfo->getId());
|
||||
$response->redirect($this->urls->format('clients:index'));
|
||||
}
|
||||
|
||||
#[HttpPost('/clients/authorise')]
|
||||
#[ExactRoute('POST', '/clients/authorise')]
|
||||
#[UrlFormat('clients:authorise', '/clients/authorise')]
|
||||
public function postAuthorise(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
$authId = (string)$request->content->getParam('auth');
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('input:urlencoded')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postAuthorise(HttpResponseBuilder $response, FormContent $content) {
|
||||
$authId = (string)$content->getParam('auth');
|
||||
if(empty($authId))
|
||||
return 404;
|
||||
|
||||
|
@ -143,10 +142,13 @@ class ClientsRoutes implements RouteHandler, UrlSource {
|
|||
$response->redirect($this->urls->format('clients:index'));
|
||||
}
|
||||
|
||||
#[HttpPost('/clients/deauthorise')]
|
||||
#[ExactRoute('POST', '/clients/deauthorise')]
|
||||
#[UrlFormat('clients:deauthorise', '/clients/deauthorise')]
|
||||
public function postDeauthorise(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
$authId = (string)$request->content->getParam('auth');
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('input:urlencoded')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postDeauthorise(HttpResponseBuilder $response, FormContent $content) {
|
||||
$authId = (string)$content->getParam('auth');
|
||||
if(empty($authId))
|
||||
return 404;
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ namespace Mince;
|
|||
|
||||
use Flashii\V1\Users\V1User;
|
||||
use Index\Http\HttpResponseBuilder;
|
||||
use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Index\Templating\TplEnvironment;
|
||||
|
||||
|
@ -17,31 +18,31 @@ class HomeRoutes implements RouteHandler, UrlSource {
|
|||
private string $loginUrl
|
||||
) {}
|
||||
|
||||
#[HttpGet('/')]
|
||||
#[ExactRoute('GET', '/')]
|
||||
#[UrlFormat('index', '/')]
|
||||
public function getIndex() {
|
||||
return $this->templating->render('index');
|
||||
}
|
||||
|
||||
#[HttpGet('/login')]
|
||||
#[ExactRoute('GET', '/login')]
|
||||
#[UrlFormat('login', '/login')]
|
||||
public function getLogin(HttpResponseBuilder $response) {
|
||||
$response->redirect($this->authInfo === null ? $this->loginUrl : $this->urls->format('index'));
|
||||
}
|
||||
|
||||
#[HttpGet('/downloads')]
|
||||
#[ExactRoute('GET', '/downloads')]
|
||||
#[UrlFormat('downloads', '/downloads')]
|
||||
public function getDownloads($response) {
|
||||
$response->redirect('https://fii.moe/mc');
|
||||
}
|
||||
|
||||
#[HttpGet('/guide')]
|
||||
#[ExactRoute('GET', '/guide')]
|
||||
#[UrlFormat('guide', '/guide')]
|
||||
public function getGuide($response) {
|
||||
$response->redirect('https://fii.moe/mcguide');
|
||||
}
|
||||
|
||||
#[HttpGet('/index.php')]
|
||||
#[ExactRoute('GET', '/index.php')]
|
||||
public function getRedirect(HttpResponseBuilder $response) {
|
||||
$response->redirect($this->urls->format('index'), true);
|
||||
}
|
||||
|
|
|
@ -3,11 +3,15 @@ namespace Mince;
|
|||
|
||||
use Flashii\{FlashiiClient,FlashiiUrls};
|
||||
use Flashii\Credentials\MisuzuCredentials;
|
||||
use Flashii\V1\Users\V1User;
|
||||
use Index\{CsrfToken,Dependencies};
|
||||
use Index\Config\Config;
|
||||
use Index\Db\DbConnection;
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\RouteHandler;
|
||||
use Index\Http\Content\FormContent;
|
||||
use Index\Http\Routing\{HandlerContext,RouteHandler};
|
||||
use Index\Http\Routing\Filters\FilterInfo;
|
||||
use Index\Http\Routing\Processors\ProcessorInfo;
|
||||
use Index\Templating\TplEnvironment;
|
||||
use Index\Urls\UrlSource;
|
||||
|
||||
|
@ -40,13 +44,14 @@ class MinceContext {
|
|||
$this->deps->register($routingCtx->router);
|
||||
$this->deps->register($routingCtx->urls);
|
||||
|
||||
$routingCtx->router->use('/', function(HttpResponseBuilder $response, HttpRequest $request) use ($templating) {
|
||||
$routingCtx->router->filter(FilterInfo::prefix('/', function(HttpResponseBuilder $response, HttpRequest $request) use ($templating) {
|
||||
$authToken = (string)$request->getCookie('msz_auth');
|
||||
if(empty($authToken)) {
|
||||
$csrfSecret = $request->remoteAddress;
|
||||
$userInfo = null;
|
||||
} else {
|
||||
$flashii = new FlashiiClient('Mince', new MisuzuCredentials($authToken), new FlashiiUrls(
|
||||
$this->config->getString('apii:url', FlashiiUrls::PROD_URL),
|
||||
$this->config->getString('apii:api', FlashiiUrls::PROD_API_URL)
|
||||
));
|
||||
|
||||
|
@ -71,7 +76,30 @@ class MinceContext {
|
|||
'user' => $userInfo,
|
||||
'csrfp' => $csrfToken->createToken(),
|
||||
]);
|
||||
});
|
||||
}));
|
||||
|
||||
$routingCtx->router->preprocessor(ProcessorInfo::pre('mince:require-authed', function(HandlerContext $context) {
|
||||
$authInfo = $this->deps->resolve(V1User::class);
|
||||
if($authInfo === null)
|
||||
return 403;
|
||||
|
||||
$context->deps->register($authInfo);
|
||||
}));
|
||||
|
||||
$routingCtx->router->preprocessor(ProcessorInfo::pre('mince:verify-csrf', function(
|
||||
HandlerContext $context,
|
||||
?FormContent $content = null
|
||||
) {
|
||||
if($content === null)
|
||||
return 400;
|
||||
|
||||
$csrf = $this->deps->resolve(CsrfToken::class);
|
||||
if($csrf === null)
|
||||
return 500;
|
||||
|
||||
if(!$content->hasParam('csrfp') || !$csrf->verifyToken((string)$content->getParam('csrfp')))
|
||||
return 403;
|
||||
}));
|
||||
|
||||
$routingCtx->register($this->deps->construct(RpcRoutes::class, secretKey: $this->config->getString('rpc:secret'), clientsUrl: $this->config->getString('urls:clients')));
|
||||
$routingCtx->register($this->deps->construct(HomeRoutes::class, loginUrl: $this->config->getString('site:login')));
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace Mince;
|
|||
use stdClass;
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\Router;
|
||||
use Index\Http\Routing\Routes\RouteInfo;
|
||||
use Ramsey\Uuid\{Uuid,UuidInterface};
|
||||
|
||||
final class MojangInterop {
|
||||
|
@ -34,8 +35,14 @@ final class MojangInterop {
|
|||
}
|
||||
|
||||
public static function registerRoutes(Router $router): void {
|
||||
$router->get('/uuid', fn($response, $request) => self::uuidResolver($response, $request));
|
||||
$router->get('/blockedservers', fn($response, $request) => self::proxyBlockServers($response, $request));
|
||||
$router->route(RouteInfo::exact(
|
||||
'GET', '/uuid',
|
||||
fn(HttpResponseBuilder $response, HttpRequest $request) => self::uuidResolver($response, $request)
|
||||
));
|
||||
$router->route(RouteInfo::exact(
|
||||
'GET', '/blockedservers',
|
||||
fn(HttpResponseBuilder $response, HttpRequest $request) => self::proxyBlockServers($response, $request)
|
||||
));
|
||||
}
|
||||
|
||||
public static function uuidResolver(HttpResponseBuilder $response, HttpRequest $request): string {
|
||||
|
|
|
@ -2,18 +2,19 @@
|
|||
namespace Mince;
|
||||
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{HttpRouter,Router,RouteHandler};
|
||||
use Index\Http\Routing\{Router,RouteHandler};
|
||||
use Index\Http\Routing\Filters\FilterInfo;
|
||||
use Index\Urls\{ArrayUrlRegistry,UrlRegistry,UrlSource};
|
||||
use Index\Templating\TplEnvironment;
|
||||
|
||||
class RoutingContext {
|
||||
public private(set) UrlRegistry $urls;
|
||||
public private(set) HttpRouter $router;
|
||||
public private(set) Router $router;
|
||||
|
||||
public function __construct(TplEnvironment $templating) {
|
||||
$this->urls = new ArrayUrlRegistry;
|
||||
$this->router = new HttpRouter(errorHandler: new RoutingErrorHandler($templating));
|
||||
$this->router->use('/', fn(HttpResponseBuilder $resp) => $resp->setPoweredBy('Mince'));
|
||||
$this->router = new Router(errorHandler: new RoutingErrorHandler($templating));
|
||||
$this->router->filter(FilterInfo::prefix('/', fn(HttpResponseBuilder $resp) => $resp->setPoweredBy('Mince')));
|
||||
}
|
||||
|
||||
public function register(RouteHandler|UrlSource $handler): void {
|
||||
|
|
|
@ -1,21 +1,29 @@
|
|||
<?php
|
||||
namespace Mince;
|
||||
|
||||
use Index\Http\{HttpErrorHandler,HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\HttpResponse;
|
||||
use Index\Http\Streams\Stream;
|
||||
use Index\Http\Routing\HandlerContext;
|
||||
use Index\Http\Routing\ErrorHandling\ErrorHandler;
|
||||
use Index\Templating\TplEnvironment;
|
||||
|
||||
class RoutingErrorHandler implements HttpErrorHandler {
|
||||
class RoutingErrorHandler implements ErrorHandler {
|
||||
public function __construct(
|
||||
private TplEnvironment $templating
|
||||
) {}
|
||||
|
||||
public function handle(HttpResponseBuilder $response, HttpRequest $request, int $code, string $message): void {
|
||||
$response->setTypeHTML();
|
||||
$response->content = $this->templating->render('http-error', [
|
||||
public function handle(HandlerContext $context): void {
|
||||
if(!$context->response->needsBody)
|
||||
return;
|
||||
|
||||
$context->response->setTypeHTML('utf-8');
|
||||
$context->response->body = Stream::createStream($this->templating->render('http-error', [
|
||||
'error' => [
|
||||
'code' => sprintf('%03d', $code),
|
||||
'text' => $message,
|
||||
'code' => sprintf('%03d', $context->response->statusCode),
|
||||
'text' => $context->response->reasonPhrase === ''
|
||||
? HttpResponse::defaultReasonPhase($context->response->statusCode)
|
||||
: $context->response->reasonPhrase,
|
||||
],
|
||||
]);
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,11 @@ use stdClass;
|
|||
use InvalidArgumentException;
|
||||
use RuntimeException;
|
||||
use Stringable;
|
||||
use Index\Http\{FormHttpContent,HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{HttpMiddleware,HttpPost,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Content\UrlEncodedFormContent;
|
||||
use Index\Http\Routing\{RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\Before;
|
||||
use Index\Http\Routing\Routes\ExactRoute;
|
||||
use Mince\Clients\ClientsContext;
|
||||
use Mince\Users\UsersContext;
|
||||
use Ramsey\Uuid\Uuid;
|
||||
|
@ -44,8 +47,9 @@ class RpcRoutes implements RouteHandler {
|
|||
return self::createPayload('error', $attrs);
|
||||
}
|
||||
|
||||
#[HttpMiddleware('/rpc')]
|
||||
public function verifyRequest(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
#[ExactRoute('POST', '/rpc/auth')]
|
||||
#[Before('input:urlencoded', required: false)]
|
||||
public function postAuth(HttpResponseBuilder $response, HttpRequest $request, ?UrlEncodedFormContent $content = null) {
|
||||
$userTime = (int)$request->getHeaderLine('X-Mince-Time');
|
||||
$userHash = base64_decode((string)$request->getHeaderLine('X-Mince-Hash'));
|
||||
|
||||
|
@ -53,28 +57,24 @@ class RpcRoutes implements RouteHandler {
|
|||
if(empty($userHash) || $userTime < $currentTime - 60 || $userTime > $currentTime + 60)
|
||||
return self::createErrorPayload('verification', 'Request verification failed.');
|
||||
|
||||
$paramString = $request->getParamString();
|
||||
if($request->method === 'POST') {
|
||||
if(!($request->content instanceof FormHttpContent))
|
||||
return self::createErrorPayload('request', 'Request body is not in expect format.');
|
||||
$bodyString = $request->content->getParamString();
|
||||
if(!empty($paramString) && !empty($bodyString))
|
||||
$paramString .= '&';
|
||||
$paramString .= $bodyString;
|
||||
}
|
||||
$paramString = $request->getParamString(true);
|
||||
if($content === null)
|
||||
return self::createErrorPayload('request', 'Request body is not in expect format.');
|
||||
|
||||
$verifyText = (string)$userTime . '#' . $request->path . '?' . $paramString;
|
||||
$bodyString = $content->getParamString(true);
|
||||
if(!empty($paramString) && !empty($bodyString))
|
||||
$paramString .= '&';
|
||||
$paramString .= $bodyString;
|
||||
|
||||
$verifyText = (string)$userTime . '#' . $request->requestTarget . '?' . $paramString;
|
||||
$verifyHash = hash_hmac('sha256', $verifyText, $this->secretKey, true);
|
||||
|
||||
if(!hash_equals($verifyHash, $userHash))
|
||||
return self::createErrorPayload('verification', 'Request verification failed.');
|
||||
}
|
||||
|
||||
#[HttpPost('/rpc/auth')]
|
||||
public function postAuth(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
$id = (string)$request->content->getParam('id');
|
||||
$name = (string)$request->content->getParam('name');
|
||||
$addr = (string)$request->content->getParam('ip');
|
||||
$id = (string)$content->getParam('id');
|
||||
$name = (string)$content->getParam('name');
|
||||
$addr = (string)$content->getParam('ip');
|
||||
|
||||
if(empty($name))
|
||||
return self::createErrorPayload('auth:username', 'Username is invalid.');
|
||||
|
|
|
@ -8,9 +8,13 @@ use InvalidArgumentException;
|
|||
use RuntimeException;
|
||||
use Flashii\V1\Users\V1User;
|
||||
use Index\{CsrfToken,XString};
|
||||
use Index\Http\{FormHttpContent,HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Routing\{HttpGet,HttpMiddleware,HttpPost,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Json\JsonHttpContent;
|
||||
use Index\Http\{HttpResponseBuilder,HttpRequest};
|
||||
use Index\Http\Content\{FormContent,MultipartFormContent};
|
||||
use Index\Http\Content\Multipart\FileMultipartFormData;
|
||||
use Index\Http\Routing\{HandlerContext,RouteHandler,RouteHandlerCommon};
|
||||
use Index\Http\Routing\Processors\{Before,Preprocessor};
|
||||
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||
use Index\Http\Streams\Stream;
|
||||
use Index\Templating\TplEnvironment;
|
||||
use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
|
||||
use Mince\MojangInterop;
|
||||
|
@ -59,23 +63,14 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
unlink($path);
|
||||
}
|
||||
|
||||
#[HttpMiddleware('/skins')]
|
||||
public function verifyRequest(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
if($this->authInfo === null)
|
||||
return 403;
|
||||
|
||||
#[Preprocessor('mince:skins:get-link')]
|
||||
public function preGetLink(HandlerContext $context): void {
|
||||
try {
|
||||
$this->linkInfo = $this->clientsCtx->accountLinks->getLink(userInfo: $this->authInfo->getId());
|
||||
} catch(RuntimeException $ex) {
|
||||
$response->redirect($this->urls->format('clients:index'));
|
||||
return true;
|
||||
}
|
||||
|
||||
if($request->method === 'POST') {
|
||||
if(!($request->content instanceof FormHttpContent))
|
||||
return 400;
|
||||
if(!$request->content->hasParam('csrfp') || !$this->csrfp->verifyToken((string)$request->content->getParam('csrfp')))
|
||||
return 403;
|
||||
$context->response->statusCode = 302;
|
||||
$context->response->redirect($this->urls->format('clients:index'));
|
||||
$context->halt();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,9 +86,11 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
],
|
||||
];
|
||||
|
||||
#[HttpGet('/skins')]
|
||||
#[ExactRoute('GET', '/skins')]
|
||||
#[UrlFormat('skins:index', '/skins', ['error' => '<error>'])]
|
||||
public function getSkins(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('mince:skins:get-link')]
|
||||
public function getSkins(HttpRequest $request) {
|
||||
$skinInfo = $this->skinsCtx->skins->getSkin($this->linkInfo);
|
||||
$skinPath = $skinInfo === null ? null : $this->getRemotePath($skinInfo->hash, false);
|
||||
$capeInfo = $this->skinsCtx->capes->getCape($this->linkInfo);
|
||||
|
@ -125,71 +122,88 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
return $template->render();
|
||||
}
|
||||
|
||||
#[HttpPost('/skins/upload-skin')]
|
||||
#[ExactRoute('POST', '/skins/upload-skin')]
|
||||
#[UrlFormat('skins:skin:upload', '/skins/upload-skin')]
|
||||
public function postUploadSkin(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
if(!$request->content->hasUploadedFile('texture'))
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('mince:skins:get-link')]
|
||||
#[Before('input:multipart')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postUploadSkin(HttpResponseBuilder $response, MultipartFormContent $content) {
|
||||
$texture = $content->getParamData('texture');
|
||||
if(!($texture instanceof FileMultipartFormData))
|
||||
return 400;
|
||||
|
||||
$texture = $request->content->getUploadedFile('texture');
|
||||
$model = (string)$request->content->getParam('model');
|
||||
|
||||
$model = (string)$content->getParam('model');
|
||||
if(!in_array($model, SkinsData::MODELS)) {
|
||||
$response->redirect($this->urls->format('skins:index', ['error' => 'skin:model']));
|
||||
return;
|
||||
}
|
||||
|
||||
if($texture->size > 512000) {
|
||||
if($texture->getSize() > 512000) {
|
||||
$response->redirect($this->urls->format('skins:index', ['error' => 'skin:size']));
|
||||
return;
|
||||
}
|
||||
|
||||
$skinInfo = $this->skinsCtx->skins->getSkin($this->linkInfo);
|
||||
$tmpPath = $texture->localFileName;
|
||||
$hasNewFile = is_file($tmpPath);
|
||||
|
||||
if($hasNewFile) {
|
||||
try {
|
||||
$imagick = new Imagick($tmpPath);
|
||||
$imagick->setImageFormat('png');
|
||||
$imagick->setBackgroundColor(new ImagickPixel('transparent'));
|
||||
$imagick->setImageExtent(64, $imagick->getImageHeight() < 64 ? 32 : 64);
|
||||
$imagick->stripImage();
|
||||
$imagick->writeImage();
|
||||
$imagick->destroy();
|
||||
} catch(ImagickException $ex) {
|
||||
$response->redirect($this->urls->format('skins:index', ['error' => 'skin:format']));
|
||||
return;
|
||||
}
|
||||
|
||||
$hash = hash_file('sha256', $tmpPath);
|
||||
$localPath = $this->getLocalPath($hash);
|
||||
} else {
|
||||
$hash = $skinInfo->hash;
|
||||
$tmpPath = null;
|
||||
if($texture->getClientFilename() !== '') {
|
||||
$tmpPath = tempnam(sys_get_temp_dir(), 'mince-skin-');
|
||||
$texture->moveTo($tmpPath);
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
// apply new skin
|
||||
if($hasNewFile && !is_file($localPath))
|
||||
$texture->moveTo($localPath);
|
||||
$this->skinsCtx->skins->updateSkin($this->linkInfo, $hash, $model);
|
||||
} finally {
|
||||
// see about deleting the old one
|
||||
if($skinInfo !== null)
|
||||
$this->deleteLocalFileMaybe($skinInfo->hash);
|
||||
}
|
||||
} finally {
|
||||
// try to delete new one if something went awry
|
||||
if($hasNewFile)
|
||||
$this->deleteLocalFileMaybe($hash);
|
||||
}
|
||||
$hasNewFile = $tmpPath !== null;
|
||||
if($hasNewFile) {
|
||||
try {
|
||||
$imagick = new Imagick($tmpPath);
|
||||
$imagick->setImageFormat('png');
|
||||
$imagick->setBackgroundColor(new ImagickPixel('transparent'));
|
||||
$imagick->setImageExtent(64, $imagick->getImageHeight() < 64 ? 32 : 64);
|
||||
$imagick->stripImage();
|
||||
$imagick->writeImage();
|
||||
$imagick->destroy();
|
||||
} catch(ImagickException $ex) {
|
||||
$response->redirect($this->urls->format('skins:index', ['error' => 'skin:format']));
|
||||
return;
|
||||
}
|
||||
|
||||
$response->redirect($this->urls->format('skins:index'));
|
||||
$hash = hash_file('sha256', $tmpPath);
|
||||
$localPath = $this->getLocalPath($hash);
|
||||
} else {
|
||||
$hash = $skinInfo->hash;
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
// apply new skin
|
||||
if($hasNewFile && !is_file($localPath))
|
||||
rename($tmpPath, $localPath);
|
||||
|
||||
$this->skinsCtx->skins->updateSkin($this->linkInfo, $hash, $model);
|
||||
} finally {
|
||||
// see about deleting the old one
|
||||
if($skinInfo !== null)
|
||||
$this->deleteLocalFileMaybe($skinInfo->hash);
|
||||
}
|
||||
} finally {
|
||||
// try to delete new one if something went awry
|
||||
if($hasNewFile)
|
||||
$this->deleteLocalFileMaybe($hash);
|
||||
}
|
||||
|
||||
$response->redirect($this->urls->format('skins:index'));
|
||||
} finally {
|
||||
if($tmpPath !== null && is_file($tmpPath))
|
||||
unlink($tmpPath);
|
||||
}
|
||||
}
|
||||
|
||||
#[HttpPost('/skins/delete-skin')]
|
||||
#[ExactRoute('POST', '/skins/delete-skin')]
|
||||
#[UrlFormat('skins:skin:delete', '/skins/delete-skin')]
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('mince:skins:get-link')]
|
||||
#[Before('input:urlencoded')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postDeleteSkin(HttpResponseBuilder $response) {
|
||||
$skinInfo = $this->skinsCtx->skins->getSkin($this->linkInfo);
|
||||
if($skinInfo !== null) {
|
||||
|
@ -200,60 +214,75 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
$response->redirect($this->urls->format('skins:index'));
|
||||
}
|
||||
|
||||
#[HttpPost('/skins/upload-cape')]
|
||||
#[ExactRoute('POST', '/skins/upload-cape')]
|
||||
#[UrlFormat('skins:cape:upload', '/skins/upload-cape')]
|
||||
public function postUploadCape(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
if(!$request->content->hasUploadedFile('texture'))
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('mince:skins:get-link')]
|
||||
#[Before('input:multipart')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postUploadCape(HttpResponseBuilder $response, MultipartFormContent $content) {
|
||||
$texture = $content->getParamData('texture');
|
||||
if(!($texture instanceof FileMultipartFormData))
|
||||
return 400;
|
||||
|
||||
$texture = $request->content->getUploadedFile('texture');
|
||||
if($texture->size > 256000) {
|
||||
if($texture->getSize() > 256000) {
|
||||
$response->redirect($this->urls->format('skins:index', ['error' => 'cape:size']));
|
||||
return;
|
||||
}
|
||||
|
||||
$tmpPath = $texture->localFileName;
|
||||
|
||||
$tmpPath = tempnam(sys_get_temp_dir(), 'mince-cape-');
|
||||
try {
|
||||
$imagick = new Imagick($tmpPath);
|
||||
$imagick->setImageFormat('png');
|
||||
$imagick->setBackgroundColor(new ImagickPixel('transparent'));
|
||||
$imagick->setImageExtent(64, 32);
|
||||
$imagick->stripImage();
|
||||
$imagick->writeImage();
|
||||
$imagick->destroy();
|
||||
} catch(ImagickException $ex) {
|
||||
$response->redirect($this->urls->format('skins:index', ['error' => 'cape:format']));
|
||||
return;
|
||||
}
|
||||
|
||||
$hash = hash_file('sha256', $tmpPath);
|
||||
$localPath = $this->getLocalPath($hash);
|
||||
|
||||
try {
|
||||
// get previous cape
|
||||
$capeInfo = $this->skinsCtx->capes->getCape($this->linkInfo);
|
||||
$texture->moveTo($tmpPath);
|
||||
|
||||
try {
|
||||
// apply new cape
|
||||
if(!is_file($localPath))
|
||||
$texture->moveTo($localPath);
|
||||
$this->skinsCtx->capes->updateCape($this->linkInfo, $hash);
|
||||
} finally {
|
||||
// see about deleting the old one
|
||||
if($capeInfo !== null)
|
||||
$this->deleteLocalFileMaybe($capeInfo->hash);
|
||||
$imagick = new Imagick($tmpPath);
|
||||
$imagick->setImageFormat('png');
|
||||
$imagick->setBackgroundColor(new ImagickPixel('transparent'));
|
||||
$imagick->setImageExtent(64, 32);
|
||||
$imagick->stripImage();
|
||||
$imagick->writeImage();
|
||||
$imagick->destroy();
|
||||
} catch(ImagickException $ex) {
|
||||
$response->redirect($this->urls->format('skins:index', ['error' => 'cape:format']));
|
||||
return;
|
||||
}
|
||||
} finally {
|
||||
// try to delete new one if something went awry
|
||||
$this->deleteLocalFileMaybe($hash);
|
||||
}
|
||||
|
||||
$response->redirect($this->urls->format('skins:index'));
|
||||
$hash = hash_file('sha256', $tmpPath);
|
||||
$localPath = $this->getLocalPath($hash);
|
||||
|
||||
try {
|
||||
// get previous cape
|
||||
$capeInfo = $this->skinsCtx->capes->getCape($this->linkInfo);
|
||||
|
||||
try {
|
||||
// apply new cape
|
||||
if(!is_file($localPath))
|
||||
rename($tmpPath, $localPath);
|
||||
|
||||
$this->skinsCtx->capes->updateCape($this->linkInfo, $hash);
|
||||
} finally {
|
||||
// see about deleting the old one
|
||||
if($capeInfo !== null)
|
||||
$this->deleteLocalFileMaybe($capeInfo->hash);
|
||||
}
|
||||
} finally {
|
||||
// try to delete new one if something went awry
|
||||
$this->deleteLocalFileMaybe($hash);
|
||||
}
|
||||
|
||||
$response->redirect($this->urls->format('skins:index'));
|
||||
} finally {
|
||||
if(is_file($tmpPath))
|
||||
unlink($tmpPath);
|
||||
}
|
||||
}
|
||||
|
||||
#[HttpPost('/skins/delete-cape')]
|
||||
#[ExactRoute('POST', '/skins/delete-cape')]
|
||||
#[UrlFormat('skins:cape:delete', '/skins/delete-cape')]
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('mince:skins:get-link')]
|
||||
#[Before('input:urlencoded')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postDeleteCape(HttpResponseBuilder $response) {
|
||||
$capeInfo = $this->skinsCtx->capes->getCape($this->linkInfo);
|
||||
if($capeInfo !== null) {
|
||||
|
@ -264,12 +293,16 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
$response->redirect($this->urls->format('skins:index'));
|
||||
}
|
||||
|
||||
#[HttpPost('/skins/import')]
|
||||
#[ExactRoute('POST', '/skins/import')]
|
||||
#[UrlFormat('skins:import', '/skins/import')]
|
||||
public function postImport(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
#[Before('mince:require-authed')]
|
||||
#[Before('mince:skins:get-link')]
|
||||
#[Before('input:urlencoded')]
|
||||
#[Before('mince:verify-csrf')]
|
||||
public function postImport(HttpResponseBuilder $response, HttpRequest $request, FormContent $content) {
|
||||
$userAgent = $request->getHeaderLine('User-Agent');
|
||||
|
||||
$userName = (string)$request->content->getParam('username');
|
||||
$userName = (string)$content->getParam('username');
|
||||
if($userName === '')
|
||||
$userName = $this->linkInfo->name;
|
||||
|
||||
|
@ -383,7 +416,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
return $profileInfo;
|
||||
}
|
||||
|
||||
#[HttpGet('/session/minecraft/profile/([a-fA-F0-9\-]+)')]
|
||||
#[PatternRoute('GET', '/session/minecraft/profile/([a-fA-F0-9\-]+)')]
|
||||
public function getSessionMinecraftProfile(HttpResponseBuilder $response, HttpRequest $request, string $id) {
|
||||
try {
|
||||
$uuid = Uuid::fromString($id);
|
||||
|
@ -409,16 +442,13 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
return $this->getProfileInfo($uuid, true);
|
||||
}
|
||||
|
||||
#[HttpPost('/session/minecraft/join')]
|
||||
public function postSessionMinecraftJoin(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
if(!($request->content instanceof JsonHttpContent))
|
||||
return 415;
|
||||
|
||||
#[ExactRoute('POST', '/session/minecraft/join')]
|
||||
public function postSessionMinecraftJoin() {
|
||||
// just accept this always idk if it matters
|
||||
return 204;
|
||||
}
|
||||
|
||||
#[HttpGet('/session/minecraft/hasJoined')]
|
||||
#[ExactRoute('GET', '/session/minecraft/hasJoined')]
|
||||
public function getSessionMinecraftHasJoined(HttpResponseBuilder $response, HttpRequest $request) {
|
||||
$userName = (string)$request->getParam('username');
|
||||
$serverId = (string)$request->getParam('serverId');
|
||||
|
@ -428,7 +458,7 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
return $this->getProfileInfo($uuid, false);
|
||||
}
|
||||
|
||||
#[HttpGet('/users/profiles/minecraft/([A-Za-z0-9_]+)')]
|
||||
#[PatternRoute('GET', '/users/profiles/minecraft/([A-Za-z0-9_]+)')]
|
||||
public function getUsersMinecraftProfile(HttpResponseBuilder $response, HttpRequest $request, string $name) {
|
||||
try {
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(name: $name);
|
||||
|
@ -447,8 +477,8 @@ class SkinsRoutes implements RouteHandler, UrlSource {
|
|||
}
|
||||
|
||||
// quirky path and two of them to achieve equal string length with http://s3.amazonaws.com/MinecraftSkins/ for flashii.net and edgii.net
|
||||
#[HttpGet('/s3MinecraftSkins/([A-Za-z0-9_]+).png')]
|
||||
#[HttpGet('/s3s3MinecraftSkins/([A-Za-z0-9_]+).png')]
|
||||
#[PatternRoute('GET', '/s3MinecraftSkins/([A-Za-z0-9_]+).png')]
|
||||
#[PatternRoute('GET', '/s3s3MinecraftSkins/([A-Za-z0-9_]+).png')]
|
||||
public function getS3MinecraftSkin(HttpResponseBuilder $response, HttpRequest $request, string $name) {
|
||||
try {
|
||||
$linkInfo = $this->clientsCtx->accountLinks->getLink(name: $name);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue