diff --git a/app/Filament/Admin/Resources/Nodes/Pages/CreateNode.php b/app/Filament/Admin/Resources/Nodes/Pages/CreateNode.php index b913ec4d8..861022f28 100644 --- a/app/Filament/Admin/Resources/Nodes/Pages/CreateNode.php +++ b/app/Filament/Admin/Resources/Nodes/Pages/CreateNode.php @@ -64,9 +64,8 @@ class CreateNode extends CreateRecord ->icon(TablerIcon::Server) ->columnSpanFull() ->columns([ - 'default' => 2, - 'sm' => 3, - 'md' => 3, + 'default' => 1, + 'md' => 2, 'lg' => 4, ]) ->schema([ @@ -76,81 +75,83 @@ class CreateNode extends CreateRecord ->autofocus() ->live(debounce: 1500) ->rules(Node::getRulesForField('fqdn')) - ->prohibited(fn ($state) => is_ip($state) && request()->isSecure()) ->label(fn ($state) => is_ip($state) ? trans('admin/node.ip_address') : trans('admin/node.domain')) ->placeholder(fn ($state) => is_ip($state) ? '192.168.1.1' : 'node.example.com') - ->helperText(function ($state) { + ->helperText(fn () => request()->isSecure() ? trans('admin/node.fqdn_ssl') : null) + ->validationMessages([ + 'prohibited' => trans('admin/node.dns_error'), + ]) + ->prohibited(function ($state, Get $get) { + if (!$state) { + return true; + } + + if (is_ip($state)) { + return false; + } + + $ip = $get('ip'); + + return !is_ip($ip); + }) + ->hintColor(function ($state, Get $get) { + if (!$state) { + return null; + } + if (is_ip($state)) { if (request()->isSecure()) { - return trans('admin/node.fqdn_help'); + return 'warning'; } + } else { + $ip = $get('ip'); - return ''; + return is_ip($ip) ? 'success' : 'danger'; } - return trans('admin/node.error'); + return null; }) - ->hintColor('danger') - ->hint(function ($state) { - if (is_ip($state) && request()->isSecure()) { - return trans('admin/node.ssl_ip'); + ->hint(function ($state, Get $get) { + if (!$state) { + return null; } - return ''; + if (is_ip($state)) { + if (request()->isSecure()) { + return trans('admin/node.ssl_ip'); + } + } else { + $ip = $get('ip'); + + return is_ip($ip) ? trans('admin/node.valid') . ': ' . $ip : trans('admin/node.invalid'); + } + + return null; }) ->afterStateUpdated(function (Set $set, ?string $state) { - $set('dns', null); $set('ip', null); + if (!$state) { + return; + } + [$subdomain] = str($state)->explode('.', 2); if (!is_numeric($subdomain)) { $set('name', $subdomain); } - if (!$state || is_ip($state)) { - $set('dns', null); - - return; - } - - $ip = get_ip_from_hostname($state); - if ($ip) { - $set('dns', true); - - $set('ip', $ip); - } else { - $set('dns', false); + if (!is_ip($state)) { + $ip = get_ip_from_hostname($state); + if (is_ip($ip)) { + $set('ip', $ip); + } else { + $set('ip', null); + } } }) ->maxLength(255), - - TextInput::make('ip') - ->disabled() - ->hidden(), - - ToggleButtons::make('dns') - ->label(trans('admin/node.dns')) - ->helperText(trans('admin/node.dns_help')) - ->disabled() - ->inline() - ->default(null) - ->hint(fn (Get $get) => $get('ip')) - ->hintColor('success') - ->options([ - true => trans('admin/node.valid'), - false => trans('admin/node.invalid'), - ]) - ->colors([ - true => 'success', - false => 'danger', - ]) - ->columnSpan([ - 'default' => 1, - 'sm' => 1, - 'md' => 1, - 'lg' => 1, - ]), - + Hidden::make('ip') + ->saved(false), TextInput::make('daemon_connect') ->columnSpan(1) ->label(fn (Get $get) => $get('connection') === 'https_proxy' ? trans('admin/node.connect_port') : trans('admin/node.port')) @@ -160,7 +161,16 @@ class CreateNode extends CreateRecord ->default(8080) ->required() ->integer(), - + TextInput::make('daemon_listen') + ->columnSpan(1) + ->label(trans('admin/node.listen_port')) + ->helperText(trans('admin/node.listen_port_help')) + ->minValue(1) + ->maxValue(65535) + ->default(8080) + ->required() + ->integer() + ->visible(fn (Get $get) => $get('connection') === 'https_proxy'), TextInput::make('name') ->label(trans('admin/node.display_name')) ->columnSpan([ @@ -171,27 +181,16 @@ class CreateNode extends CreateRecord ]) ->required() ->maxLength(100), - - Hidden::make('scheme') - ->default(fn () => request()->isSecure() ? 'https' : 'http'), - - Hidden::make('behind_proxy') - ->default(false), - ToggleButtons::make('connection') ->label(trans('admin/node.ssl')) - ->columnSpan(1) + ->columnSpan(2) ->inline() - ->helperText(function (Get $get) { + ->helperText(function () { if (request()->isSecure()) { - return new HtmlString(trans('admin/node.panel_on_ssl')); + return trans('admin/node.panel_on_ssl'); } - if (is_ip($get('fqdn'))) { - return trans('admin/node.ssl_help'); - } - - return ''; + return null; }) ->disableOptionWhen(fn (string $value) => $value === 'http' && request()->isSecure()) ->options([ @@ -219,17 +218,10 @@ class CreateNode extends CreateRecord $set('daemon_connect', $state === 'https_proxy' ? 443 : 8080); $set('daemon_listen', 8080); }), - - TextInput::make('daemon_listen') - ->columnSpan(1) - ->label(trans('admin/node.listen_port')) - ->helperText(trans('admin/node.listen_port_help')) - ->minValue(1) - ->maxValue(65535) - ->default(8080) - ->required() - ->integer() - ->visible(fn (Get $get) => $get('connection') === 'https_proxy'), + Hidden::make('scheme') + ->default(fn () => request()->isSecure() ? 'https' : 'http'), + Hidden::make('behind_proxy') + ->default(false), ]), Step::make('advanced') ->label(trans('admin/node.tabs.advanced_settings')) diff --git a/app/Filament/Admin/Resources/Nodes/Pages/EditNode.php b/app/Filament/Admin/Resources/Nodes/Pages/EditNode.php index 8d2c50684..eb3b8e7f3 100644 --- a/app/Filament/Admin/Resources/Nodes/Pages/EditNode.php +++ b/app/Filament/Admin/Resources/Nodes/Pages/EditNode.php @@ -137,74 +137,83 @@ class EditNode extends EditRecord ->autofocus() ->live(debounce: 1500) ->rules(Node::getRulesForField('fqdn')) - ->prohibited(fn ($state) => is_ip($state) && request()->isSecure()) ->label(fn ($state) => is_ip($state) ? trans('admin/node.ip_address') : trans('admin/node.domain')) ->placeholder(fn ($state) => is_ip($state) ? '192.168.1.1' : 'node.example.com') - ->helperText(function ($state) { + ->helperText(fn () => request()->isSecure() ? trans('admin/node.fqdn_ssl') : null) + ->validationMessages([ + 'prohibited' => trans('admin/node.dns_error'), + ]) + ->prohibited(function ($state, Get $get) { + if (!$state) { + return true; + } + + if (is_ip($state)) { + return false; + } + + $ip = $get('ip'); + + return !is_ip($ip); + }) + ->hintColor(function ($state, Get $get) { + if (!$state) { + return null; + } + if (is_ip($state)) { if (request()->isSecure()) { - return trans('admin/node.fqdn_help'); + return 'warning'; } + } else { + $ip = $get('ip'); - return ''; + return is_ip($ip) ? 'success' : 'danger'; } - return trans('admin/node.error'); + return null; }) - ->hintColor('danger') - ->hint(function ($state) { - if (is_ip($state) && request()->isSecure()) { - return trans('admin/node.ssl_ip'); + ->hint(function ($state, Get $get) { + if (!$state) { + return null; } - return ''; + if (is_ip($state)) { + if (request()->isSecure()) { + return trans('admin/node.ssl_ip'); + } + } else { + $ip = $get('ip'); + + return is_ip($ip) ? trans('admin/node.valid') . ': ' . $ip : trans('admin/node.invalid'); + } + + return null; }) ->afterStateUpdated(function (Set $set, ?string $state) { - $set('dns', null); $set('ip', null); + if (!$state) { + return; + } + [$subdomain] = str($state)->explode('.', 2); if (!is_numeric($subdomain)) { $set('name', $subdomain); } - if (!$state || is_ip($state)) { - $set('dns', null); - - return; - } - - $ip = get_ip_from_hostname($state); - if ($ip) { - $set('dns', true); - - $set('ip', $ip); - } else { - $set('dns', false); + if (!is_ip($state)) { + $ip = get_ip_from_hostname($state); + if (is_ip($ip)) { + $set('ip', $ip); + } else { + $set('ip', null); + } } }) ->maxLength(255), - TextInput::make('ip') - ->disabled() - ->hidden(), - ToggleButtons::make('dns') - ->label(trans('admin/node.dns')) - ->helperText(trans('admin/node.dns_help')) - ->disabled() - ->inline() - ->default(null) - ->hint(fn (Get $get) => $get('ip')) - ->hintColor('success') - ->stateCast(new BooleanStateCast(false, true)) - ->options([ - 1 => trans('admin/node.valid'), - 0 => trans('admin/node.invalid'), - ]) - ->colors([ - 1 => 'success', - 0 => 'danger', - ]) - ->columnSpan(1), + Hidden::make('ip') + ->saved(false), TextInput::make('daemon_connect') ->columnSpan(1) ->label(fn (Get $get) => $get('connection') === 'https_proxy' ? trans('admin/node.connect_port') : trans('admin/node.port')) @@ -214,6 +223,16 @@ class EditNode extends EditRecord ->default(8080) ->required() ->integer(), + TextInput::make('daemon_listen') + ->columnSpan(1) + ->label(trans('admin/node.listen_port')) + ->helperText(trans('admin/node.listen_port_help')) + ->minValue(1) + ->maxValue(65535) + ->default(8080) + ->required() + ->integer() + ->visible(fn (Get $get) => $get('connection') === 'https_proxy'), TextInput::make('name') ->label(trans('admin/node.display_name')) ->columnSpan([ @@ -224,22 +243,16 @@ class EditNode extends EditRecord ]) ->required() ->maxLength(100), - Hidden::make('scheme'), - Hidden::make('behind_proxy'), ToggleButtons::make('connection') ->label(trans('admin/node.ssl')) - ->columnSpan(1) + ->columnSpan(2) ->inline() - ->helperText(function (Get $get) { + ->helperText(function () { if (request()->isSecure()) { - return new HtmlString(trans('admin/node.panel_on_ssl')); + return trans('admin/node.panel_on_ssl'); } - if (is_ip($get('fqdn'))) { - return trans('admin/node.ssl_help'); - } - - return ''; + return null; }) ->disableOptionWhen(fn (string $value) => $value === 'http' && request()->isSecure()) ->options([ @@ -267,16 +280,10 @@ class EditNode extends EditRecord $set('daemon_connect', $state === 'https_proxy' ? 443 : 8080); $set('daemon_listen', 8080); }), - TextInput::make('daemon_listen') - ->columnSpan(1) - ->label(trans('admin/node.listen_port')) - ->helperText(trans('admin/node.listen_port_help')) - ->minValue(1) - ->maxValue(65535) - ->default(8080) - ->required() - ->integer() - ->visible(fn (Get $get) => $get('connection') === 'https_proxy'), + Hidden::make('scheme') + ->default(fn () => request()->isSecure() ? 'https' : 'http'), + Hidden::make('behind_proxy') + ->default(false), ]), Tab::make('advanced_settings') ->label(trans('admin/node.tabs.advanced_settings')) diff --git a/lang/en/admin/node.php b/lang/en/admin/node.php index 918171a04..ab688c773 100644 --- a/lang/en/admin/node.php +++ b/lang/en/admin/node.php @@ -42,13 +42,11 @@ return [ 'refresh' => 'Refresh', 'custom_ip' => 'Enter Custom IP', 'domain' => 'Domain Name', - 'ssl_ip' => 'You cannot connect to an IP Address over SSL', - 'error' => 'This is the domain name that points to your node\'s IP Address. If you\'ve already set up this, you can verify it by checking the next field!', - 'fqdn_help' => 'Your panel is currently secured via an SSL certificate and that means your nodes require one too. You must use a domain name, because you cannot get SSL certificates for IP Addresses.', - 'dns' => 'DNS Record Check', - 'dns_help' => 'This lets you know if your DNS record is pointing to the correct IP address.', - 'valid' => 'Valid', - 'invalid' => 'Invalid', + 'ssl_ip' => 'Consider using a domain name instead of an ip address', + 'fqdn_ssl' => 'Your panel is currently secured via an SSL certificate and that means your nodes require one too.', + 'dns_error' => 'No valid DNS records were found for the provided domain name.', + 'valid' => 'Valid DNS', + 'invalid' => 'Invalid DNS', 'port' => 'Port', 'ports' => 'Ports', 'port_help' => 'If you are running the daemon behind Cloudflare you should set the daemon port to 8443 to allow websocket proxying over SSL.', @@ -58,7 +56,7 @@ return [ 'listen_port_help' => 'Wings will listen on this port.', 'display_name' => 'Display Name', 'ssl' => 'Communicate over SSL', - 'panel_on_ssl' => 'Your Panel is using a secure SSL connection,
so your Daemon must too.', + 'panel_on_ssl' => 'Your Panel is using a secure SSL connection, so your Daemon must too.', 'ssl_help' => 'An IP address cannot use SSL.', 'tags' => 'Tags',