diff --git a/app/Livewire/Settings/Advanced.php b/app/Livewire/Settings/Advanced.php
new file mode 100644
index 000000000..0456c6291
--- /dev/null
+++ b/app/Livewire/Settings/Advanced.php
@@ -0,0 +1,119 @@
+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');
+ }
+}
diff --git a/app/Livewire/Settings/Index.php b/app/Livewire/Settings/Index.php
index f9df7ee33..73ee37dbf 100644
--- a/app/Livewire/Settings/Index.php
+++ b/app/Livewire/Settings/Index.php
@@ -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.
Make sure you have added the DNS records correctly.
{$this->settings->fqdn}->{$this->server->ip}
Check this documentation 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.
Make sure you have added the DNS records correctly.
{$this->fqdn}->{$this->server->ip}
Check this documentation 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;
- }
}
diff --git a/app/Livewire/Settings/Updates.php b/app/Livewire/Settings/Updates.php
new file mode 100644
index 000000000..fe20763b6
--- /dev/null
+++ b/app/Livewire/Settings/Updates.php
@@ -0,0 +1,101 @@
+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');
+ }
+}
diff --git a/app/Livewire/Storage/Form.php b/app/Livewire/Storage/Form.php
index 8ca0020c7..ad1627863 100644
--- a/app/Livewire/Storage/Form.php
+++ b/app/Livewire/Storage/Form.php
@@ -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);
}
diff --git a/app/Policies/S3StoragePolicy.php b/app/Policies/S3StoragePolicy.php
new file mode 100644
index 000000000..9a8c435a3
--- /dev/null
+++ b/app/Policies/S3StoragePolicy.php
@@ -0,0 +1,66 @@
+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;
+ }
+}
diff --git a/resources/css/utilities.css b/resources/css/utilities.css
index fe0cd10ed..d09d7f49c 100644
--- a/resources/css/utilities.css
+++ b/resources/css/utilities.css
@@ -42,7 +42,7 @@
}
@utility button {
- @apply flex gap-2 justify-center items-center px-2 py-1 text-sm text-black normal-case rounded-sm border outline-0 cursor-pointer bg-neutral-200/50 border-neutral-300 hover:bg-neutral-300 dark:bg-coolgray-200 dark:text-white dark:hover:text-white dark:hover:bg-coolgray-500 dark:border-coolgray-300 hover:text-black disabled:cursor-not-allowed min-w-fit dark:disabled:text-neutral-600 disabled:border-none disabled:hover:bg-transparent disabled:bg-transparent disabled:text-neutral-300;
+ @apply flex gap-2 justify-center items-center px-2 py-1 text-sm text-black normal-case rounded-sm border outline-0 cursor-pointer bg-neutral-200/50 border-neutral-300 hover:bg-neutral-300 dark:bg-coolgray-200 dark:text-white dark:hover:text-white dark:hover:bg-coolgray-500 dark:border-coolgray-300 hover:text-black disabled:cursor-not-allowed min-w-fit dark:disabled:text-neutral-600 disabled:border-transparent disabled:hover:bg-transparent disabled:bg-transparent disabled:text-neutral-300;
}
@utility alert-success {
diff --git a/resources/views/components/settings/navbar.blade.php b/resources/views/components/settings/navbar.blade.php
index a54dc1886..395c0953e 100644
--- a/resources/views/components/settings/navbar.blade.php
+++ b/resources/views/components/settings/navbar.blade.php
@@ -5,19 +5,19 @@
diff --git a/resources/views/components/settings/sidebar.blade.php b/resources/views/components/settings/sidebar.blade.php
new file mode 100644
index 000000000..ef2f0d5d2
--- /dev/null
+++ b/resources/views/components/settings/sidebar.blade.php
@@ -0,0 +1,8 @@
+