refactor(ui): separate views for instance settings to separate paths to make it cleaner

This commit is contained in:
Andras Bacsai
2025-06-30 08:50:17 +02:00
parent d37369dcaf
commit 90817914d9
36 changed files with 647 additions and 402 deletions

View File

@@ -0,0 +1,119 @@
<?php
namespace App\Livewire\Settings;
use App\Models\InstanceSettings;
use App\Models\Server;
use Auth;
use Hash;
use Livewire\Attributes\Validate;
use Livewire\Component;
class Advanced extends Component
{
#[Validate('required')]
public Server $server;
public InstanceSettings $settings;
#[Validate('boolean')]
public bool $is_registration_enabled;
#[Validate('boolean')]
public bool $do_not_track;
#[Validate('boolean')]
public bool $is_dns_validation_enabled;
#[Validate('nullable|string')]
public ?string $custom_dns_servers = null;
#[Validate('boolean')]
public bool $is_api_enabled;
#[Validate('nullable|string')]
public ?string $allowed_ips = null;
#[Validate('boolean')]
public bool $is_sponsorship_popup_enabled;
#[Validate('boolean')]
public bool $disable_two_step_confirmation;
public function mount()
{
if (! isInstanceAdmin()) {
return redirect()->route('dashboard');
} else {
$this->server = Server::findOrFail(0);
$this->settings = instanceSettings();
$this->custom_dns_servers = $this->settings->custom_dns_servers;
$this->allowed_ips = $this->settings->allowed_ips;
$this->do_not_track = $this->settings->do_not_track;
$this->is_registration_enabled = $this->settings->is_registration_enabled;
$this->is_dns_validation_enabled = $this->settings->is_dns_validation_enabled;
$this->is_api_enabled = $this->settings->is_api_enabled;
$this->disable_two_step_confirmation = $this->settings->disable_two_step_confirmation;
$this->is_sponsorship_popup_enabled = $this->settings->is_sponsorship_popup_enabled;
}
}
public function submit()
{
try {
$this->validate();
$this->custom_dns_servers = str($this->custom_dns_servers)->replaceEnd(',', '')->trim();
$this->custom_dns_servers = str($this->custom_dns_servers)->trim()->explode(',')->map(function ($dns) {
return str($dns)->trim()->lower();
})->unique()->implode(',');
$this->allowed_ips = str($this->allowed_ips)->replaceEnd(',', '')->trim();
$this->allowed_ips = str($this->allowed_ips)->trim()->explode(',')->map(function ($ip) {
return str($ip)->trim();
})->unique()->implode(',');
$this->instantSave();
} catch (\Exception $e) {
return handleError($e, $this);
}
}
public function instantSave()
{
try {
$this->settings->is_registration_enabled = $this->is_registration_enabled;
$this->settings->do_not_track = $this->do_not_track;
$this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled;
$this->settings->custom_dns_servers = $this->custom_dns_servers;
$this->settings->is_api_enabled = $this->is_api_enabled;
$this->settings->allowed_ips = $this->allowed_ips;
$this->settings->is_sponsorship_popup_enabled = $this->is_sponsorship_popup_enabled;
$this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation;
$this->settings->save();
$this->dispatch('success', 'Settings updated!');
} catch (\Exception $e) {
return handleError($e, $this);
}
}
public function toggleTwoStepConfirmation($password): bool
{
if (! Hash::check($password, Auth::user()->password)) {
$this->addError('password', 'The provided password is incorrect.');
return false;
}
$this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation = true;
$this->settings->save();
$this->dispatch('success', 'Two step confirmation has been disabled.');
return true;
}
public function render()
{
return view('livewire.settings.advanced');
}
}

View File

@@ -2,11 +2,8 @@
namespace App\Livewire\Settings;
use App\Jobs\CheckForUpdatesJob;
use App\Models\InstanceSettings;
use App\Models\Server;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Validate;
use Livewire\Component;
@@ -15,10 +12,7 @@ class Index extends Component
{
public InstanceSettings $settings;
protected Server $server;
#[Validate('boolean')]
public bool $is_auto_update_enabled;
public Server $server;
#[Validate('nullable|string|max:255')]
public ?string $fqdn = null;
@@ -29,48 +23,18 @@ class Index extends Component
#[Validate('required|integer|min:1025|max:65535')]
public int $public_port_max;
#[Validate('nullable|string')]
public ?string $custom_dns_servers = null;
#[Validate('nullable|string|max:255')]
public ?string $instance_name = null;
#[Validate('nullable|string')]
public ?string $allowed_ips = null;
#[Validate('nullable|string')]
public ?string $public_ipv4 = null;
#[Validate('nullable|string')]
public ?string $public_ipv6 = null;
#[Validate('string')]
public string $auto_update_frequency;
#[Validate('string|required')]
public string $update_check_frequency;
#[Validate('required|string|timezone')]
public string $instance_timezone;
#[Validate('boolean')]
public bool $do_not_track;
#[Validate('boolean')]
public bool $is_registration_enabled;
#[Validate('boolean')]
public bool $is_dns_validation_enabled;
#[Validate('boolean')]
public bool $is_api_enabled;
#[Validate('boolean')]
public bool $disable_two_step_confirmation;
#[Validate('boolean')]
public bool $is_sponsorship_popup_enabled;
public function render()
{
return view('livewire.settings.index');
@@ -82,24 +46,14 @@ class Index extends Component
return redirect()->route('dashboard');
} else {
$this->settings = instanceSettings();
$this->server = Server::findOrFail(0);
$this->fqdn = $this->settings->fqdn;
$this->public_port_min = $this->settings->public_port_min;
$this->public_port_max = $this->settings->public_port_max;
$this->custom_dns_servers = $this->settings->custom_dns_servers;
$this->instance_name = $this->settings->instance_name;
$this->allowed_ips = $this->settings->allowed_ips;
$this->public_ipv4 = $this->settings->public_ipv4;
$this->public_ipv6 = $this->settings->public_ipv6;
$this->do_not_track = $this->settings->do_not_track;
$this->is_auto_update_enabled = $this->settings->is_auto_update_enabled;
$this->is_registration_enabled = $this->settings->is_registration_enabled;
$this->is_dns_validation_enabled = $this->settings->is_dns_validation_enabled;
$this->is_api_enabled = $this->settings->is_api_enabled;
$this->auto_update_frequency = $this->settings->auto_update_frequency;
$this->update_check_frequency = $this->settings->update_check_frequency;
$this->instance_timezone = $this->settings->instance_timezone;
$this->disable_two_step_confirmation = $this->settings->disable_two_step_confirmation;
$this->is_sponsorship_popup_enabled = $this->settings->is_sponsorship_popup_enabled;
}
}
@@ -115,30 +69,13 @@ class Index extends Component
public function instantSave($isSave = true)
{
$this->validate();
if ($this->settings->is_auto_update_enabled === true) {
$this->validate([
'auto_update_frequency' => ['required', 'string'],
]);
}
$this->settings->fqdn = $this->fqdn;
$this->settings->public_port_min = $this->public_port_min;
$this->settings->public_port_max = $this->public_port_max;
$this->settings->custom_dns_servers = $this->custom_dns_servers;
$this->settings->instance_name = $this->instance_name;
$this->settings->allowed_ips = $this->allowed_ips;
$this->settings->public_ipv4 = $this->public_ipv4;
$this->settings->public_ipv6 = $this->public_ipv6;
$this->settings->do_not_track = $this->do_not_track;
$this->settings->is_auto_update_enabled = $this->is_auto_update_enabled;
$this->settings->is_registration_enabled = $this->is_registration_enabled;
$this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled;
$this->settings->is_api_enabled = $this->is_api_enabled;
$this->settings->auto_update_frequency = $this->auto_update_frequency;
$this->settings->update_check_frequency = $this->update_check_frequency;
$this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation;
$this->settings->instance_timezone = $this->instance_timezone;
$this->settings->is_sponsorship_popup_enabled = $this->is_sponsorship_popup_enabled;
if ($isSave) {
$this->settings->save();
$this->dispatch('success', 'Settings updated!');
@@ -149,7 +86,6 @@ class Index extends Component
{
try {
$error_show = false;
$this->server = Server::findOrFail(0);
$this->resetErrorBag();
if (! validate_timezone($this->instance_timezone)) {
@@ -166,46 +102,15 @@ class Index extends Component
}
$this->validate();
if ($this->is_auto_update_enabled && ! validate_cron_expression($this->auto_update_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.');
if (empty($this->auto_update_frequency)) {
$this->auto_update_frequency = '0 0 * * *';
}
return;
}
if (! validate_cron_expression($this->update_check_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.');
if (empty($this->update_check_frequency)) {
$this->update_check_frequency = '0 * * * *';
}
return;
}
if ($this->settings->is_dns_validation_enabled && $this->settings->fqdn) {
if (! validate_dns_entry($this->settings->fqdn, $this->server)) {
$this->dispatch('error', "Validating DNS failed.<br><br>Make sure you have added the DNS records correctly.<br><br>{$this->settings->fqdn}->{$this->server->ip}<br><br>Check this <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/dns-configuration'>documentation</a> for further help.");
if ($this->settings->is_dns_validation_enabled && $this->fqdn) {
if (! validate_dns_entry($this->fqdn, $this->server)) {
$this->dispatch('error', "Validating DNS failed.<br><br>Make sure you have added the DNS records correctly.<br><br>{$this->fqdn}->{$this->server->ip}<br><br>Check this <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/dns-configuration'>documentation</a> for further help.");
$error_show = true;
}
}
if ($this->settings->fqdn) {
check_domain_usage(domain: $this->settings->fqdn);
if ($this->fqdn) {
check_domain_usage(domain: $this->fqdn);
}
$this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->replaceEnd(',', '')->trim();
$this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->trim()->explode(',')->map(function ($dns) {
return str($dns)->trim()->lower();
});
$this->settings->custom_dns_servers = $this->settings->custom_dns_servers->unique();
$this->settings->custom_dns_servers = $this->settings->custom_dns_servers->implode(',');
$this->settings->allowed_ips = str($this->settings->allowed_ips)->replaceEnd(',', '')->trim();
$this->settings->allowed_ips = str($this->settings->allowed_ips)->trim()->explode(',')->map(function ($ip) {
return str($ip)->trim();
});
$this->settings->allowed_ips = $this->settings->allowed_ips->unique();
$this->settings->allowed_ips = $this->settings->allowed_ips->implode(',');
$this->instantSave(isSave: false);
@@ -218,31 +123,4 @@ class Index extends Component
return handleError($e, $this);
}
}
public function checkManually()
{
CheckForUpdatesJob::dispatchSync();
$this->dispatch('updateAvailable');
$settings = instanceSettings();
if ($settings->new_version_available) {
$this->dispatch('success', 'New version available!');
} else {
$this->dispatch('success', 'No new version available.');
}
}
public function toggleTwoStepConfirmation($password): bool
{
if (! Hash::check($password, Auth::user()->password)) {
$this->addError('password', 'The provided password is incorrect.');
return false;
}
$this->settings->disable_two_step_confirmation = $this->disable_two_step_confirmation = true;
$this->settings->save();
$this->dispatch('success', 'Two step confirmation has been disabled.');
return true;
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace App\Livewire\Settings;
use App\Jobs\CheckForUpdatesJob;
use App\Models\InstanceSettings;
use App\Models\Server;
use Livewire\Attributes\Validate;
use Livewire\Component;
class Updates extends Component
{
public InstanceSettings $settings;
public Server $server;
#[Validate('string')]
public string $auto_update_frequency;
#[Validate('string|required')]
public string $update_check_frequency;
#[Validate('boolean')]
public bool $is_auto_update_enabled;
public function mount()
{
$this->server = Server::findOrFail(0);
$this->settings = instanceSettings();
$this->auto_update_frequency = $this->settings->auto_update_frequency;
$this->update_check_frequency = $this->settings->update_check_frequency;
$this->is_auto_update_enabled = $this->settings->is_auto_update_enabled;
}
public function instantSave()
{
try {
if ($this->settings->is_auto_update_enabled === true) {
$this->validate([
'auto_update_frequency' => ['required', 'string'],
]);
}
$this->settings->auto_update_frequency = $this->auto_update_frequency;
$this->settings->update_check_frequency = $this->update_check_frequency;
$this->settings->is_auto_update_enabled = $this->is_auto_update_enabled;
$this->settings->save();
$this->dispatch('success', 'Settings updated!');
} catch (\Exception $e) {
return handleError($e, $this);
}
}
public function submit()
{
try {
$this->resetErrorBag();
$this->validate();
if ($this->is_auto_update_enabled && ! validate_cron_expression($this->auto_update_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.');
if (empty($this->auto_update_frequency)) {
$this->auto_update_frequency = '0 0 * * *';
}
return;
}
if (! validate_cron_expression($this->update_check_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.');
if (empty($this->update_check_frequency)) {
$this->update_check_frequency = '0 * * * *';
}
return;
}
$this->instantSave();
$this->server->setupDynamicProxyConfiguration();
} catch (\Exception $e) {
return handleError($e, $this);
}
}
public function checkManually()
{
CheckForUpdatesJob::dispatchSync();
$this->dispatch('updateAvailable');
$settings = instanceSettings();
if ($settings->new_version_available) {
$this->dispatch('success', 'New version available!');
} else {
$this->dispatch('success', 'No new version available.');
}
}
public function render()
{
return view('livewire.settings.updates');
}
}

View File

@@ -31,7 +31,7 @@ class Form extends Component
'storage.endpoint' => 'Endpoint',
];
public function test_s3_connection()
public function testConnection()
{
try {
$this->storage->testConnection(shouldSave: true);
@@ -45,6 +45,8 @@ class Form extends Component
public function delete()
{
try {
$this->authorize('delete', $this->storage);
$this->storage->delete();
return redirect()->route('storage.index');
@@ -57,7 +59,7 @@ class Form extends Component
{
$this->validate();
try {
$this->test_s3_connection();
$this->testConnection();
} catch (\Throwable $e) {
return handleError($e, $this);
}

View File

@@ -0,0 +1,66 @@
<?php
namespace App\Policies;
use App\Models\S3Storage;
use App\Models\Server;
use App\Models\User;
class S3StoragePolicy
{
/**
* Determine whether the user can view any models.
*/
public function viewAny(User $user): bool
{
return true;
}
/**
* Determine whether the user can view the model.
*/
public function view(User $user, S3Storage $storage): bool
{
return $user->teams()->get()->firstWhere('id', $storage->team_id) !== null;
}
/**
* Determine whether the user can create models.
*/
public function create(User $user): bool
{
return true;
}
/**
* Determine whether the user can update the model.
*/
public function update(User $user, Server $server): bool
{
return $user->teams()->get()->firstWhere('id', $server->team_id) !== null;
}
/**
* Determine whether the user can delete the model.
*/
public function delete(User $user, S3Storage $storage): bool
{
return $user->teams()->get()->firstWhere('id', $storage->team_id) !== null;
}
/**
* Determine whether the user can restore the model.
*/
public function restore(User $user, S3Storage $storage): bool
{
return false;
}
/**
* Determine whether the user can permanently delete the model.
*/
public function forceDelete(User $user, S3Storage $storage): bool
{
return false;
}
}