Merge branch 'develop' into attributes

This commit is contained in:
Matthew Penner 2022-10-31 13:47:54 -06:00 committed by GitHub
commit 294c348976
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 225 additions and 102 deletions

View file

@ -8,7 +8,7 @@ APP_ENVIRONMENT_ONLY=true
DB_CONNECTION=mysql DB_CONNECTION=mysql
DB_HOST=127.0.0.1 DB_HOST=127.0.0.1
DB_DATABASE=panel_test DB_DATABASE=testing
DB_USERNAME=root DB_USERNAME=root
DB_PASSWORD= DB_PASSWORD=

View file

@ -24,7 +24,7 @@ jobs:
image: ${{ matrix.database }} image: ${{ matrix.database }}
env: env:
MYSQL_ALLOW_EMPTY_PASSWORD: yes MYSQL_ALLOW_EMPTY_PASSWORD: yes
MYSQL_DATABASE: panel_test MYSQL_DATABASE: testing
ports: ports:
- 3306 - 3306
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

View file

@ -6,6 +6,7 @@
![GitHub contributors](https://img.shields.io/github/contributors/pterodactyl/panel?style=for-the-badge) ![GitHub contributors](https://img.shields.io/github/contributors/pterodactyl/panel?style=for-the-badge)
# Pterodactyl Panel # Pterodactyl Panel
Pterodactyl® is a free, open-source game server management panel built with PHP, React, and Go. Designed with security 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 in mind, Pterodactyl runs all game servers in isolated Docker containers while exposing a beautiful and intuitive
UI to end users. 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) ![Image](https://cdn.pterodactyl.io/site-assets/pterodactyl_v1_demo.gif)
## Documentation ## Documentation
* [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html) * [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html)
* [Wings Documentation](https://pterodactyl.io/wings/1.0/installing.html) * [Wings Documentation](https://pterodactyl.io/wings/1.0/installing.html)
* [Community Guides](https://pterodactyl.io/community/about.html) * [Community Guides](https://pterodactyl.io/community/about.html)
* Or, get additional help [via Discord](https://discord.gg/pterodactyl) * Or, get additional help [via Discord](https://discord.gg/pterodactyl)
## Sponsors ## Sponsors
I would like to extend my sincere thanks to the following sponsors for helping fund Pterodactyl's developement. 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) [Interested in becoming a sponsor?](https://github.com/sponsors/matthewpi)
| Company | About | | Company | About |
| ------- | ----- | |-----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [**WISP**](https://wisp.gg) | Extra features. | | [**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. | | [**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. | | [**RocketNode**](https://rocketnode.com/) | Innovative game server hosting combined with a straightforward control panel, affordable prices, and Rocket-Fast support. |
| [**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. | | [**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! | | [**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! | | [**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. | | [**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. |
| [**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. | | [**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. |
| [**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! |
### Supported Games ### Supported Games
Pterodactyl supports a wide variety of games by utilizing Docker containers to isolate each instance. This gives 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. 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) * [and many more...](https://github.com/parkervcp/eggs)
## License ## License
Pterodactyl® Copyright © 2015 - 2022 Dane Everitt and contributors. Pterodactyl® Copyright © 2015 - 2022 Dane Everitt and contributors.
Code released under the [MIT License](./LICENSE.md). Code released under the [MIT License](./LICENSE.md).

View file

@ -0,0 +1,15 @@
<?php
namespace Pterodactyl\Exceptions;
use Exception;
use Spatie\Ignition\Contracts\Solution;
use Spatie\Ignition\Contracts\ProvidesSolution;
class ManifestDoesNotExistException extends Exception implements ProvidesSolution
{
public function getSolution(): Solution
{
return new Solutions\ManifestDoesNotExistSolution();
}
}

View file

@ -0,0 +1,25 @@
<?php
namespace Pterodactyl\Exceptions\Solutions;
use Spatie\Ignition\Contracts\Solution;
class ManifestDoesNotExistSolution implements Solution
{
public function getSolutionTitle(): string
{
return "The manifest.json file hasn't been generated yet";
}
public function getSolutionDescription(): string
{
return 'Run yarn run build:production to build the frontend first.';
}
public function getDocumentationLinks(): array
{
return [
'Docs' => 'https://github.com/pterodactyl/panel/blob/develop/package.json',
];
}
}

View file

@ -36,6 +36,7 @@ class SettingsController extends ClientApiController
{ {
$this->repository->update($server->id, [ $this->repository->update($server->id, [
'name' => $request->input('name'), 'name' => $request->input('name'),
'description' => $request->input('description') ?? '',
]); ]);
if ($server->name !== $request->input('name')) { if ($server->name !== $request->input('name')) {

View file

@ -11,7 +11,7 @@ class RenameServerRequest extends ClientApiRequest implements ClientPermissionsR
{ {
/** /**
* Returns the permissions string indicating which permission should be used to * 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). * the given resource (server).
*/ */
public function permission(): string public function permission(): string
@ -26,6 +26,7 @@ class RenameServerRequest extends ClientApiRequest implements ClientPermissionsR
{ {
return [ return [
'name' => Server::getRules()['name'], 'name' => Server::getRules()['name'],
'description' => 'string|nullable',
]; ];
} }
} }

View file

@ -195,7 +195,7 @@ class Permission extends Model
'settings' => [ 'settings' => [
'description' => 'Permissions that control a user\'s access to the settings for this server.', 'description' => 'Permissions that control a user\'s access to the settings for this server.',
'keys' => [ '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.', 'reinstall' => 'Allows a user to trigger a reinstall of this server.',
], ],
], ],

View file

@ -5,6 +5,7 @@ namespace Pterodactyl\Services\Helpers;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Filesystem\FilesystemManager; use Illuminate\Filesystem\FilesystemManager;
use Illuminate\Contracts\Filesystem\Filesystem; use Illuminate\Contracts\Filesystem\Filesystem;
use Pterodactyl\Exceptions\ManifestDoesNotExistException;
class AssetHashService class AssetHashService
{ {
@ -106,6 +107,11 @@ class AssetHashService
); );
} }
return static::$manifest; $manifest = static::$manifest;
if ($manifest === null) {
throw new ManifestDoesNotExistException();
}
return $manifest;
} }
} }

0
bootstrap/cache/.gitignore vendored Executable file → Normal file
View file

View file

@ -1,5 +1,6 @@
<?php <?php
use Illuminate\Support\Str;
use NunoMaduro\Collision\Provider; use NunoMaduro\Collision\Provider;
use Illuminate\Contracts\Console\Kernel; use Illuminate\Contracts\Console\Kernel;
use Symfony\Component\Console\Output\ConsoleOutput; use Symfony\Component\Console\Output\ConsoleOutput;
@ -23,7 +24,7 @@ $kernel->bootstrap();
$output = new ConsoleOutput(); $output = new ConsoleOutput();
$prefix = 'database.connections.' . config('database.default'); $prefix = 'database.connections.' . config('database.default');
if (config("$prefix.database") !== 'panel_test') { if (!Str::contains(config("$prefix.database"), 'test')) {
$output->writeln(PHP_EOL . '<error>Cannot run test process against non-testing database.</error>'); $output->writeln(PHP_EOL . '<error>Cannot run test process against non-testing database.</error>');
$output->writeln(PHP_EOL . '<error>Environment is currently pointed at: "' . config("$prefix.database") . '".</error>'); $output->writeln(PHP_EOL . '<error>Environment is currently pointed at: "' . config("$prefix.database") . '".</error>');
exit(1); exit(1);

View file

@ -17,7 +17,7 @@
} }
], ],
"require": { "require": {
"php": "^8.0.2 || ^8.1", "php": "^8.0.2 || ^8.1 || ^8.2",
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-pdo": "*", "ext-pdo": "*",
@ -58,6 +58,7 @@
"fakerphp/faker": "~1.20", "fakerphp/faker": "~1.20",
"friendsofphp/php-cs-fixer": "~3.11", "friendsofphp/php-cs-fixer": "~3.11",
"itsgoingd/clockwork": "~5.1", "itsgoingd/clockwork": "~5.1",
"laravel/sail": "~1.16",
"mockery/mockery": "~1.5", "mockery/mockery": "~1.5",
"nunomaduro/collision": "~6.3", "nunomaduro/collision": "~6.3",
"php-mock/php-mock-phpunit": "~2.6", "php-mock/php-mock-phpunit": "~2.6",

158
composer.lock generated
View file

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "80a0f1016b1ba9e0b31d6cfe0f27f8c1", "content-hash": "ae61e7d6e405e3a59c8a54f3eefa2c50",
"packages": [ "packages": [
{ {
"name": "aws/aws-crt-php", "name": "aws/aws-crt-php",
@ -376,16 +376,16 @@
}, },
{ {
"name": "doctrine/dbal", "name": "doctrine/dbal",
"version": "3.4.5", "version": "3.4.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/dbal.git", "url": "https://github.com/doctrine/dbal.git",
"reference": "a5a58773109c0abb13e658c8ccd92aeec8d07f9e" "reference": "3ce132f7c0b83d33b26ab6ed308e9e9260699bc4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/dbal/zipball/a5a58773109c0abb13e658c8ccd92aeec8d07f9e", "url": "https://api.github.com/repos/doctrine/dbal/zipball/3ce132f7c0b83d33b26ab6ed308e9e9260699bc4",
"reference": "a5a58773109c0abb13e658c8ccd92aeec8d07f9e", "reference": "3ce132f7c0b83d33b26ab6ed308e9e9260699bc4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -400,14 +400,14 @@
"require-dev": { "require-dev": {
"doctrine/coding-standard": "10.0.0", "doctrine/coding-standard": "10.0.0",
"jetbrains/phpstorm-stubs": "2022.2", "jetbrains/phpstorm-stubs": "2022.2",
"phpstan/phpstan": "1.8.3", "phpstan/phpstan": "1.8.10",
"phpstan/phpstan-strict-rules": "^1.3", "phpstan/phpstan-strict-rules": "^1.4",
"phpunit/phpunit": "9.5.24", "phpunit/phpunit": "9.5.25",
"psalm/plugin-phpunit": "0.17.0", "psalm/plugin-phpunit": "0.17.0",
"squizlabs/php_codesniffer": "3.7.1", "squizlabs/php_codesniffer": "3.7.1",
"symfony/cache": "^5.4|^6.0", "symfony/cache": "^5.4|^6.0",
"symfony/console": "^4.4|^5.4|^6.0", "symfony/console": "^4.4|^5.4|^6.0",
"vimeo/psalm": "4.27.0" "vimeo/psalm": "4.29.0"
}, },
"suggest": { "suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files." "symfony/console": "For helpful console commands such as SQL execution and import of files."
@ -467,7 +467,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/dbal/issues", "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": [ "funding": [
{ {
@ -483,7 +483,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-09-23T17:48:57+00:00" "time": "2022-10-21T14:38:43+00:00"
}, },
{ {
"name": "doctrine/deprecations", "name": "doctrine/deprecations",
@ -622,23 +622,23 @@
}, },
{ {
"name": "doctrine/inflector", "name": "doctrine/inflector",
"version": "2.0.5", "version": "2.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/inflector.git", "url": "https://github.com/doctrine/inflector.git",
"reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392" "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/inflector/zipball/ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
"reference": "ade2b3bbfb776f27f0558e26eed43b5d9fe1b392", "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^7.2 || ^8.0" "php": "^7.2 || ^8.0"
}, },
"require-dev": { "require-dev": {
"doctrine/coding-standard": "^9", "doctrine/coding-standard": "^10",
"phpstan/phpstan": "^1.8", "phpstan/phpstan": "^1.8",
"phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-phpunit": "^1.1",
"phpstan/phpstan-strict-rules": "^1.3", "phpstan/phpstan-strict-rules": "^1.3",
@ -693,7 +693,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/inflector/issues", "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": [ "funding": [
{ {
@ -709,7 +709,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-09-07T09:01:28+00:00" "time": "2022-10-20T09:10:12+00:00"
}, },
{ {
"name": "doctrine/lexer", "name": "doctrine/lexer",
@ -1263,16 +1263,16 @@
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
"version": "2.4.1", "version": "2.4.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/psr7.git", "url": "https://github.com/guzzle/psr7.git",
"reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" "reference": "3148458748274be1546f8f2809a6c09fe66f44aa"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", "url": "https://api.github.com/repos/guzzle/psr7/zipball/3148458748274be1546f8f2809a6c09fe66f44aa",
"reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", "reference": "3148458748274be1546f8f2809a6c09fe66f44aa",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1362,7 +1362,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/guzzle/psr7/issues", "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": [ "funding": [
{ {
@ -1378,7 +1378,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-08-28T14:45:39+00:00" "time": "2022-10-25T13:49:28+00:00"
}, },
{ {
"name": "hashids/hashids", "name": "hashids/hashids",
@ -1513,16 +1513,16 @@
}, },
{ {
"name": "laravel/framework", "name": "laravel/framework",
"version": "v9.36.3", "version": "v9.37.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/framework.git", "url": "https://github.com/laravel/framework.git",
"reference": "80ba0561b3682b96743e1c152fde0698bbdb2412" "reference": "0c9675abf6d966e834b2ebeca3319f524e07a330"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/80ba0561b3682b96743e1c152fde0698bbdb2412", "url": "https://api.github.com/repos/laravel/framework/zipball/0c9675abf6d966e834b2ebeca3319f524e07a330",
"reference": "80ba0561b3682b96743e1c152fde0698bbdb2412", "reference": "0c9675abf6d966e834b2ebeca3319f524e07a330",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1534,7 +1534,7 @@
"fruitcake/php-cors": "^1.2", "fruitcake/php-cors": "^1.2",
"laravel/serializable-closure": "^1.2.2", "laravel/serializable-closure": "^1.2.2",
"league/commonmark": "^2.2", "league/commonmark": "^2.2",
"league/flysystem": "^3.0.16", "league/flysystem": "^3.8.0",
"monolog/monolog": "^2.0", "monolog/monolog": "^2.0",
"nesbot/carbon": "^2.62.1", "nesbot/carbon": "^2.62.1",
"nunomaduro/termwind": "^1.13", "nunomaduro/termwind": "^1.13",
@ -1695,7 +1695,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "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", "name": "laravel/helpers",
@ -2332,16 +2332,16 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "3.9.0", "version": "3.10.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "60f3760352fe08e918bc3b1acae4e91af092ebe1" "reference": "b9bd194b016114d6ff6765c09d40c7d427e4e3f6"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/60f3760352fe08e918bc3b1acae4e91af092ebe1", "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/b9bd194b016114d6ff6765c09d40c7d427e4e3f6",
"reference": "60f3760352fe08e918bc3b1acae4e91af092ebe1", "reference": "b9bd194b016114d6ff6765c09d40c7d427e4e3f6",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2357,7 +2357,7 @@
}, },
"require-dev": { "require-dev": {
"async-aws/s3": "^1.5", "async-aws/s3": "^1.5",
"async-aws/simple-s3": "^1.0", "async-aws/simple-s3": "^1.1",
"aws/aws-sdk-php": "^3.198.1", "aws/aws-sdk-php": "^3.198.1",
"composer/semver": "^3.0", "composer/semver": "^3.0",
"ext-fileinfo": "*", "ext-fileinfo": "*",
@ -2403,7 +2403,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/thephpleague/flysystem/issues", "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": [ "funding": [
{ {
@ -2419,7 +2419,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-10-18T21:02:43+00:00" "time": "2022-10-25T07:01:47+00:00"
}, },
{ {
"name": "league/flysystem-aws-s3-v3", "name": "league/flysystem-aws-s3-v3",
@ -3476,16 +3476,16 @@
}, },
{ {
"name": "phpseclib/phpseclib", "name": "phpseclib/phpseclib",
"version": "3.0.16", "version": "3.0.17",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpseclib/phpseclib.git", "url": "https://github.com/phpseclib/phpseclib.git",
"reference": "7181378909ed8890be4db53d289faac5b77f8b05" "reference": "dbc2307d5c69aeb22db136c52e91130d7f2ca761"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/7181378909ed8890be4db53d289faac5b77f8b05", "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/dbc2307d5c69aeb22db136c52e91130d7f2ca761",
"reference": "7181378909ed8890be4db53d289faac5b77f8b05", "reference": "dbc2307d5c69aeb22db136c52e91130d7f2ca761",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3566,7 +3566,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/phpseclib/phpseclib/issues", "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": [ "funding": [
{ {
@ -3582,7 +3582,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-09-05T18:03:08+00:00" "time": "2022-10-24T10:51:50+00:00"
}, },
{ {
"name": "pragmarx/google2fa", "name": "pragmarx/google2fa",
@ -8725,6 +8725,66 @@
], ],
"time": "2022-10-19T21:46:50+00:00" "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", "name": "mockery/mockery",
"version": "1.5.1", "version": "1.5.1",
@ -10954,16 +11014,16 @@
}, },
{ {
"name": "spatie/laravel-ignition", "name": "spatie/laravel-ignition",
"version": "1.5.2", "version": "1.6.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/spatie/laravel-ignition.git", "url": "https://github.com/spatie/laravel-ignition.git",
"reference": "f2336fc79d99aab5cf27fa4aebe5e9c9ecf3808a" "reference": "c21309ebf6657e0c38083afac8af9baa12885676"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/f2336fc79d99aab5cf27fa4aebe5e9c9ecf3808a", "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/c21309ebf6657e0c38083afac8af9baa12885676",
"reference": "f2336fc79d99aab5cf27fa4aebe5e9c9ecf3808a", "reference": "c21309ebf6657e0c38083afac8af9baa12885676",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -11040,7 +11100,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2022-10-14T12:24:21+00:00" "time": "2022-10-25T08:38:04+00:00"
}, },
{ {
"name": "symfony/filesystem", "name": "symfony/filesystem",
@ -11291,7 +11351,7 @@
"prefer-stable": true, "prefer-stable": true,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": "^8.0.2 || ^8.1", "php": "^8.0.2 || ^8.1 || ^8.2",
"ext-json": "*", "ext-json": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"ext-pdo": "*", "ext-pdo": "*",

View file

@ -91,8 +91,8 @@ return [
*/ */
'from' => [ 'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'address' => env('MAIL_FROM_ADDRESS', env('MAIL_FROM', 'hello@example.com')),
'name' => env('MAIL_FROM_NAME', 'Example'), 'name' => env('MAIL_FROM_NAME', 'Pterodactyl Panel'),
], ],
/* /*

View file

@ -33,7 +33,7 @@ return [
'database' => [ 'database' => [
'driver' => 'database', 'driver' => 'database',
'table' => 'jobs', 'table' => 'jobs',
'queue' => 'default', 'queue' => env('QUEUE_STANDARD', 'default'),
'retry_after' => 90, 'retry_after' => 90,
'after_commit' => false, 'after_commit' => false,
], ],
@ -43,7 +43,7 @@ return [
'key' => env('AWS_ACCESS_KEY_ID'), 'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'), 'secret' => env('AWS_SECRET_ACCESS_KEY'),
'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), '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'), 'suffix' => env('SQS_SUFFIX'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'after_commit' => false, 'after_commit' => false,
@ -52,7 +52,7 @@ return [
'redis' => [ 'redis' => [
'driver' => 'redis', 'driver' => 'redis',
'connection' => 'default', 'connection' => 'default',
'queue' => env('REDIS_QUEUE', 'default'), 'queue' => env('REDIS_QUEUE', env('QUEUE_STANDARD', 'default')),
'retry_after' => 90, 'retry_after' => 90,
'block_for' => null, 'block_for' => null,
'after_commit' => false, 'after_commit' => false,

View file

@ -1,28 +1,28 @@
{ {
"_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO", "_comment": "DO NOT EDIT: FILE GENERATED AUTOMATICALLY BY PTERODACTYL PANEL - PTERODACTYL.IO",
"meta": { "meta": {
"version": "PTDL_v1", "version": "PTDL_v2",
"update_url": null "update_url": null
}, },
"exported_at": "2021-06-15T16:54:54-04:00", "exported_at": "2022-10-15T12:38:18+02:00",
"name": "Mumble Server", "name": "Mumble Server",
"author": "support@pterodactyl.io", "author": "support@pterodactyl.io",
"description": "Mumble is an open source, low-latency, high quality voice chat software primarily intended for use while gaming.", "description": "Mumble is an open source, low-latency, high quality voice chat software primarily intended for use while gaming.",
"features": null, "features": null,
"images": [ "docker_images": {
"ghcr.io\/pterodactyl\/yolks:alpine" "Mumble": "ghcr.io\/parkervcp\/yolks:voice_mumble"
], },
"file_denylist": [], "file_denylist": [],
"startup": ".\/murmur.x86 -fg", "startup": "mumble-server -fg -ini murmur.ini",
"config": { "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}", "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" "stop": "^C"
}, },
"scripts": { "scripts": {
"installation": { "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", "container": "ghcr.io\/pterodactyl\/installers:alpine",
"entrypoint": "ash" "entrypoint": "ash"
} }
@ -35,16 +35,8 @@
"default_value": "100", "default_value": "100",
"user_viewable": true, "user_viewable": true,
"user_editable": false, "user_editable": false,
"rules": "required|numeric|digits_between:1,5" "rules": "required|numeric|digits_between:1,5",
}, "field_type": "text"
{
"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"
} }
] ]
} }

View file

@ -22,7 +22,7 @@
<php> <php>
<env name="APP_ENV" value="testing" /> <env name="APP_ENV" value="testing" />
<env name="BCRYPT_ROUNDS" value="4" /> <env name="BCRYPT_ROUNDS" value="4" />
<env name="DB_DATABASE" value="panel_test" /> <env name="DB_DATABASE" value="testing" />
<env name="CACHE_DRIVER" value="array" /> <env name="CACHE_DRIVER" value="array" />
<env name="SESSION_DRIVER" value="array" /> <env name="SESSION_DRIVER" value="array" />
<env name="QUEUE_CONNECTION" value="sync" /> <env name="QUEUE_CONNECTION" value="sync" />

View file

@ -115,6 +115,7 @@ return [
], ],
'settings' => [ 'settings' => [
'rename' => 'Renamed the server from :old to :new', 'rename' => 'Renamed the server from :old to :new',
'description' => 'Changed the server description from :old to :new',
], ],
'startup' => [ 'startup' => [
'edit' => 'Changed the :variable variable from ":old" to ":new"', 'edit' => 'Changed the :variable variable from ":old" to ":new"',

View file

@ -1,8 +1,8 @@
import http from '@/api/http'; import http from '@/api/http';
export default (uuid: string, name: string): Promise<void> => { export default (uuid: string, name: string, description?: string): Promise<void> => {
return new Promise((resolve, reject) => { 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()) .then(() => resolve())
.catch(reject); .catch(reject);
}); });

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { ServerContext } from '@/state/server'; import { ServerContext } from '@/state/server';
import TitledGreyBox from '@/components/elements/TitledGreyBox'; 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 { Actions, useStoreActions } from 'easy-peasy';
import renameServer from '@/api/server/renameServer'; import renameServer from '@/api/server/renameServer';
import Field from '@/components/elements/Field'; import Field from '@/components/elements/Field';
@ -11,19 +11,29 @@ import { ApplicationStore } from '@/state';
import { httpErrorToHuman } from '@/api/http'; import { httpErrorToHuman } from '@/api/http';
import { Button } from '@/components/elements/button/index'; import { Button } from '@/components/elements/button/index';
import tw from 'twin.macro'; 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 { interface Values {
name: string; name: string;
description: string;
} }
const RenameServerBox = () => { const RenameServerBox = () => {
const { isSubmitting } = useFormikContext<Values>(); const { isSubmitting } = useFormikContext<Values>();
return ( return (
<TitledGreyBox title={'Change Server Name'} css={tw`relative`}> <TitledGreyBox title={'Change Server Details'} css={tw`relative`}>
<SpinnerOverlay visible={isSubmitting} /> <SpinnerOverlay visible={isSubmitting} />
<Form css={tw`mb-0`}> <Form css={tw`mb-0`}>
<Field id={'name'} name={'name'} label={'Server Name'} type={'text'} /> <Field id={'name'} name={'name'} label={'Server Name'} type={'text'} />
<div css={tw`mt-6`}>
<Label>Server Description</Label>
<FormikFieldWrapper name={'description'}>
<FormikField as={Textarea} name={'description'} rows={3} />
</FormikFieldWrapper>
</div>
<div css={tw`mt-6 text-right`}> <div css={tw`mt-6 text-right`}>
<Button type={'submit'}>Save</Button> <Button type={'submit'}>Save</Button>
</div> </div>
@ -37,10 +47,10 @@ export default () => {
const setServer = ServerContext.useStoreActions((actions) => actions.server.setServer); const setServer = ServerContext.useStoreActions((actions) => actions.server.setServer);
const { addError, clearFlashes } = useStoreActions((actions: Actions<ApplicationStore>) => actions.flashes); const { addError, clearFlashes } = useStoreActions((actions: Actions<ApplicationStore>) => actions.flashes);
const submit = ({ name }: Values, { setSubmitting }: FormikHelpers<Values>) => { const submit = ({ name, description }: Values, { setSubmitting }: FormikHelpers<Values>) => {
clearFlashes('settings'); clearFlashes('settings');
renameServer(server.uuid, name) renameServer(server.uuid, name, description)
.then(() => setServer({ ...server, name })) .then(() => setServer({ ...server, name, description }))
.catch((error) => { .catch((error) => {
console.error(error); console.error(error);
addError({ key: 'settings', message: httpErrorToHuman(error) }); addError({ key: 'settings', message: httpErrorToHuman(error) });
@ -53,9 +63,11 @@ export default () => {
onSubmit={submit} onSubmit={submit}
initialValues={{ initialValues={{
name: server.name, name: server.name,
description: server.description,
}} }}
validationSchema={object().shape({ validationSchema={object().shape({
name: string().required().min(1), name: string().required().min(1),
description: string().nullable(),
})} })}
> >
<RenameServerBox /> <RenameServerBox />

View file

@ -21,9 +21,11 @@ class SettingsControllerTest extends ClientApiIntegrationTestCase
/** @var \Pterodactyl\Models\Server $server */ /** @var \Pterodactyl\Models\Server $server */
[$user, $server] = $this->generateTestAccount($permissions); [$user, $server] = $this->generateTestAccount($permissions);
$originalName = $server->name; $originalName = $server->name;
$originalDescription = $server->description;
$response = $this->actingAs($user)->postJson("/api/client/servers/$server->uuid/settings/rename", [ $response = $this->actingAs($user)->postJson("/api/client/servers/$server->uuid/settings/rename", [
'name' => '', 'name' => '',
'description' => '',
]); ]);
$response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY); $response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
@ -31,15 +33,18 @@ class SettingsControllerTest extends ClientApiIntegrationTestCase
$server = $server->refresh(); $server = $server->refresh();
$this->assertSame($originalName, $server->name); $this->assertSame($originalName, $server->name);
$this->assertSame($originalDescription, $server->description);
$this->actingAs($user) $this->actingAs($user)
->postJson("/api/client/servers/$server->uuid/settings/rename", [ ->postJson("/api/client/servers/$server->uuid/settings/rename", [
'name' => 'Test Server Name', 'name' => 'Test Server Name',
'description' => 'This is a test server.',
]) ])
->assertStatus(Response::HTTP_NO_CONTENT); ->assertStatus(Response::HTTP_NO_CONTENT);
$server = $server->refresh(); $server = $server->refresh();
$this->assertSame('Test Server Name', $server->name); $this->assertSame('Test Server Name', $server->name);
$this->assertSame('This is a test server.', $server->description);
} }
/** /**