diff --git a/app/Console/Commands/Environment/AppSettingsCommand.php b/app/Console/Commands/Environment/AppSettingsCommand.php new file mode 100644 index 000000000..39d23336b --- /dev/null +++ b/app/Console/Commands/Environment/AppSettingsCommand.php @@ -0,0 +1,174 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Console\Commands\Environment; + +use Ramsey\Uuid\Uuid; +use Illuminate\Console\Command; +use Illuminate\Contracts\Console\Kernel; +use Pterodactyl\Traits\Commands\EnvironmentWriterTrait; +use Illuminate\Contracts\Config\Repository as ConfigRepository; + +class AppSettingsCommand extends Command +{ + use EnvironmentWriterTrait; + + /** + * @var \Illuminate\Contracts\Console\Kernel + */ + protected $command; + + /** + * @var \Illuminate\Contracts\Config\Repository + */ + protected $config; + + /** + * @var string + */ + protected $description = 'Configure basic environment settings for the Panel.'; + + /** + * @var string + */ + protected $signature = 'p:environment:setup + {--url= : The URL that this Panel is running on.} + {--timezone= : The timezone to use for Panel times.} + {--cache= : The cache driver backend to use.} + {--session= : The session driver backend to use.} + {--redis-host= : Redis host to use for connections.} + {--redis-pass= : Password used to connect to redis.} + {--redis-port= : Port to connect to redis over.}'; + + /** + * @var array + */ + protected $variables = []; + + /** + * AppSettingsCommand constructor. + * + * @param \Illuminate\Contracts\Config\Repository $config + * @param \Illuminate\Contracts\Console\Kernel $command + */ + public function __construct(ConfigRepository $config, Kernel $command) + { + parent::__construct(); + + $this->command = $command; + $this->config = $config; + } + + /** + * Handle command execution. + * + * @throws \Pterodactyl\Exceptions\PterodactylException + */ + public function handle() + { + if (is_null($this->config->get('pterodactyl.service.author'))) { + $this->variables['SERVICE_AUTHOR'] = Uuid::uuid4()->toString(); + } + + $this->output->comment(trans('command/messages.environment.app.app_url_help')); + $this->variables['APP_URL'] = $this->option('url') ?? $this->ask( + trans('command/messages.environment.app.app_url'), $this->config->get('app.url', 'http://example.org') + ); + + $this->output->comment(trans('command/messages.environment.app.timezone_help')); + $this->variables['APP_TIMEZONE'] = $this->option('timezone') ?? $this->ask( + trans('command/messages.environment.app.timezone'), $this->config->get('app.timezone') + ); + + $this->variables['CACHE_DRIVER'] = $this->option('cache') ?? $this->choice( + trans('command/messages.environment.app.cache_driver'), [ + 'redis' => 'Redis (recommended)', + 'memcached' => 'Memcached', + ], $this->config->get('cache.default', 'redis') + ); + + $this->variables['SESSION_DRIVER'] = $this->option('session') ?? $this->choice( + trans('command/messages.environment.app.session_driver'), [ + 'redis' => 'Redis (recommended)', + 'memcached' => 'Memcached', + 'mysql' => 'MySQL Database', + 'file' => 'Filesystem', + 'cookie' => 'Cookie', + ], $this->config->get('session.driver', 'redis') + ); + + $this->variables['QUEUE_DRIVER'] = $this->option('session') ?? $this->choice( + trans('command/messages.environment.app.session_driver'), [ + 'redis' => 'Redis (recommended)', + 'database' => 'MySQL Database', + 'sync' => 'Sync', + ], $this->config->get('queue.driver', 'redis') + ); + + $this->checkForRedis(); + $this->writeToEnvironment($this->variables); + + $this->command->call('config:cache'); + $this->info($this->command->output()); + } + + /** + * Check if redis is selected, if so, request connection details and verify them. + */ + private function checkForRedis() + { + $items = collect($this->variables)->filter(function ($item) { + return $item === 'redis'; + }); + + // Redis was not selected, no need to continue. + if (count($items) === 0) { + return; + } + + $this->output->note(trans('command/messages.environment.app.using_redis')); + $this->variables['REDIS_HOST'] = $this->option('redis-host') ?? $this->ask( + trans('command/messages.environment.app.redis_host'), $this->config->get('database.redis.default.host') + ); + + $askForRedisPassword = true; + if (! empty($this->config->get('database.redis.default.password'))) { + $this->variables['REDIS_PASSWORD'] = $this->config->get('database.redis.default.password'); + $askForRedisPassword = $this->confirm(trans('command/messages.environment.app.redis_pass_defined')); + } + + if ($askForRedisPassword) { + $this->output->comment(trans('command/messages.environment.app.redis_pass_help')); + $this->variables['REDIS_PASSWORD'] = $this->option('redis-pass') ?? $this->output->askHidden( + trans('command/messages.environment.app.redis_password'), function () { + return true; + } + ); + } + + $this->variables['REDIS_PORT'] = $this->option('redis-port') ?? $this->ask( + trans('command/messages.environment.app.redis_port'), $this->config->get('database.redis.default.port') + ); + } +} diff --git a/app/Console/Commands/Environment/DatabaseSettingsCommand.php b/app/Console/Commands/Environment/DatabaseSettingsCommand.php new file mode 100644 index 000000000..9d7e9f0c0 --- /dev/null +++ b/app/Console/Commands/Environment/DatabaseSettingsCommand.php @@ -0,0 +1,165 @@ +. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +namespace Pterodactyl\Console\Commands\Environment; + +use PDOException; +use Illuminate\Console\Command; +use Illuminate\Contracts\Console\Kernel; +use Illuminate\Database\DatabaseManager; +use Pterodactyl\Traits\Commands\EnvironmentWriterTrait; +use Illuminate\Contracts\Config\Repository as ConfigRepository; + +class DatabaseSettingsCommand extends Command +{ + use EnvironmentWriterTrait; + + /** + * @var \Illuminate\Contracts\Config\Repository + */ + protected $config; + + /** + * @var \Illuminate\Contracts\Console\Kernel + */ + protected $console; + + /** + * @var \Illuminate\Database\DatabaseManager + */ + protected $database; + + /** + * @var string + */ + protected $description = 'Configure database settings for the Panel.'; + + /** + * @var string + */ + protected $signature = 'p:environment:database + {--host= : The connection address for the MySQL server.} + {--port= : The connection port for the MySQL server.}'; + + /** + * @var array + */ + protected $variables = []; + + /** + * DatabaseSettingsCommand constructor. + * + * @param \Illuminate\Contracts\Config\Repository $config + * @param \Illuminate\Database\DatabaseManager $database + * @param \Illuminate\Contracts\Console\Kernel $console + */ + public function __construct(ConfigRepository $config, DatabaseManager $database, Kernel $console) + { + parent::__construct(); + + $this->config = $config; + $this->console = $console; + $this->database = $database; + } + + /** + * Handle command execution. + * + * @return int + * + * @throws \Pterodactyl\Exceptions\PterodactylException + */ + public function handle() + { + $this->output->note(trans('command/messages.environment.database.host_warning')); + $this->variables['DB_HOST'] = $this->option('host') ?? $this->ask( + trans('command/messages.environment.database.host'), $this->config->get('database.connections.mysql.host', '127.0.0.1') + ); + + $this->variables['DB_PORT'] = $this->option('port') ?? $this->ask( + trans('command/messages.environment.database.port'), $this->config->get('database.connections.mysql.port', 3306) + ); + + $this->variables['DB_DATABASE'] = $this->option('port') ?? $this->ask( + trans('command/messages.environment.database.database'), $this->config->get('database.connections.mysql.database', 'panel') + ); + + $this->output->note(trans('command/messages.environment.database.username_warning')); + $this->variables['DB_USERNAME'] = $this->option('port') ?? $this->ask( + trans('command/messages.environment.database.username'), $this->config->get('database.connections.mysql.username', 'pterodactyl') + ); + + $askForMySQLPassword = true; + if (! empty($this->config->get('database.connections.mysql.password')) && $this->input->isInteractive()) { + $this->variables['DB_PASSWORD'] = $this->config->get('database.connections.mysql.password'); + $askForMySQLPassword = $this->confirm(trans('command/messages.environment.database.password_defined')); + } + + if ($askForMySQLPassword) { + $this->variables['DB_PASSWORD'] = $this->option('password') ?? $this->secret(trans('command/messages.environment.database.password')); + } + + try { + $this->testMySQLConnection(); + } catch (PDOException $exception) { + $this->output->error(trans('command/messages.environment.database.connection_error', ['error' => $exception->getMessage()])); + $this->output->error(trans('command/messages.environment.database.creds_not_saved')); + + if ($this->confirm(trans('command/messages.environment.database.try_again'))) { + $this->database->disconnect('_pterodactyl_command_test'); + + return $this->handle(); + } + + return 1; + } + + $this->writeToEnvironment($this->variables); + + $this->console->call('config:cache'); + $this->info($this->console->output()); + + return 0; + } + + /** + * Test that we can connect to the provided MySQL instance and perform a selection. + */ + private function testMySQLConnection() + { + $this->config->set('database.connections._pterodactyl_command_test', [ + 'driver' => 'mysql', + 'host' => $this->variables['DB_HOST'], + 'port' => $this->variables['DB_PORT'], + 'database' => $this->variables['DB_DATABASE'], + 'username' => $this->variables['DB_USERNAME'], + 'password' => $this->variables['DB_PASSWORD'], + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'strict' => true, + ]); + + $this->database->connection('_pterodactyl_command_test')->getPdo(); + } +} diff --git a/app/Console/Commands/UpdateEmailSettings.php b/app/Console/Commands/UpdateEmailSettings.php deleted file mode 100644 index 960742b99..000000000 --- a/app/Console/Commands/UpdateEmailSettings.php +++ /dev/null @@ -1,168 +0,0 @@ -. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -namespace Pterodactyl\Console\Commands; - -use Illuminate\Console\Command; - -class UpdateEmailSettings extends Command -{ - /** - * The name and signature of the console command. - * - * @var string - */ - protected $signature = 'pterodactyl:mail - {--driver=} - {--email=} - {--from-name=} - {--host=} - {--port=} - {--username=} - {--password=}'; - - /** - * The console command description. - * - * @var string - */ - protected $description = 'Sets or updates email settings for the .env file.'; - - /** - * Create a new command instance. - */ - public function __construct() - { - parent::__construct(); - } - - /** - * Execute the console command. - * - * @return mixed - */ - public function handle() - { - $variables = []; - $file = base_path() . '/.env'; - if (! file_exists($file)) { - $this->error('Missing environment file! It appears that you have not installed this panel correctly.'); - exit(); - } - - $envContents = file_get_contents($file); - - $this->table([ - 'Option', - 'Description', - ], [ - [ - 'smtp', - 'SMTP Server Email', - ], - [ - 'mail', - 'PHP\'s Internal Mail Server', - ], - [ - 'mailgun', - 'Mailgun Email Service', - ], - [ - 'mandrill', - 'Mandrill Transactional Email Service', - ], - [ - 'postmark', - 'Postmark Transactional Email Service', - ], - ]); - - $variables['MAIL_DRIVER'] = is_null($this->option('driver')) ? $this->choice('Which email driver would you like to use?', [ - 'smtp', - 'mail', - 'mailgun', - 'mandrill', - 'postmark', - ]) : $this->option('driver'); - - switch ($variables['MAIL_DRIVER']) { - case 'smtp': - $variables['MAIL_HOST'] = is_null($this->option('host')) ? $this->ask('SMTP Host (e.g smtp.google.com)', config('mail.host')) : $this->option('host'); - $variables['MAIL_PORT'] = is_null($this->option('port')) ? $this->anticipate('SMTP Host Port (e.g 587)', ['587', config('mail.port')], config('mail.port')) : $this->option('port'); - $variables['MAIL_USERNAME'] = is_null($this->option('username')) ? $this->ask('SMTP Username', config('mail.username')) : $this->option('password'); - $variables['MAIL_PASSWORD'] = is_null($this->option('password')) ? $this->secret('SMTP Password') : $this->option('password'); - break; - case 'mail': - break; - case 'mailgun': - $variables['MAILGUN_DOMAIN'] = is_null($this->option('host')) ? $this->ask('Mailgun Domain') : $this->option('host'); - $variables['MAILGUN_KEY'] = is_null($this->option('username')) ? $this->ask('Mailgun Key') : $this->option('username'); - break; - case 'mandrill': - $variables['MANDRILL_SECRET'] = is_null($this->option('username')) ? $this->ask('Mandrill Secret') : $this->option('username'); - break; - case 'postmark': - $variables['MAIL_DRIVER'] = 'smtp'; - $variables['MAIL_HOST'] = 'smtp.postmarkapp.com'; - $variables['MAIL_PORT'] = 587; - $variables['MAIL_USERNAME'] = is_null($this->option('username')) ? $this->ask('Postmark API Token', config('mail.username')) : $this->option('username'); - $variables['MAIL_PASSWORD'] = $variables['MAIL_USERNAME']; - break; - default: - $this->error('No email service was defined!'); - exit(); - break; - } - - $variables['MAIL_FROM'] = is_null($this->option('email')) ? $this->ask('Email address emails should originate from', config('mail.from.address')) : $this->option('email'); - $variables['MAIL_FROM_NAME'] = is_null($this->option('from-name')) ? $this->ask('Name emails should appear to be from', config('mail.from.name')) : $this->option('from-name'); - $variables['MAIL_FROM_NAME'] = '"' . $variables['MAIL_FROM_NAME'] . '"'; - $variables['MAIL_ENCRYPTION'] = 'tls'; - - $bar = $this->output->createProgressBar(count($variables)); - - $this->line('Writing new email environment configuration to file.'); - foreach ($variables as $key => $value) { - if (str_contains($value, ' ') && ! str_contains($value, '"')) { - $value = '"' . $value . '"'; - } - $newValue = $key . '=' . $value . ' # DO NOT EDIT! set using pterodactyl:mail'; - - if (preg_match_all('/^' . $key . '=(.*)$/m', $envContents) < 1) { - $envContents = $envContents . "\n" . $newValue; - } else { - $envContents = preg_replace('/^' . $key . '=(.*)$/m', $newValue, $envContents); - } - $bar->advance(); - } - - file_put_contents($file, $envContents); - $bar->finish(); - - $this->line('Updating environment configuration cache file.'); - $this->call('config:cache'); - echo "\n"; - } -} diff --git a/app/Console/Commands/UpdateEnvironment.php b/app/Console/Commands/UpdateEnvironment.php deleted file mode 100644 index 5ee663908..000000000 --- a/app/Console/Commands/UpdateEnvironment.php +++ /dev/null @@ -1,206 +0,0 @@ -. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -namespace Pterodactyl\Console\Commands; - -use Uuid; -use Illuminate\Console\Command; - -class UpdateEnvironment extends Command -{ - /** - * The name and signature of the console command. - * - * @var string - */ - protected $signature = 'pterodactyl:env - {--dbhost=} - {--dbport=} - {--dbname=} - {--dbuser=} - {--dbpass=} - {--url=} - {--driver=} - {--session-driver=} - {--queue-driver=} - {--timezone=}'; - - /** - * The console command description. - * - * @var string - */ - protected $description = 'Update environment settings automatically.'; - - /** - * Create a new command instance. - */ - public function __construct() - { - parent::__construct(); - } - - /** - * Execute the console command. - * - * @return mixed - */ - public function handle() - { - $variables = []; - $file = base_path() . '/.env'; - if (! file_exists($file)) { - $this->error('Missing environment file! It appears that you have not installed this panel correctly.'); - exit(); - } - - $envContents = file_get_contents($file); - - $this->info('Simply leave blank and press enter to fields that you do not wish to update.'); - if (is_null(config('pterodactyl.service.author', null))) { - $this->info('No service author set, setting one now.'); - $variables['SERVICE_AUTHOR'] = (string) Uuid::generate(4); - } - - if (isset($variables['APP_THEME'])) { - if ($variables['APP_THEME'] === 'default') { - $variables['APP_THEME'] = 'pterodactyl'; - } - } - - if (is_null($this->option('dbhost'))) { - $variables['DB_HOST'] = $this->anticipate('Database Host', ['localhost', '127.0.0.1', config('database.connections.mysql.host')], config('database.connections.mysql.host')); - } else { - $variables['DB_HOST'] = $this->option('dbhost'); - } - - if (is_null($this->option('dbport'))) { - $variables['DB_PORT'] = $this->anticipate('Database Port', [3306, config('database.connections.mysql.port')], config('database.connections.mysql.port')); - } else { - $variables['DB_PORT'] = $this->option('dbport'); - } - - if (is_null($this->option('dbname'))) { - $variables['DB_DATABASE'] = $this->anticipate('Database Name', ['pterodactyl', 'homestead', config('database.connections.mysql.database')], config('database.connections.mysql.database')); - } else { - $variables['DB_DATABASE'] = $this->option('dbname'); - } - - if (is_null($this->option('dbuser'))) { - $variables['DB_USERNAME'] = $this->anticipate('Database Username', [config('database.connections.mysql.username')], config('database.connections.mysql.username')); - } else { - $variables['DB_USERNAME'] = $this->option('dbuser'); - } - - if (is_null($this->option('dbpass'))) { - $this->line('The Database Password field is required; you cannot hit enter and use a default value.'); - $variables['DB_PASSWORD'] = $this->secret('Database User Password'); - } else { - $variables['DB_PASSWORD'] = $this->option('dbpass'); - } - - if (is_null($this->option('url'))) { - $variables['APP_URL'] = $this->ask('Panel URL (include http(s)://)', config('app.url')); - } else { - $variables['APP_URL'] = $this->option('url'); - } - - if (is_null($this->option('timezone'))) { - $this->line('The timezone should match one of the supported timezones according to http://php.net/manual/en/timezones.php'); - $variables['APP_TIMEZONE'] = $this->anticipate('Panel Timezone', \DateTimeZone::listIdentifiers(\DateTimeZone::ALL), config('app.timezone')); - } else { - $variables['APP_TIMEZONE'] = $this->option('timezone'); - } - - if (is_null($this->option('driver'))) { - $options = [ - 'memcached' => 'Memcache', - 'redis' => 'Redis (recommended)', - 'apc' => 'APC', - 'array' => 'PHP Array', - ]; - $default = (in_array(config('cache.default', 'memcached'), $options)) ? config('cache.default', 'memcached') : 'memcached'; - - $this->line('If you chose redis as your cache driver backend, you *must* have a redis server configured already.'); - $variables['CACHE_DRIVER'] = $this->choice('Which cache driver backend would you like to use?', $options, $default); - } else { - $variables['CACHE_DRIVER'] = $this->option('driver'); - } - - if (is_null($this->option('session-driver'))) { - $options = [ - 'database' => 'MySQL (recommended)', - 'redis' => 'Redis', - 'file' => 'File', - 'cookie' => 'Cookie', - 'apc' => 'APC', - 'array' => 'PHP Array', - ]; - $default = (in_array(config('session.driver', 'database'), $options)) ? config('cache.default', 'database') : 'database'; - - $this->line('If you chose redis as your cache driver backend, you *must* have a redis server configured already.'); - $variables['SESSION_DRIVER'] = $this->choice('Which session driver backend would you like to use?', $options, $default); - } else { - $variables['SESSION_DRIVER'] = $this->option('session-driver'); - } - - if (is_null($this->option('queue-driver'))) { - $options = [ - 'database' => 'Database (recommended)', - 'redis' => 'Redis', - 'sqs' => 'Amazon SQS', - 'sync' => 'Sync', - 'null' => 'None', - ]; - $default = (in_array(config('queue.driver', 'database'), $options)) ? config('queue.driver', 'database') : 'database'; - - $this->line('If you chose redis as your queue driver backend, you *must* have a redis server configured already.'); - $variables['QUEUE_DRIVER'] = $this->choice('Which queue driver backend would you like to use?', $options, $default); - } else { - $variables['QUEUE_DRIVER'] = $this->option('queue-driver'); - } - - $bar = $this->output->createProgressBar(count($variables)); - - foreach ($variables as $key => $value) { - if (str_contains($value, ' ') && ! str_contains($value, '"')) { - $value = '"' . $value . '"'; - } - $newValue = $key . '=' . $value . ' # DO NOT EDIT! set using pterodactyl:env'; - - if (preg_match_all('/^' . $key . '=(.*)$/m', $envContents) < 1) { - $envContents = $envContents . "\n" . $newValue; - } else { - $envContents = preg_replace('/^' . $key . '=(.*)$/m', $newValue, $envContents); - } - $bar->advance(); - } - - file_put_contents($file, $envContents); - $bar->finish(); - - $this->call('config:cache'); - $this->line("\n"); - } -} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index c74250e06..4d7fc2c5a 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -10,9 +10,11 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel; use Pterodactyl\Console\Commands\Server\RebuildServerCommand; use Pterodactyl\Console\Commands\Location\MakeLocationCommand; use Pterodactyl\Console\Commands\User\DisableTwoFactorCommand; +use Pterodactyl\Console\Commands\Environment\AppSettingsCommand; use Pterodactyl\Console\Commands\Location\DeleteLocationCommand; use Pterodactyl\Console\Commands\Schedule\ProcessRunnableCommand; use Pterodactyl\Console\Commands\Environment\EmailSettingsCommand; +use Pterodactyl\Console\Commands\Environment\DatabaseSettingsCommand; use Pterodactyl\Console\Commands\Maintenance\CleanServiceBackupFilesCommand; class Kernel extends ConsoleKernel @@ -23,7 +25,9 @@ class Kernel extends ConsoleKernel * @var array */ protected $commands = [ + AppSettingsCommand::class, CleanServiceBackupFilesCommand::class, + DatabaseSettingsCommand::class, DeleteLocationCommand::class, DeleteUserCommand::class, DisableTwoFactorCommand::class, diff --git a/config/database.php b/config/database.php index b9ce78c03..998f95d4d 100644 --- a/config/database.php +++ b/config/database.php @@ -33,15 +33,15 @@ return [ 'connections' => [ 'mysql' => [ 'driver' => 'mysql', - 'host' => env('DB_HOST', 'localhost'), + 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), - 'database' => env('DB_DATABASE', 'forge'), - 'username' => env('DB_USERNAME', 'forge'), + 'database' => env('DB_DATABASE', 'panel'), + 'username' => env('DB_USERNAME', 'pterodactyl'), 'password' => env('DB_PASSWORD', ''), - 'charset' => 'utf8', - 'collation' => 'utf8_unicode_ci', + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', - 'strict' => false, + 'strict' => env('DB_STRICT_MODE', true), ], ], diff --git a/resources/lang/en/command/messages.php b/resources/lang/en/command/messages.php index d9e719679..304b604c5 100644 --- a/resources/lang/en/command/messages.php +++ b/resources/lang/en/command/messages.php @@ -75,5 +75,32 @@ return [ 'ask_mail_name' => 'Name that emails should appear from', 'ask_encryption' => 'Encryption method to use', ], + 'database' => [ + 'host_warning' => 'It is highly recommended to not use "localhost" as your database host as we have seen frequent socket connection issues. If you want to use a local connection you should be using "127.0.0.1".', + 'host' => 'Database Host', + 'port' => 'Database Port', + 'database' => 'Database Name', + 'username_warning' => 'Using the "root" account for MySQL connections is not only highly frowned upon, it is also not allowed by this application. You\'ll need to have created a MySQL user for this software.', + 'username' => 'Database Username', + 'password_defined' => 'It appears you already have a MySQL connection password defined, would you like to change it?', + 'password' => 'Database Password', + 'connection_error' => 'Unable to connect to the MySQL server using the provided credentials. The error returned was ":error".', + 'creds_not_saved' => 'Your connection credentials have NOT been saved. You will need to provide valid connection information before proceeding.', + 'try_again' => 'Go back and try again?', + ], + 'app' => [ + 'app_url_help' => 'The application URL MUST begin with https:// or http:// depending on if you are using SSL or not. If you do not include the scheme your emails and other content will link to the wrong location.', + 'app_url' => 'Application URL', + 'timezone_help' => 'The timezone should match one of PHP\'s supported timezones. If you are unsure, please reference http://php.net/manual/en/timezones.php.', + 'timezone' => 'Application Timezone', + 'cache_driver' => 'Cache Driver', + 'session_driver' => 'Session Driver', + 'using_redis' => 'You\'ve selected the Redis driver for one or more options, please provide valid connection information below. In most cases you can use the defaults provided unless you have modified your setup.', + 'redis_host' => 'Redis Host', + 'redis_password' => 'Redis Password', + 'redis_port' => 'Redis Port', + 'redis_pass_defined' => 'It seems a password is already defined for Redis, would you like to change it?', + 'redis_pass_help' => 'By default a Redis server instance has no password as it is running locally and inaccessable to the outside world. If this is the case, simply hit enter without entering a value.', + ], ], ];