fix: settings view

feat: add separate views for settings
This commit is contained in:
Andras Bacsai
2024-08-06 14:36:56 +02:00
parent c4436aadfa
commit b77171d2f2
13 changed files with 301 additions and 334 deletions

View File

@@ -1,51 +0,0 @@
<?php
namespace App\Livewire\Settings;
use App\Models\OauthSetting;
use Livewire\Component;
class Auth extends Component
{
public $oauth_settings_map;
protected function rules()
{
return OauthSetting::all()->reduce(function ($carry, $setting) {
$carry["oauth_settings_map.$setting->provider.enabled"] = 'required';
$carry["oauth_settings_map.$setting->provider.client_id"] = 'nullable';
$carry["oauth_settings_map.$setting->provider.client_secret"] = 'nullable';
$carry["oauth_settings_map.$setting->provider.redirect_uri"] = 'nullable';
$carry["oauth_settings_map.$setting->provider.tenant"] = 'nullable';
return $carry;
}, []);
}
public function mount()
{
$this->oauth_settings_map = OauthSetting::all()->sortBy('provider')->reduce(function ($carry, $setting) {
$carry[$setting->provider] = $setting;
return $carry;
}, []);
}
private function updateOauthSettings()
{
foreach (array_values($this->oauth_settings_map) as &$setting) {
$setting->save();
}
}
public function instantSave()
{
$this->updateOauthSettings();
}
public function submit()
{
$this->updateOauthSettings();
$this->dispatch('success', 'Instance settings updated successfully!');
}
}

View File

@@ -1,97 +0,0 @@
<?php
namespace App\Livewire\Settings;
use App\Jobs\DatabaseBackupJob;
use App\Models\InstanceSettings;
use App\Models\S3Storage;
use App\Models\ScheduledDatabaseBackup;
use App\Models\Server;
use App\Models\StandalonePostgresql;
use Livewire\Component;
class Backup extends Component
{
public InstanceSettings $settings;
public $s3s;
public StandalonePostgresql|null|array $database = [];
public ScheduledDatabaseBackup|null|array $backup = [];
public $executions = [];
protected $rules = [
'database.uuid' => 'required',
'database.name' => 'required',
'database.description' => 'nullable',
'database.postgres_user' => 'required',
'database.postgres_password' => 'required',
];
protected $validationAttributes = [
'database.uuid' => 'uuid',
'database.name' => 'name',
'database.description' => 'description',
'database.postgres_user' => 'postgres user',
'database.postgres_password' => 'postgres password',
];
public function mount()
{
$this->backup = $this->database?->scheduledBackups->first() ?? null;
$this->executions = $this->backup?->executions ?? [];
}
public function add_coolify_database()
{
try {
$server = Server::findOrFail(0);
$out = instant_remote_process(['docker inspect coolify-db'], $server);
$envs = format_docker_envs_to_json($out);
$postgres_password = $envs['POSTGRES_PASSWORD'];
$postgres_user = $envs['POSTGRES_USER'];
$postgres_db = $envs['POSTGRES_DB'];
$this->database = StandalonePostgresql::create([
'id' => 0,
'name' => 'coolify-db',
'description' => 'Coolify database',
'postgres_user' => $postgres_user,
'postgres_password' => $postgres_password,
'postgres_db' => $postgres_db,
'status' => 'running',
'destination_type' => 'App\Models\StandaloneDocker',
'destination_id' => 0,
]);
$this->backup = ScheduledDatabaseBackup::create([
'id' => 0,
'enabled' => true,
'save_s3' => false,
'frequency' => '0 0 * * *',
'database_id' => $this->database->id,
'database_type' => 'App\Models\StandalonePostgresql',
'team_id' => currentTeam()->id,
]);
$this->database->refresh();
$this->backup->refresh();
$this->s3s = S3Storage::whereTeamId(0)->get();
} catch (\Exception $e) {
return handleError($e, $this);
}
}
public function backup_now()
{
dispatch(new DatabaseBackupJob(
backup: $this->backup
));
$this->dispatch('success', 'Backup queued. It will be available in a few minutes.');
}
public function submit()
{
$this->dispatch('success', 'Backup updated.');
}
}

View File

@@ -1,177 +0,0 @@
<?php
namespace App\Livewire\Settings;
use App\Models\InstanceSettings as ModelsInstanceSettings;
use App\Models\Server;
use Livewire\Component;
use Cron\CronExpression;
class Configuration extends Component
{
public ModelsInstanceSettings $settings;
public bool $do_not_track;
public bool $is_auto_update_enabled;
public bool $is_registration_enabled;
public bool $is_dns_validation_enabled;
public bool $is_api_enabled;
public string $auto_update_frequency;
public string $update_check_frequency;
protected string $dynamic_config_path = '/data/coolify/proxy/dynamic';
protected Server $server;
protected $rules = [
'settings.fqdn' => 'nullable',
'settings.resale_license' => 'nullable',
'settings.public_port_min' => 'required',
'settings.public_port_max' => 'required',
'settings.custom_dns_servers' => 'nullable',
'settings.instance_name' => 'nullable',
'settings.allowed_ips' => 'nullable',
'settings.is_auto_update_enabled' => 'boolean',
'auto_update_frequency' => 'nullable|string',
'update_check_frequency' => 'nullable|string',
];
protected $validationAttributes = [
'settings.fqdn' => 'FQDN',
'settings.resale_license' => 'Resale License',
'settings.public_port_min' => 'Public port min',
'settings.public_port_max' => 'Public port max',
'settings.custom_dns_servers' => 'Custom DNS servers',
'settings.allowed_ips' => 'Allowed IPs',
'settings.is_auto_update_enabled' => 'Auto Update Enabled',
'auto_update_frequency' => 'Auto Update Frequency',
'update_check_frequency' => 'Update Check Frequency',
];
public function mount()
{
$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;
}
public function instantSave()
{
$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->save();
$this->dispatch('success', 'Settings updated!');
}
public function submit()
{
try {
$error_show = false;
$this->server = Server::findOrFail(0);
$this->resetErrorBag();
if ($this->settings->public_port_min > $this->settings->public_port_max) {
$this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.');
return;
}
$this->validate();
if ($this->is_auto_update_enabled && !$this->validateCronExpression($this->auto_update_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.');
return;
}
if (!$this->validateCronExpression($this->update_check_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.');
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.");
$error_show = true;
}
}
if ($this->settings->fqdn) {
check_domain_usage(domain: $this->settings->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->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->save();
$this->server->setupDynamicProxyConfiguration();
if (! $error_show) {
$this->dispatch('success', 'Instance settings updated successfully!');
}
} catch (\Exception $e) {
return handleError($e, $this);
}
}
private function validateCronExpression($expression): bool
{
if (empty($expression)) {
return true;
}
$isValid = false;
try {
$cronExpression = new CronExpression($expression);
$isValid = $cronExpression->getNextRunDate() !== false;
} catch (\Exception $e) {
$isValid = false;
}
if (isset(VALID_CRON_STRINGS[$expression])) {
$isValid = true;
}
return $isValid;
}
public function updatedAutoUpdateFrequency()
{
if (!$this->validateCronExpression($this->auto_update_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.');
}
}
public function updatedUpdateCheckFrequency()
{
if (!$this->validateCronExpression($this->update_check_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.');
}
}
}

View File

@@ -1,127 +0,0 @@
<?php
namespace App\Livewire\Settings;
use App\Models\InstanceSettings;
use App\Notifications\TransactionalEmails\Test;
use Livewire\Component;
class Email extends Component
{
public InstanceSettings $settings;
public string $emails;
protected $rules = [
'settings.smtp_enabled' => 'nullable|boolean',
'settings.smtp_host' => 'required',
'settings.smtp_port' => 'required|numeric',
'settings.smtp_encryption' => 'nullable',
'settings.smtp_username' => 'nullable',
'settings.smtp_password' => 'nullable',
'settings.smtp_timeout' => 'nullable',
'settings.smtp_from_address' => 'required|email',
'settings.smtp_from_name' => 'required',
'settings.resend_enabled' => 'nullable|boolean',
'settings.resend_api_key' => 'nullable',
];
protected $validationAttributes = [
'settings.smtp_from_address' => 'From Address',
'settings.smtp_from_name' => 'From Name',
'settings.smtp_recipients' => 'Recipients',
'settings.smtp_host' => 'Host',
'settings.smtp_port' => 'Port',
'settings.smtp_encryption' => 'Encryption',
'settings.smtp_username' => 'Username',
'settings.smtp_password' => 'Password',
'settings.smtp_timeout' => 'Timeout',
'settings.resend_api_key' => 'Resend API Key',
];
public function mount()
{
$this->emails = auth()->user()->email;
}
public function submitFromFields()
{
try {
$this->resetErrorBag();
$this->validate([
'settings.smtp_from_address' => 'required|email',
'settings.smtp_from_name' => 'required',
]);
$this->settings->save();
$this->dispatch('success', 'Settings saved.');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function submitResend()
{
try {
$this->resetErrorBag();
$this->validate([
'settings.smtp_from_address' => 'required|email',
'settings.smtp_from_name' => 'required',
'settings.resend_api_key' => 'required',
]);
$this->settings->save();
$this->dispatch('success', 'Settings saved.');
} catch (\Throwable $e) {
$this->settings->resend_enabled = false;
return handleError($e, $this);
}
}
public function instantSaveResend()
{
try {
$this->settings->smtp_enabled = false;
$this->submitResend();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function instantSave()
{
try {
$this->settings->resend_enabled = false;
$this->submit();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function submit()
{
try {
$this->resetErrorBag();
$this->validate([
'settings.smtp_from_address' => 'required|email',
'settings.smtp_from_name' => 'required',
'settings.smtp_host' => 'required',
'settings.smtp_port' => 'required|numeric',
'settings.smtp_encryption' => 'nullable',
'settings.smtp_username' => 'nullable',
'settings.smtp_password' => 'nullable',
'settings.smtp_timeout' => 'nullable',
]);
$this->settings->save();
$this->dispatch('success', 'Settings saved.');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function sendTestNotification()
{
$this->settings?->notify(new Test($this->emails));
$this->dispatch('success', 'Test email sent.');
}
}

View File

@@ -3,38 +3,185 @@
namespace App\Livewire\Settings;
use App\Models\InstanceSettings;
use App\Models\S3Storage;
use App\Models\StandalonePostgresql;
use App\Models\Server;
use Cron\CronExpression;
use Livewire\Component;
class Index extends Component
{
public InstanceSettings $settings;
public StandalonePostgresql $database;
public bool $do_not_track;
public $s3s;
public bool $is_auto_update_enabled;
public bool $is_registration_enabled;
public bool $is_dns_validation_enabled;
public bool $is_api_enabled;
public string $auto_update_frequency;
public string $update_check_frequency;
protected string $dynamic_config_path = '/data/coolify/proxy/dynamic';
protected Server $server;
protected $rules = [
'settings.fqdn' => 'nullable',
'settings.resale_license' => 'nullable',
'settings.public_port_min' => 'required',
'settings.public_port_max' => 'required',
'settings.custom_dns_servers' => 'nullable',
'settings.instance_name' => 'nullable',
'settings.allowed_ips' => 'nullable',
'settings.is_auto_update_enabled' => 'boolean',
'auto_update_frequency' => 'nullable|string',
'update_check_frequency' => 'nullable|string',
];
protected $validationAttributes = [
'settings.fqdn' => 'FQDN',
'settings.resale_license' => 'Resale License',
'settings.public_port_min' => 'Public port min',
'settings.public_port_max' => 'Public port max',
'settings.custom_dns_servers' => 'Custom DNS servers',
'settings.allowed_ips' => 'Allowed IPs',
'settings.is_auto_update_enabled' => 'Auto Update Enabled',
'auto_update_frequency' => 'Auto Update Frequency',
'update_check_frequency' => 'Update Check Frequency',
];
public function mount()
{
if (isInstanceAdmin()) {
$settings = \App\Models\InstanceSettings::get();
$database = StandalonePostgresql::whereName('coolify-db')->first();
$s3s = S3Storage::whereTeamId(0)->get() ?? [];
if ($database) {
if ($database->status !== 'running') {
$database->status = 'running';
$database->save();
}
$this->database = $database;
}
$this->settings = $settings;
$this->s3s = $s3s;
$this->settings = InstanceSettings::get();
$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;
} else {
return redirect()->route('dashboard');
}
}
public function instantSave()
{
$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->save();
$this->dispatch('success', 'Settings updated!');
}
public function submit()
{
try {
$error_show = false;
$this->server = Server::findOrFail(0);
$this->resetErrorBag();
if ($this->settings->public_port_min > $this->settings->public_port_max) {
$this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.');
return;
}
$this->validate();
if ($this->is_auto_update_enabled && ! $this->validateCronExpression($this->auto_update_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.');
return;
}
if (! $this->validateCronExpression($this->update_check_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.');
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.");
$error_show = true;
}
}
if ($this->settings->fqdn) {
check_domain_usage(domain: $this->settings->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->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->save();
$this->server->setupDynamicProxyConfiguration();
if (! $error_show) {
$this->dispatch('success', 'Instance settings updated successfully!');
}
} catch (\Exception $e) {
return handleError($e, $this);
}
}
private function validateCronExpression($expression): bool
{
if (empty($expression)) {
return true;
}
$isValid = false;
try {
$cronExpression = new CronExpression($expression);
$isValid = $cronExpression->getNextRunDate() !== false;
} catch (\Exception $e) {
$isValid = false;
}
if (isset(VALID_CRON_STRINGS[$expression])) {
$isValid = true;
}
return $isValid;
}
public function updatedAutoUpdateFrequency()
{
if (! $this->validateCronExpression($this->auto_update_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.');
}
}
public function updatedUpdateCheckFrequency()
{
if (! $this->validateCronExpression($this->update_check_frequency)) {
$this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.');
}
}
public function render()
{
return view('livewire.settings.index');