diff --git a/.env.ci b/.env.ci index e893452d4..1a9e848e3 100644 --- a/.env.ci +++ b/.env.ci @@ -8,7 +8,7 @@ APP_ENVIRONMENT_ONLY=true DB_CONNECTION=mysql DB_HOST=127.0.0.1 -DB_DATABASE=panel_test +DB_DATABASE=testing DB_USERNAME=root DB_PASSWORD= diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0e6f93b66..4da19b6ed 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -24,7 +24,7 @@ jobs: image: ${{ matrix.database }} env: MYSQL_ALLOW_EMPTY_PASSWORD: yes - MYSQL_DATABASE: panel_test + MYSQL_DATABASE: testing ports: - 3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 diff --git a/README.md b/README.md index 9ac8a0d15..79efc44e6 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ ![GitHub contributors](https://img.shields.io/github/contributors/pterodactyl/panel?style=for-the-badge) # Pterodactyl Panel + Pterodactyl® is a free, open-source game server management panel built with PHP, React, and Go. Designed with security in mind, Pterodactyl runs all game servers in isolated Docker containers while exposing a beautiful and intuitive UI to end users. @@ -15,30 +16,31 @@ Stop settling for less. Make game servers a first class citizen on your platform ![Image](https://cdn.pterodactyl.io/site-assets/pterodactyl_v1_demo.gif) ## Documentation + * [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html) * [Wings Documentation](https://pterodactyl.io/wings/1.0/installing.html) * [Community Guides](https://pterodactyl.io/community/about.html) * Or, get additional help [via Discord](https://discord.gg/pterodactyl) ## Sponsors + I would like to extend my sincere thanks to the following sponsors for helping fund Pterodactyl's developement. [Interested in becoming a sponsor?](https://github.com/sponsors/matthewpi) -| Company | About | -| ------- | ----- | -| [**WISP**](https://wisp.gg) | Extra features. | -| [**BisectHosting**](https://www.bisecthosting.com/) | BisectHosting provides Minecraft, Valheim and other server hosting services with the highest reliability and lightning fast support since 2012. | -| [**Fragnet**](https://fragnet.net) | Providing low latency, high-end game hosting solutions to gamers, game studios and eSports platforms. | -| [**Tempest**](https://tempest.net/) | Tempest Hosting is a subsidiary of Path Network, Inc. offering unmetered DDoS protected 10Gbps dedicated servers, starting at just $80/month. Full anycast, tons of filters. | -| [**Bloom.host**](https://bloom.host) | Bloom.host offers dedicated core VPS and Minecraft hosting with Ryzen 9 processors. With owned-hardware, we offer truly unbeatable prices on high-performance hosting. | -| [**MineStrator**](https://minestrator.com/) | Looking for the most highend French hosting company for your minecraft server? More than 24,000 members on our discord trust us. Give us a try! | -| [**Skynode**](https://www.skynode.pro/) | Skynode provides blazing fast game servers along with a top-notch user experience. Whatever our clients are looking for, we're able to provide it! | -| [**DeinServerHost**](https://deinserverhost.de/) | DeinServerHost offers Dedicated, vps and Gameservers for many popular Games like Minecraft and Rust in Germany since 2013. | -| [**Aussie Server Hosts**](https://aussieserverhosts.com/) | No frills Australian Owned and operated High Performance Server hosting for some of the most demanding games serving Australia and New Zealand. | -| [**VibeGAMES**](https://vibegames.net/) | VibeGAMES is a game server provider that specializes in DDOS protection for the games we offer. We have multiple locations in the US, Brazil, France, Germany, Singapore, Australia and South Africa.| -| [**Gamenodes**](https://gamenodes.nl) | Gamenodes love quality. For Minecraft, Discord Bots and other services, among others. With our own programmers, we provide just that little bit of extra service! | +| Company | About | +|-----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [**WISP**](https://wisp.gg) | Extra features. | +| [**Fragnet**](https://fragnet.net) | Providing low latency, high-end game hosting solutions to gamers, game studios and eSports platforms. | +| [**RocketNode**](https://rocketnode.com/) | Innovative game server hosting combined with a straightforward control panel, affordable prices, and Rocket-Fast support. | +| [**Aussie Server Hosts**](https://aussieserverhosts.com/) | No frills Australian Owned and operated High Performance Server hosting for some of the most demanding games serving Australia and New Zealand. | +| [**BisectHosting**](https://www.bisecthosting.com/) | BisectHosting provides Minecraft, Valheim and other server hosting services with the highest reliability and lightning fast support since 2012. | +| [**MineStrator**](https://minestrator.com/) | Looking for the most highend French hosting company for your minecraft server? More than 24,000 members on our discord trust us. Give us a try! | +| [**Skynode**](https://www.skynode.pro/) | Skynode provides blazing fast game servers along with a top-notch user experience. Whatever our clients are looking for, we're able to provide it! | +| [**VibeGAMES**](https://vibegames.net/) | VibeGAMES is a game server provider that specializes in DDOS protection for the games we offer. We have multiple locations in the US, Brazil, France, Germany, Singapore, Australia and South Africa. | +| [**Pterodactyl Market**](https://pterodactylmarket.com/) | Pterodactyl Market is a one-and-stop shop for Pterodactyl. In our market, you can find Add-ons, Themes, Eggs, and more for Pterodactyl. | ### Supported Games + Pterodactyl supports a wide variety of games by utilizing Docker containers to isolate each instance. This gives you the power to run game servers without bloating machines with a host of additional dependencies. @@ -67,6 +69,7 @@ and there are plenty more games available provided by the community. Some of the * [and many more...](https://github.com/parkervcp/eggs) ## License + Pterodactyl® Copyright © 2015 - 2022 Dane Everitt and contributors. Code released under the [MIT License](./LICENSE.md). diff --git a/app/Exceptions/ManifestDoesNotExistException.php b/app/Exceptions/ManifestDoesNotExistException.php new file mode 100644 index 000000000..2769cd03c --- /dev/null +++ b/app/Exceptions/ManifestDoesNotExistException.php @@ -0,0 +1,15 @@ + 'https://github.com/pterodactyl/panel/blob/develop/package.json', + ]; + } +} diff --git a/app/Http/Controllers/Api/Client/Servers/SettingsController.php b/app/Http/Controllers/Api/Client/Servers/SettingsController.php index 7f1946a21..d1377d67a 100644 --- a/app/Http/Controllers/Api/Client/Servers/SettingsController.php +++ b/app/Http/Controllers/Api/Client/Servers/SettingsController.php @@ -36,6 +36,7 @@ class SettingsController extends ClientApiController { $this->repository->update($server->id, [ 'name' => $request->input('name'), + 'description' => $request->input('description') ?? '', ]); if ($server->name !== $request->input('name')) { diff --git a/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php b/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php index 8cb5efa35..4a74f0a0e 100644 --- a/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php +++ b/app/Http/Requests/Api/Client/Servers/Settings/RenameServerRequest.php @@ -11,7 +11,7 @@ class RenameServerRequest extends ClientApiRequest implements ClientPermissionsR { /** * Returns the permissions string indicating which permission should be used to - * validate that the authenticated user has permission to perform this action aganist + * validate that the authenticated user has permission to perform this action against * the given resource (server). */ public function permission(): string @@ -26,6 +26,7 @@ class RenameServerRequest extends ClientApiRequest implements ClientPermissionsR { return [ 'name' => Server::getRules()['name'], + 'description' => 'string|nullable', ]; } } diff --git a/app/Models/Permission.php b/app/Models/Permission.php index 6d27a90d3..b2e00070e 100644 --- a/app/Models/Permission.php +++ b/app/Models/Permission.php @@ -195,7 +195,7 @@ class Permission extends Model 'settings' => [ 'description' => 'Permissions that control a user\'s access to the settings for this server.', 'keys' => [ - 'rename' => 'Allows a user to rename this server.', + 'rename' => 'Allows a user to rename this server and change the description of it.', 'reinstall' => 'Allows a user to trigger a reinstall of this server.', ], ], diff --git a/app/Services/Helpers/AssetHashService.php b/app/Services/Helpers/AssetHashService.php index 2e1c1aaa6..725a56669 100644 --- a/app/Services/Helpers/AssetHashService.php +++ b/app/Services/Helpers/AssetHashService.php @@ -5,6 +5,7 @@ namespace Pterodactyl\Services\Helpers; use Illuminate\Support\Arr; use Illuminate\Filesystem\FilesystemManager; use Illuminate\Contracts\Filesystem\Filesystem; +use Pterodactyl\Exceptions\ManifestDoesNotExistException; class AssetHashService { @@ -106,6 +107,11 @@ class AssetHashService ); } - return static::$manifest; + $manifest = static::$manifest; + if ($manifest === null) { + throw new ManifestDoesNotExistException(); + } + + return $manifest; } } diff --git a/bootstrap/cache/.gitignore b/bootstrap/cache/.gitignore old mode 100755 new mode 100644 diff --git a/bootstrap/tests.php b/bootstrap/tests.php index 35479a0cd..5b5449355 100644 --- a/bootstrap/tests.php +++ b/bootstrap/tests.php @@ -1,5 +1,6 @@ bootstrap(); $output = new ConsoleOutput(); $prefix = 'database.connections.' . config('database.default'); -if (config("$prefix.database") !== 'panel_test') { +if (!Str::contains(config("$prefix.database"), 'test')) { $output->writeln(PHP_EOL . 'Cannot run test process against non-testing database.'); $output->writeln(PHP_EOL . 'Environment is currently pointed at: "' . config("$prefix.database") . '".'); exit(1); diff --git a/composer.json b/composer.json index 2d4026781..160537b6b 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ } ], "require": { - "php": "^8.0.2 || ^8.1", + "php": "^8.0.2 || ^8.1 || ^8.2", "ext-json": "*", "ext-mbstring": "*", "ext-pdo": "*", @@ -58,6 +58,7 @@ "fakerphp/faker": "~1.20", "friendsofphp/php-cs-fixer": "~3.11", "itsgoingd/clockwork": "~5.1", + "laravel/sail": "~1.16", "mockery/mockery": "~1.5", "nunomaduro/collision": "~6.3", "php-mock/php-mock-phpunit": "~2.6", diff --git a/composer.lock b/composer.lock index a506d4edc..9f4b73f6f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "80a0f1016b1ba9e0b31d6cfe0f27f8c1", + "content-hash": "ae61e7d6e405e3a59c8a54f3eefa2c50", "packages": [ { "name": "aws/aws-crt-php", @@ -376,16 +376,16 @@ }, { "name": "doctrine/dbal", - "version": "3.4.5", + "version": "3.4.6", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "a5a58773109c0abb13e658c8ccd92aeec8d07f9e" + "reference": "3ce132f7c0b83d33b26ab6ed308e9e9260699bc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/a5a58773109c0abb13e658c8ccd92aeec8d07f9e", - "reference": "a5a58773109c0abb13e658c8ccd92aeec8d07f9e", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/3ce132f7c0b83d33b26ab6ed308e9e9260699bc4", + "reference": "3ce132f7c0b83d33b26ab6ed308e9e9260699bc4", "shasum": "" }, "require": { @@ -400,14 +400,14 @@ "require-dev": { "doctrine/coding-standard": "10.0.0", "jetbrains/phpstorm-stubs": "2022.2", - "phpstan/phpstan": "1.8.3", - "phpstan/phpstan-strict-rules": "^1.3", - "phpunit/phpunit": "9.5.24", + "phpstan/phpstan": "1.8.10", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "9.5.25", "psalm/plugin-phpunit": "0.17.0", "squizlabs/php_codesniffer": "3.7.1", "symfony/cache": "^5.4|^6.0", "symfony/console": "^4.4|^5.4|^6.0", - "vimeo/psalm": "4.27.0" + "vimeo/psalm": "4.29.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -467,7 +467,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.4.5" + "source": "https://github.com/doctrine/dbal/tree/3.4.6" }, "funding": [ { @@ -483,7 +483,7 @@ "type": "tidelift" } ], - "time": "2022-09-23T17:48:57+00:00" + "time": "2022-10-21T14:38:43+00:00" }, { "name": "doctrine/deprecations", @@ -622,23 +622,23 @@ }, { "name": "doctrine/inflector", - "version": "2.0.5", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392" + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", - "reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^10", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-strict-rules": "^1.3", @@ -693,7 +693,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.5" + "source": "https://github.com/doctrine/inflector/tree/2.0.6" }, "funding": [ { @@ -709,7 +709,7 @@ "type": "tidelift" } ], - "time": "2022-09-07T09:01:28+00:00" + "time": "2022-10-20T09:10:12+00:00" }, { "name": "doctrine/lexer", @@ -1263,16 +1263,16 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.4.1", + "version": "2.4.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" + "reference": "3148458748274be1546f8f2809a6c09fe66f44aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", - "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/3148458748274be1546f8f2809a6c09fe66f44aa", + "reference": "3148458748274be1546f8f2809a6c09fe66f44aa", "shasum": "" }, "require": { @@ -1362,7 +1362,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.1" + "source": "https://github.com/guzzle/psr7/tree/2.4.2" }, "funding": [ { @@ -1378,7 +1378,7 @@ "type": "tidelift" } ], - "time": "2022-08-28T14:45:39+00:00" + "time": "2022-10-25T13:49:28+00:00" }, { "name": "hashids/hashids", @@ -1513,16 +1513,16 @@ }, { "name": "laravel/framework", - "version": "v9.36.3", + "version": "v9.37.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "80ba0561b3682b96743e1c152fde0698bbdb2412" + "reference": "0c9675abf6d966e834b2ebeca3319f524e07a330" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/80ba0561b3682b96743e1c152fde0698bbdb2412", - "reference": "80ba0561b3682b96743e1c152fde0698bbdb2412", + "url": "https://api.github.com/repos/laravel/framework/zipball/0c9675abf6d966e834b2ebeca3319f524e07a330", + "reference": "0c9675abf6d966e834b2ebeca3319f524e07a330", "shasum": "" }, "require": { @@ -1534,7 +1534,7 @@ "fruitcake/php-cors": "^1.2", "laravel/serializable-closure": "^1.2.2", "league/commonmark": "^2.2", - "league/flysystem": "^3.0.16", + "league/flysystem": "^3.8.0", "monolog/monolog": "^2.0", "nesbot/carbon": "^2.62.1", "nunomaduro/termwind": "^1.13", @@ -1695,7 +1695,7 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2022-10-19T13:23:53+00:00" + "time": "2022-10-25T15:43:46+00:00" }, { "name": "laravel/helpers", @@ -2332,16 +2332,16 @@ }, { "name": "league/flysystem", - "version": "3.9.0", + "version": "3.10.2", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "60f3760352fe08e918bc3b1acae4e91af092ebe1" + "reference": "b9bd194b016114d6ff6765c09d40c7d427e4e3f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/60f3760352fe08e918bc3b1acae4e91af092ebe1", - "reference": "60f3760352fe08e918bc3b1acae4e91af092ebe1", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/b9bd194b016114d6ff6765c09d40c7d427e4e3f6", + "reference": "b9bd194b016114d6ff6765c09d40c7d427e4e3f6", "shasum": "" }, "require": { @@ -2357,7 +2357,7 @@ }, "require-dev": { "async-aws/s3": "^1.5", - "async-aws/simple-s3": "^1.0", + "async-aws/simple-s3": "^1.1", "aws/aws-sdk-php": "^3.198.1", "composer/semver": "^3.0", "ext-fileinfo": "*", @@ -2403,7 +2403,7 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/3.9.0" + "source": "https://github.com/thephpleague/flysystem/tree/3.10.2" }, "funding": [ { @@ -2419,7 +2419,7 @@ "type": "tidelift" } ], - "time": "2022-10-18T21:02:43+00:00" + "time": "2022-10-25T07:01:47+00:00" }, { "name": "league/flysystem-aws-s3-v3", @@ -3476,16 +3476,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.16", + "version": "3.0.17", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "7181378909ed8890be4db53d289faac5b77f8b05" + "reference": "dbc2307d5c69aeb22db136c52e91130d7f2ca761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7181378909ed8890be4db53d289faac5b77f8b05", - "reference": "7181378909ed8890be4db53d289faac5b77f8b05", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/dbc2307d5c69aeb22db136c52e91130d7f2ca761", + "reference": "dbc2307d5c69aeb22db136c52e91130d7f2ca761", "shasum": "" }, "require": { @@ -3566,7 +3566,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.16" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.17" }, "funding": [ { @@ -3582,7 +3582,7 @@ "type": "tidelift" } ], - "time": "2022-09-05T18:03:08+00:00" + "time": "2022-10-24T10:51:50+00:00" }, { "name": "pragmarx/google2fa", @@ -8725,6 +8725,66 @@ ], "time": "2022-10-19T21:46:50+00:00" }, + { + "name": "laravel/sail", + "version": "v1.16.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/sail.git", + "reference": "7d1ed5f856ec8b9708712e3fc0708fcabe114659" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sail/zipball/7d1ed5f856ec8b9708712e3fc0708fcabe114659", + "reference": "7d1ed5f856ec8b9708712e3fc0708fcabe114659", + "shasum": "" + }, + "require": { + "illuminate/console": "^8.0|^9.0", + "illuminate/contracts": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "bin": [ + "bin/sail" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Sail\\SailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Docker files for running a basic Laravel application.", + "keywords": [ + "docker", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/sail/issues", + "source": "https://github.com/laravel/sail" + }, + "time": "2022-09-28T13:13:22+00:00" + }, { "name": "mockery/mockery", "version": "1.5.1", @@ -10954,16 +11014,16 @@ }, { "name": "spatie/laravel-ignition", - "version": "1.5.2", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/spatie/laravel-ignition.git", - "reference": "f2336fc79d99aab5cf27fa4aebe5e9c9ecf3808a" + "reference": "c21309ebf6657e0c38083afac8af9baa12885676" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/f2336fc79d99aab5cf27fa4aebe5e9c9ecf3808a", - "reference": "f2336fc79d99aab5cf27fa4aebe5e9c9ecf3808a", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/c21309ebf6657e0c38083afac8af9baa12885676", + "reference": "c21309ebf6657e0c38083afac8af9baa12885676", "shasum": "" }, "require": { @@ -11040,7 +11100,7 @@ "type": "github" } ], - "time": "2022-10-14T12:24:21+00:00" + "time": "2022-10-25T08:38:04+00:00" }, { "name": "symfony/filesystem", @@ -11291,7 +11351,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": "^8.0.2 || ^8.1", + "php": "^8.0.2 || ^8.1 || ^8.2", "ext-json": "*", "ext-mbstring": "*", "ext-pdo": "*", diff --git a/config/mail.php b/config/mail.php index 0f9639291..95c6f303c 100644 --- a/config/mail.php +++ b/config/mail.php @@ -91,8 +91,8 @@ return [ */ 'from' => [ - 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), - 'name' => env('MAIL_FROM_NAME', 'Example'), + 'address' => env('MAIL_FROM_ADDRESS', env('MAIL_FROM', 'hello@example.com')), + 'name' => env('MAIL_FROM_NAME', 'Pterodactyl Panel'), ], /* diff --git a/config/queue.php b/config/queue.php index 35585df0e..39b93eefb 100644 --- a/config/queue.php +++ b/config/queue.php @@ -33,7 +33,7 @@ return [ 'database' => [ 'driver' => 'database', 'table' => 'jobs', - 'queue' => 'default', + 'queue' => env('QUEUE_STANDARD', 'default'), 'retry_after' => 90, 'after_commit' => false, ], @@ -43,7 +43,7 @@ return [ 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), - 'queue' => env('SQS_QUEUE', 'default'), + 'queue' => env('SQS_QUEUE', env('QUEUE_STANDARD', 'default')), 'suffix' => env('SQS_SUFFIX'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'after_commit' => false, @@ -52,7 +52,7 @@ return [ 'redis' => [ 'driver' => 'redis', 'connection' => 'default', - 'queue' => env('REDIS_QUEUE', 'default'), + 'queue' => env('REDIS_QUEUE', env('QUEUE_STANDARD', 'default')), 'retry_after' => 90, 'block_for' => null, 'after_commit' => false, diff --git a/database/Seeders/eggs/voice-servers/egg-mumble-server.json b/database/Seeders/eggs/voice-servers/egg-mumble-server.json index 27f60e717..feac4dc1a 100644 --- a/database/Seeders/eggs/voice-servers/egg-mumble-server.json +++ b/database/Seeders/eggs/voice-servers/egg-mumble-server.json @@ -1,28 +1,28 @@ { "_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO", "meta": { - "version": "PTDL_v1", + "version": "PTDL_v2", "update_url": null }, - "exported_at": "2021-06-15T16:54:54-04:00", + "exported_at": "2022-10-15T12:38:18+02:00", "name": "Mumble Server", "author": "support@pterodactyl.io", "description": "Mumble is an open source, low-latency, high quality voice chat software primarily intended for use while gaming.", "features": null, - "images": [ - "ghcr.io\/pterodactyl\/yolks:alpine" - ], + "docker_images": { + "Mumble": "ghcr.io\/parkervcp\/yolks:voice_mumble" + }, "file_denylist": [], - "startup": ".\/murmur.x86 -fg", + "startup": "mumble-server -fg -ini murmur.ini", "config": { - "files": "{\r\n \"murmur.ini\": {\r\n \"parser\": \"ini\",\r\n \"find\": {\r\n \"logfile\": \"murmur.log\",\r\n \"port\": \"{{server.build.default.port}}\",\r\n \"host\": \"0.0.0.0\",\r\n \"users\": \"{{server.build.env.MAX_USERS}}\"\r\n }\r\n }\r\n}", + "files": "{\r\n \"murmur.ini\": {\r\n \"parser\": \"ini\",\r\n \"find\": {\r\n \"database\": \"\/home\/container\/murmur.sqlite\",\r\n \"logfile\": \"\/home\/container\/murmur.log\",\r\n \"port\": \"{{server.build.default.port}}\",\r\n \"host\": \"0.0.0.0\",\r\n \"users\": \"{{server.build.env.MAX_USERS}}\"\r\n }\r\n }\r\n}", "startup": "{\r\n \"done\": \"Server listening on\"\r\n}", - "logs": "{\r\n \"custom\": true,\r\n \"location\": \"logs\/murmur.log\"\r\n}", + "logs": "{}", "stop": "^C" }, "scripts": { "installation": { - "script": "#!\/bin\/ash\r\n# Mumble Installation Script\r\n#\r\n# Server Files: \/mnt\/server\r\nGITHUB_PACKAGE=mumble-voip\/mumble\r\nMATCH=murmur-static\r\n\r\nif [ ! -d \/mnt\/server\/ ]; then\r\n mkdir \/mnt\/server\/\r\nfi\r\n\r\ncd \/mnt\/server\r\n\r\nif [ -z \"${GITHUB_USER}\" ] && [ -z \"${GITHUB_OAUTH_TOKEN}\" ] ; then\r\n echo -e \"using anon api call\"\r\nelse\r\n echo -e \"user and oauth token set\"\r\n alias curl='curl -u ${GITHUB_USER}:${GITHUB_OAUTH_TOKEN} '\r\nfi\r\n\r\n## get release info and download links\r\nLATEST_JSON=$(curl --silent \"https:\/\/api.github.com\/repos\/${GITHUB_PACKAGE}\/releases\/latest\")\r\nRELEASES=$(curl --silent \"https:\/\/api.github.com\/repos\/${GITHUB_PACKAGE}\/releases\")\r\n\r\nif [ -z \"${VERSION}\" ] || [ \"${VERSION}\" == \"latest\" ]; then\r\n DOWNLOAD_LINK=$(echo ${LATEST_JSON} | jq .assets | jq -r .[].browser_download_url | grep -m 1 -i ${MATCH})\r\nelse\r\n VERSION_CHECK=$(echo ${RELEASES} | jq -r --arg VERSION \"${VERSION}\" '.[] | select(.tag_name==$VERSION) | .tag_name')\r\n if [ \"${VERSION}\" == \"${VERSION_CHECK}\" ]; then\r\n DOWNLOAD_LINK=$(echo ${RELEASES} | jq -r --arg VERSION \"${VERSION}\" '.[] | select(.tag_name==$VERSION) | .assets[].browser_download_url' | grep -m 1 -i ${MATCH})\r\n else\r\n echo -e \"defaulting to latest release\"\r\n DOWNLOAD_LINK=$(echo ${LATEST_JSON} | jq .assets | jq -r .[].browser_download_url)\r\n fi\r\nfi\r\n\r\ncurl -L ${DOWNLOAD_LINK} | tar xjv --strip-components=1", + "script": "#!\/bin\/ash\r\n\r\nif [ ! -d \/mnt\/server\/ ]; then\r\n mkdir \/mnt\/server\/\r\nfi\r\n\r\ncd \/mnt\/server\r\n\r\nFILE=\/mnt\/server\/murmur.ini\r\nif [ -f \"$FILE\" ]; then\r\n echo \"Config file already exists.\"\r\nelse \r\n echo \"Downloading the config file.\"\r\n apk add --no-cache murmur\r\n cp \/etc\/murmur.ini \/mnt\/server\/murmur.ini\r\n apk del murmur\r\nfi\r\necho \"done\"", "container": "ghcr.io\/pterodactyl\/installers:alpine", "entrypoint": "ash" } @@ -35,16 +35,8 @@ "default_value": "100", "user_viewable": true, "user_editable": false, - "rules": "required|numeric|digits_between:1,5" - }, - { - "name": "Server Version", - "description": "Version of Mumble Server to download and use.", - "env_variable": "MUMBLE_VERSION", - "default_value": "latest", - "user_viewable": true, - "user_editable": true, - "rules": "required|string" + "rules": "required|numeric|digits_between:1,5", + "field_type": "text" } ] -} \ No newline at end of file +} diff --git a/phpunit.xml b/phpunit.xml index d02831cf4..efc42d687 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -22,7 +22,7 @@ - + diff --git a/resources/lang/en/activity.php b/resources/lang/en/activity.php index afa655806..501a1dcde 100644 --- a/resources/lang/en/activity.php +++ b/resources/lang/en/activity.php @@ -115,6 +115,7 @@ return [ ], 'settings' => [ 'rename' => 'Renamed the server from :old to :new', + 'description' => 'Changed the server description from :old to :new', ], 'startup' => [ 'edit' => 'Changed the :variable variable from ":old" to ":new"', diff --git a/resources/scripts/api/server/renameServer.ts b/resources/scripts/api/server/renameServer.ts index a4a95141e..4622f9d4d 100644 --- a/resources/scripts/api/server/renameServer.ts +++ b/resources/scripts/api/server/renameServer.ts @@ -1,8 +1,8 @@ import http from '@/api/http'; -export default (uuid: string, name: string): Promise => { +export default (uuid: string, name: string, description?: string): Promise => { return new Promise((resolve, reject) => { - http.post(`/api/client/servers/${uuid}/settings/rename`, { name }) + http.post(`/api/client/servers/${uuid}/settings/rename`, { name, description }) .then(() => resolve()) .catch(reject); }); diff --git a/resources/scripts/components/server/settings/RenameServerBox.tsx b/resources/scripts/components/server/settings/RenameServerBox.tsx index 98be2ef9f..9cb290a1a 100644 --- a/resources/scripts/components/server/settings/RenameServerBox.tsx +++ b/resources/scripts/components/server/settings/RenameServerBox.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ServerContext } from '@/state/server'; import TitledGreyBox from '@/components/elements/TitledGreyBox'; -import { Form, Formik, FormikHelpers, useFormikContext } from 'formik'; +import { Field as FormikField, Form, Formik, FormikHelpers, useFormikContext } from 'formik'; import { Actions, useStoreActions } from 'easy-peasy'; import renameServer from '@/api/server/renameServer'; import Field from '@/components/elements/Field'; @@ -11,19 +11,29 @@ import { ApplicationStore } from '@/state'; import { httpErrorToHuman } from '@/api/http'; import { Button } from '@/components/elements/button/index'; import tw from 'twin.macro'; +import Label from '@/components/elements/Label'; +import FormikFieldWrapper from '@/components/elements/FormikFieldWrapper'; +import { Textarea } from '@/components/elements/Input'; interface Values { name: string; + description: string; } const RenameServerBox = () => { const { isSubmitting } = useFormikContext(); return ( - +
+
+ + + + +
@@ -37,10 +47,10 @@ export default () => { const setServer = ServerContext.useStoreActions((actions) => actions.server.setServer); const { addError, clearFlashes } = useStoreActions((actions: Actions) => actions.flashes); - const submit = ({ name }: Values, { setSubmitting }: FormikHelpers) => { + const submit = ({ name, description }: Values, { setSubmitting }: FormikHelpers) => { clearFlashes('settings'); - renameServer(server.uuid, name) - .then(() => setServer({ ...server, name })) + renameServer(server.uuid, name, description) + .then(() => setServer({ ...server, name, description })) .catch((error) => { console.error(error); addError({ key: 'settings', message: httpErrorToHuman(error) }); @@ -53,9 +63,11 @@ export default () => { onSubmit={submit} initialValues={{ name: server.name, + description: server.description, }} validationSchema={object().shape({ name: string().required().min(1), + description: string().nullable(), })} > diff --git a/tests/Integration/Api/Client/Server/SettingsControllerTest.php b/tests/Integration/Api/Client/Server/SettingsControllerTest.php index c92754cfa..882314bea 100644 --- a/tests/Integration/Api/Client/Server/SettingsControllerTest.php +++ b/tests/Integration/Api/Client/Server/SettingsControllerTest.php @@ -21,9 +21,11 @@ class SettingsControllerTest extends ClientApiIntegrationTestCase /** @var \Pterodactyl\Models\Server $server */ [$user, $server] = $this->generateTestAccount($permissions); $originalName = $server->name; + $originalDescription = $server->description; $response = $this->actingAs($user)->postJson("/api/client/servers/$server->uuid/settings/rename", [ 'name' => '', + 'description' => '', ]); $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY); @@ -31,15 +33,18 @@ class SettingsControllerTest extends ClientApiIntegrationTestCase $server = $server->refresh(); $this->assertSame($originalName, $server->name); + $this->assertSame($originalDescription, $server->description); $this->actingAs($user) ->postJson("/api/client/servers/$server->uuid/settings/rename", [ 'name' => 'Test Server Name', + 'description' => 'This is a test server.', ]) ->assertStatus(Response::HTTP_NO_CONTENT); $server = $server->refresh(); $this->assertSame('Test Server Name', $server->name); + $this->assertSame('This is a test server.', $server->description); } /**