diff --git a/app/Console/Commands/Environment/AppSettingsCommand.php b/app/Console/Commands/Environment/AppSettingsCommand.php index c1f857f4e..b46eccdff 100644 --- a/app/Console/Commands/Environment/AppSettingsCommand.php +++ b/app/Console/Commands/Environment/AppSettingsCommand.php @@ -9,7 +9,6 @@ use App\Traits\Commands\EnvironmentWriterTrait; class AppSettingsCommand extends Command { use EnvironmentWriterTrait; - public const CACHE_DRIVERS = [ 'redis' => 'Redis', 'memcached' => 'Memcached', @@ -62,11 +61,12 @@ class AppSettingsCommand extends Command */ public function handle(): int { + if (empty(config('hashids.salt')) || $this->option('new-salt')) { $this->variables['HASHIDS_SALT'] = str_random(20); } - $this->output->comment('Provide the email address that eggs exported by this Panel should be from. This should be a valid email address.'); + $this->output->comment(__('commands.appsettings.comment.author')); $this->variables['APP_SERVICE_AUTHOR'] = $this->option('author') ?? $this->ask( 'Egg Author Email', config('panel.service.author', 'unknown@unknown.com') @@ -78,13 +78,13 @@ class AppSettingsCommand extends Command return 1; } - $this->output->comment('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.'); + $this->output->comment(__('commands.appsettings.comment.url')); $this->variables['APP_URL'] = $this->option('url') ?? $this->ask( 'Application URL', config('app.url', 'https://example.com') ); - $this->output->comment('The timezone should match one of PHP\'s supported timezones. If you are unsure, please reference https://php.net/manual/en/timezones.php.'); + $this->output->comment(__('commands.appsettings.comment.timezone')); $this->variables['APP_TIMEZONE'] = $this->option('timezone') ?? $this->anticipate( 'Application Timezone', \DateTimeZone::listIdentifiers(), @@ -115,7 +115,7 @@ class AppSettingsCommand extends Command if (!is_null($this->option('settings-ui'))) { $this->variables['APP_ENVIRONMENT_ONLY'] = $this->option('settings-ui') == 'true' ? 'false' : 'true'; } else { - $this->variables['APP_ENVIRONMENT_ONLY'] = $this->confirm('Enable UI based settings editor?', true) ? 'false' : 'true'; + $this->variables['APP_ENVIRONMENT_ONLY'] = $this->confirm(__('commands.appsettings.comment.settings_ui'), true) ? 'false' : 'true'; } // Make sure session cookies are set as "secure" when using HTTPS @@ -145,7 +145,7 @@ class AppSettingsCommand extends Command return; } - $this->output->note('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.'); + $this->output->note(__('commands.appsettings.redis.note')); $this->variables['REDIS_HOST'] = $this->option('redis-host') ?? $this->ask( 'Redis Host', config('database.redis.default.host') @@ -158,7 +158,7 @@ class AppSettingsCommand extends Command } if ($askForRedisPassword) { - $this->output->comment('By default a Redis server instance has no password as it is running locally and inaccessible to the outside world. If this is the case, simply hit enter without entering a value.'); + $this->output->comment(__('commands.appsettings.redis.comment')); $this->variables['REDIS_PASSWORD'] = $this->option('redis-pass') ?? $this->output->askHidden( 'Redis Password' ); diff --git a/app/Console/Commands/Environment/DatabaseSettingsCommand.php b/app/Console/Commands/Environment/DatabaseSettingsCommand.php index bf31b1357..e9369a965 100644 --- a/app/Console/Commands/Environment/DatabaseSettingsCommand.php +++ b/app/Console/Commands/Environment/DatabaseSettingsCommand.php @@ -49,7 +49,7 @@ class DatabaseSettingsCommand extends Command ); if ($this->variables['DB_CONNECTION'] === 'mysql') { - $this->output->note('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".'); + $this->output->note(__('commands.database_settings.DB_HOST_note')); $this->variables['DB_HOST'] = $this->option('host') ?? $this->ask( 'Database Host', config('database.connections.mysql.host', '127.0.0.1') @@ -65,7 +65,7 @@ class DatabaseSettingsCommand extends Command config('database.connections.mysql.database', 'panel') ); - $this->output->note('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.'); + $this->output->note(__('commands.database_settings.DB_USERNAME_note')); $this->variables['DB_USERNAME'] = $this->option('username') ?? $this->ask( 'Database Username', config('database.connections.mysql.username', 'pelican') @@ -74,7 +74,7 @@ class DatabaseSettingsCommand extends Command $askForMySQLPassword = true; if (!empty(config('database.connections.mysql.password')) && $this->input->isInteractive()) { $this->variables['DB_PASSWORD'] = config('database.connections.mysql.password'); - $askForMySQLPassword = $this->confirm('It appears you already have a MySQL connection password defined, would you like to change it?'); + $askForMySQLPassword = $this->confirm(__('commands.database_settings.DB_PASSWORD_note')); } if ($askForMySQLPassword) { @@ -85,9 +85,9 @@ class DatabaseSettingsCommand extends Command $this->testMySQLConnection(); } catch (\PDOException $exception) { $this->output->error(sprintf('Unable to connect to the MySQL server using the provided credentials. The error returned was "%s".', $exception->getMessage())); - $this->output->error('Your connection credentials have NOT been saved. You will need to provide valid connection information before proceeding.'); + $this->output->error(__('commands.database_settings.DB_error_2')); - if ($this->confirm('Go back and try again?')) { + if ($this->confirm(__('commands.database_settings.go_back'))) { $this->database->disconnect('_panel_command_test'); return $this->handle(); diff --git a/app/Console/Commands/Node/MakeNodeCommand.php b/app/Console/Commands/Node/MakeNodeCommand.php index 002b36b78..719e68e96 100644 --- a/app/Console/Commands/Node/MakeNodeCommand.php +++ b/app/Console/Commands/Node/MakeNodeCommand.php @@ -42,27 +42,28 @@ class MakeNodeCommand extends Command */ public function handle(): void { - $data['name'] = $this->option('name') ?? $this->ask('Enter a short identifier used to distinguish this node from others'); - $data['description'] = $this->option('description') ?? $this->ask('Enter a description to identify the node'); + $data['name'] = $this->option('name') ?? $this->ask(__('commands.make_node.name')); + $data['description'] = $this->option('description') ?? $this->ask(__('commands.make_node.description')); $data['scheme'] = $this->option('scheme') ?? $this->anticipate( - 'Please either enter https for SSL or http for a non-ssl connection', + __('commands.make_node.scheme'), ['https', 'http'], 'https' ); - $data['fqdn'] = $this->option('fqdn') ?? $this->ask('Enter a domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node'); - $data['public'] = $this->option('public') ?? $this->confirm('Should this node be public? As a note, setting a node to private you will be denying the ability to auto-deploy to this node.', true); - $data['behind_proxy'] = $this->option('proxy') ?? $this->confirm('Is your FQDN behind a proxy?'); - $data['maintenance_mode'] = $this->option('maintenance') ?? $this->confirm('Should maintenance mode be enabled?'); - $data['memory'] = $this->option('maxMemory') ?? $this->ask('Enter the maximum amount of memory'); - $data['memory_overallocate'] = $this->option('overallocateMemory') ?? $this->ask('Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new servers'); - $data['disk'] = $this->option('maxDisk') ?? $this->ask('Enter the maximum amount of disk space'); - $data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask('Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new server'); - $data['upload_size'] = $this->option('uploadSize') ?? $this->ask('Enter the maximum filesize upload', '100'); - $data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask('Enter the daemon listening port', '8080'); - $data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask('Enter the daemon SFTP listening port', '2022'); - $data['daemon_base'] = $this->option('daemonBase') ?? $this->ask('Enter the base folder', '/var/lib/pelican/volumes'); + + $data['fqdn'] = $this->option('fqdn') ?? $this->ask(__('commands.make_node.fqdn')); + $data['public'] = $this->option('public') ?? $this->confirm(__('commands.make_node.public'), true); + $data['behind_proxy'] = $this->option('proxy') ?? $this->confirm(__('commands.make_node.behind_proxy')); + $data['maintenance_mode'] = $this->option('maintenance') ?? $this->confirm(__('commands.make_node.maintenance_mode')); + $data['memory'] = $this->option('maxMemory') ?? $this->ask(__('commands.make_node.memory')); + $data['memory_overallocate'] = $this->option('overallocateMemory') ?? $this->ask(__('commands.make_node.memory_overallocate')); + $data['disk'] = $this->option('maxDisk') ?? $this->ask(__('commands.make_node.disk')); + $data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask(__('commands.make_node.disk_overallocate')); + $data['upload_size'] = $this->option('uploadSize') ?? $this->ask(__('commands.make_node.upload_size'), '100'); + $data['daemon_listen'] = $this->option('daemonListeningPort') ?? $this->ask(__('commands.make_node.daemonListen'), '8080'); + $data['daemon_sftp'] = $this->option('daemonSFTPPort') ?? $this->ask(__('commands.make_node.daemonSFTP'), '2022'); + $data['daemon_base'] = $this->option('daemonBase') ?? $this->ask(__('commands.make_node.daemonBase'), '/var/lib/pelican/volumes'); $node = $this->creationService->handle($data); - $this->line('Successfully created a new node with the name ' . $data['name'] . ' and has an id of ' . $node->id . '.'); + $this->line(__('commands.make_node.succes1') . $data['name'] . __('commands.make_node.succes2') . $node->id . '.'); } } diff --git a/app/Console/Commands/Node/NodeConfigurationCommand.php b/app/Console/Commands/Node/NodeConfigurationCommand.php index e52dccd72..44c2ec22b 100644 --- a/app/Console/Commands/Node/NodeConfigurationCommand.php +++ b/app/Console/Commands/Node/NodeConfigurationCommand.php @@ -19,14 +19,14 @@ class NodeConfigurationCommand extends Command /** @var \App\Models\Node $node */ $node = Node::query()->where($column, $this->argument('node'))->firstOr(function () { - $this->error('The selected node does not exist.'); + $this->error(__('commands.node_config.error_not_exist')); exit(1); }); $format = $this->option('format'); if (!in_array($format, ['yaml', 'yml', 'json'])) { - $this->error('Invalid format specified. Valid options are "yaml" and "json".'); + $this->error(__('commands.node_config.error_invalid_format')); return 1; } diff --git a/app/Console/Commands/Overrides/KeyGenerateCommand.php b/app/Console/Commands/Overrides/KeyGenerateCommand.php index d837c7b46..c1528de69 100644 --- a/app/Console/Commands/Overrides/KeyGenerateCommand.php +++ b/app/Console/Commands/Overrides/KeyGenerateCommand.php @@ -13,12 +13,12 @@ class KeyGenerateCommand extends BaseKeyGenerateCommand public function handle(): void { if (!empty(config('app.key')) && $this->input->isInteractive()) { - $this->output->warning('It appears you have already configured an application encryption key. Continuing with this process with overwrite that key and cause data corruption for any existing encrypted data. DO NOT CONTINUE UNLESS YOU KNOW WHAT YOU ARE DOING.'); - if (!$this->confirm('I understand the consequences of performing this command and accept all responsibility for the loss of encrypted data.')) { + $this->output->warning(__('commands.key_generate.error_already_exist')); + if (!$this->confirm(__('commands.key_generate.understand'))) { return; } - if (!$this->confirm('Are you sure you wish to continue? Changing the application encryption key WILL CAUSE DATA LOSS.')) { + if (!$this->confirm(__('commands.key_generate.continue'))) { return; } } diff --git a/app/Console/Commands/Schedule/ProcessRunnableCommand.php b/app/Console/Commands/Schedule/ProcessRunnableCommand.php index a5d007bde..eaad4d98a 100644 --- a/app/Console/Commands/Schedule/ProcessRunnableCommand.php +++ b/app/Console/Commands/Schedule/ProcessRunnableCommand.php @@ -27,7 +27,7 @@ class ProcessRunnableCommand extends Command ->get(); if ($schedules->count() < 1) { - $this->line('There are no scheduled tasks for servers that need to be run.'); + $this->line(__('commands.schedule.process.no_tasks')); return 0; } @@ -66,7 +66,7 @@ class ProcessRunnableCommand extends Command } catch (\Throwable|\Exception $exception) { logger()->error($exception, ['schedule_id' => $schedule->id]); - $this->error("An error was encountered while processing Schedule #$schedule->id: " . $exception->getMessage()); + $this->error(__('commands.schedule.process.no_tasks') . " #$schedule->id: " . $exception->getMessage()); } } } diff --git a/app/Console/Commands/UpgradeCommand.php b/app/Console/Commands/UpgradeCommand.php index e04d1a50c..75a3c185f 100644 --- a/app/Console/Commands/UpgradeCommand.php +++ b/app/Console/Commands/UpgradeCommand.php @@ -34,29 +34,30 @@ class UpgradeCommand extends Command { $skipDownload = $this->option('skip-download'); if (!$skipDownload) { - $this->output->warning('This command does not verify the integrity of downloaded assets. Please ensure that you trust the download source before continuing. If you do not wish to download an archive, please indicate that using the --skip-download flag, or answering "no" to the question below.'); - $this->output->comment('Download Source (set with --url=):'); + $this->output->warning(__('commands.upgrade.integrity')); + $this->output->comment(__('commands.upgrade.source_url')); $this->line($this->getUrl()); } if (version_compare(PHP_VERSION, '7.4.0') < 0) { - $this->error('Cannot execute self-upgrade process. The minimum required PHP version required is 7.4.0, you have [' . PHP_VERSION . '].'); + $this->error(__('commands.upgrade.php_version') . ' [' . PHP_VERSION . '].'); } $user = 'www-data'; $group = 'www-data'; if ($this->input->isInteractive()) { if (!$skipDownload) { - $skipDownload = !$this->confirm('Would you like to download and unpack the archive files for the latest version?', true); + $skipDownload = !$this->confirm(__('commands.upgrade.skipDownload'), true); } if (is_null($this->option('user'))) { $userDetails = function_exists('posix_getpwuid') ? posix_getpwuid(fileowner('public')) : []; $user = $userDetails['name'] ?? 'www-data'; - if (!$this->confirm("Your webserver user has been detected as [{$user}]: is this correct?", true)) { + $message = __('commands.upgrade.webserver_user', ['user' => $user]); + if (!$this->confirm($message, true)) { $user = $this->anticipate( - 'Please enter the name of the user running your webserver process. This varies from system to system, but is generally "www-data", "nginx", or "apache".', + __('commands.upgrade.name_webserver'), [ 'www-data', 'nginx', @@ -70,9 +71,10 @@ class UpgradeCommand extends Command $groupDetails = function_exists('posix_getgrgid') ? posix_getgrgid(filegroup('public')) : []; $group = $groupDetails['name'] ?? 'www-data'; - if (!$this->confirm("Your webserver group has been detected as [{$group}]: is this correct?", true)) { + $message = __('commands.upgrade.group_webserver', ['group' => $user]); + if (!$this->confirm($message, true)) { $group = $this->anticipate( - 'Please enter the name of the group running your webserver process. Normally this is the same as your user.', + __('commands.upgrade.group_webserver_question'), [ 'www-data', 'nginx', @@ -82,8 +84,8 @@ class UpgradeCommand extends Command } } - if (!$this->confirm('Are you sure you want to run the upgrade process for your Panel?')) { - $this->warn('Upgrade process terminated by user.'); + if (!$this->confirm(__('commands.upgrade.are_your_sure'))) { + $this->warn(__('commands.upgrade.terminated')); return; } @@ -173,7 +175,7 @@ class UpgradeCommand extends Command }); $this->newLine(2); - $this->info('Panel has been successfully upgraded. Please ensure you also update any Daemon instances'); + $this->info(__('commands.upgrade.success')); } protected function withProgress(ProgressBar $bar, \Closure $callback) diff --git a/lang/en/commands.php b/lang/en/commands.php new file mode 100644 index 000000000..8a44d0d0f --- /dev/null +++ b/lang/en/commands.php @@ -0,0 +1,71 @@ + [ + 'comment' => [ + 'author' => 'Provide the email address that eggs exported by this Panel should be from. This should be a valid email address.', + 'url' => '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.', + 'timezone' => "The timezone should match one of PHP\'s supported timezones. If you are unsure, please reference https://php.net/manual/en/timezones.php.", + 'settings_ui' => 'Enable UI based settings editor?', + ], + 'redis' => [ + 'note' => '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.', + 'comment' => 'By default a Redis server instance has no password as it is running locally and inaccessible to the outside world. If this is the case, simply hit enter without entering a value.', + ], + ], + 'database_settings' => [ + 'DB_HOST_note' => '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".', + 'DB_USERNAME_note' => "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.", + 'DB_PASSWORD_note' => 'It appears you already have a MySQL connection password defined, would you like to change it?', + 'DB_error_2' => 'Your connection credentials have NOT been saved. You will need to provide valid connection information before proceeding.', + 'go_back' => 'Go back and try again', + ], + 'make_node' => [ + 'name' => 'Enter a short identifier used to distinguish this node from others', + 'description' => 'Enter a description to identify the node', + 'scheme' => 'Please either enter https for SSL or http for a non-ssl connection', + 'fqdn' => 'Enter a domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node', + 'public' => 'Should this node be public? As a note, setting a node to private you will be denying the ability to auto-deploy to this node.', + 'behind_proxy' => 'Is your FQDN behind a proxy?', + 'maintenance_mode' => 'Should maintenance mode be enabled?', + 'memory' => 'Enter the maximum amount of memory', + 'memory_overallocate' => 'Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new servers', + 'disk' => 'Enter the maximum amount of disk space', + 'disk_overallocate' => 'Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new server', + 'upload_size' => "'Enter the maximum filesize upload", + 'daemonListen' => 'Enter the daemon listening port', + 'daemonSFTP' => 'Enter the daemon SFTP listening port', + 'daemonBase' => 'Enter the base folder', + 'succes1' => 'Successfully created a new node with the name: ', + 'succes2' => 'and has an id of: ', + ], + 'node_config' => [ + 'error_not_exist' => 'The selected node does not exist.', + 'error_invalid_format' => 'Invalid format specified. Valid options are yaml and json.', + ], + 'key_generate' => [ + 'error_already_exist' => 'It appears you have already configured an application encryption key. Continuing with this process with overwrite that key and cause data corruption for any existing encrypted data. DO NOT CONTINUE UNLESS YOU KNOW WHAT YOU ARE DOING.', + 'understand' => 'I understand the consequences of performing this command and accept all responsibility for the loss of encrypted data.', + 'continue' => 'Are you sure you wish to continue? Changing the application encryption key WILL CAUSE DATA LOSS.', + ], + 'schedule' => [ + 'process' => [ + 'no_tasks' => 'There are no scheduled tasks for servers that need to be run.', + 'error_message' => 'An error was encountered while processing Schedule: ', + ], + ], + 'upgrade' => [ + 'integrity' => 'This command does not verify the integrity of downloaded assets. Please ensure that you trust the download source before continuing. If you do not wish to download an archive, please indicate that using the --skip-download flag, or answering "no" to the question below.', + 'source_url' => 'Download Source (set with --url=):', + 'php_version' => 'Cannot execute self-upgrade process. The minimum required PHP version required is 7.4.0, you have', + 'skipDownload' => 'Would you like to download and unpack the archive files for the latest version?', + 'webserver_user' => 'Your webserver user has been detected as [{:user}]: is this correct?', + 'name_webserver' => 'Please enter the name of the user running your webserver process. This varies from system to system, but is generally "www-data", "nginx", or "apache".', + 'group_webserver' => 'Your webserver group has been detected as [{:group}]: is this correct?', + 'group_webserver_question' => 'Please enter the name of the group running your webserver process. Normally this is the same as your user.', + 'are_your_sure' => 'Are you sure you want to run the upgrade process for your Panel?', + 'terminated' => 'Upgrade process terminated by user.', + 'success' => 'Panel has been successfully upgraded. Please ensure you also update any Daemon instances', + + ], +]; diff --git a/resources/scripts/assets/images/pterodactyl.svg b/resources/scripts/assets/images/pterodactyl.svg deleted file mode 100755 index f3582adf2..000000000 --- a/resources/scripts/assets/images/pterodactyl.svg +++ /dev/null @@ -1 +0,0 @@ -Artboard 1 \ No newline at end of file