198 lines
7.1 KiB
PHP
198 lines
7.1 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Settings;
|
|
|
|
use App\Models\InstanceSettings;
|
|
use App\Models\Server;
|
|
use App\Rules\ValidIpOrCidr;
|
|
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;
|
|
|
|
public ?string $allowed_ips = null;
|
|
|
|
#[Validate('boolean')]
|
|
public bool $is_sponsorship_popup_enabled;
|
|
|
|
#[Validate('boolean')]
|
|
public bool $disable_two_step_confirmation;
|
|
|
|
public function rules()
|
|
{
|
|
return [
|
|
'server' => 'required',
|
|
'is_registration_enabled' => 'boolean',
|
|
'do_not_track' => 'boolean',
|
|
'is_dns_validation_enabled' => 'boolean',
|
|
'custom_dns_servers' => 'nullable|string',
|
|
'is_api_enabled' => 'boolean',
|
|
'allowed_ips' => ['nullable', 'string', new ValidIpOrCidr],
|
|
'is_sponsorship_popup_enabled' => 'boolean',
|
|
'disable_two_step_confirmation' => 'boolean',
|
|
];
|
|
}
|
|
|
|
public function mount()
|
|
{
|
|
if (! isInstanceAdmin()) {
|
|
return redirect()->route('dashboard');
|
|
}
|
|
$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(',');
|
|
|
|
// Handle allowed IPs with subnet support and 0.0.0.0 special case
|
|
$this->allowed_ips = str($this->allowed_ips)->replaceEnd(',', '')->trim();
|
|
|
|
// Check if user entered 0.0.0.0 or left field empty (both allow access from anywhere)
|
|
$allowsFromAnywhere = false;
|
|
if (empty($this->allowed_ips)) {
|
|
$allowsFromAnywhere = true;
|
|
} elseif ($this->allowed_ips === '0.0.0.0' || str_contains($this->allowed_ips, '0.0.0.0')) {
|
|
$allowsFromAnywhere = true;
|
|
}
|
|
|
|
// Check if it's 0.0.0.0 (allow all) or empty
|
|
if ($this->allowed_ips === '0.0.0.0' || empty($this->allowed_ips)) {
|
|
// Keep as is - empty means no restriction, 0.0.0.0 means allow all
|
|
} else {
|
|
// Validate and clean up the entries
|
|
$invalidEntries = [];
|
|
$validEntries = str($this->allowed_ips)->trim()->explode(',')->map(function ($entry) use (&$invalidEntries) {
|
|
$entry = str($entry)->trim()->toString();
|
|
|
|
if (empty($entry)) {
|
|
return null;
|
|
}
|
|
|
|
// Check if it's valid CIDR notation
|
|
if (str_contains($entry, '/')) {
|
|
[$ip, $mask] = explode('/', $entry);
|
|
if (filter_var($ip, FILTER_VALIDATE_IP) && is_numeric($mask) && $mask >= 0 && $mask <= 32) {
|
|
return $entry;
|
|
}
|
|
$invalidEntries[] = $entry;
|
|
|
|
return null;
|
|
}
|
|
|
|
// Check if it's a valid IP address
|
|
if (filter_var($entry, FILTER_VALIDATE_IP)) {
|
|
return $entry;
|
|
}
|
|
|
|
$invalidEntries[] = $entry;
|
|
|
|
return null;
|
|
})->filter()->unique();
|
|
|
|
if (! empty($invalidEntries)) {
|
|
$this->dispatch('error', 'Invalid IP addresses or subnets: '.implode(', ', $invalidEntries));
|
|
|
|
return;
|
|
}
|
|
|
|
// Also check if we have no valid entries after filtering
|
|
if ($validEntries->isEmpty()) {
|
|
$this->dispatch('error', 'No valid IP addresses or subnets provided');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->allowed_ips = $validEntries->implode(',');
|
|
}
|
|
|
|
$this->instantSave();
|
|
|
|
// Show security warning if allowing access from anywhere
|
|
if ($allowsFromAnywhere) {
|
|
$message = empty($this->allowed_ips)
|
|
? 'Empty IP allowlist allows API access from anywhere.<br><br>This is not recommended for production environments!'
|
|
: 'Using 0.0.0.0 allows API access from anywhere.<br><br>This is not recommended for production environments!';
|
|
$this->dispatch('warning', $message);
|
|
}
|
|
} 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');
|
|
}
|
|
}
|