mirror of
https://github.com/tiennm99/coolify.git
synced 2026-04-17 17:21:04 +00:00
fix(settings): fix 404 on /settings for root user on cloud instance
- Make Server property nullable in Settings components (Index, Advanced, Updates) - Add conditional server loading: only load when not on cloud - Add null checks before using server for DNS validation and proxy configuration - Fix isInstanceAdmin() to check root team's pivot role directly instead of current team - Make root team (id=0) bypass subscription check on cloud - Remove isInstanceAdmin() from main middleware bypass: only settings/admin routes are exempted - Update isSubscribed() to only check isSubscriptionActive() for navbar consistency 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,13 +19,17 @@ class DecideWhatToDoWithUser
|
|||||||
if (auth()?->user()?->currentTeam()) {
|
if (auth()?->user()?->currentTeam()) {
|
||||||
refreshSession(auth()->user()->currentTeam());
|
refreshSession(auth()->user()->currentTeam());
|
||||||
}
|
}
|
||||||
if (! auth()->user() || ! isCloud() || isInstanceAdmin()) {
|
if (! auth()->user() || ! isCloud()) {
|
||||||
if (! isCloud() && showBoarding() && ! in_array($request->path(), allowedPathsForBoardingAccounts())) {
|
if (! isCloud() && showBoarding() && ! in_array($request->path(), allowedPathsForBoardingAccounts())) {
|
||||||
return redirect()->route('onboarding');
|
return redirect()->route('onboarding');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $next($request);
|
return $next($request);
|
||||||
}
|
}
|
||||||
|
// Instance admins can access settings and admin routes regardless of subscription
|
||||||
|
if (isInstanceAdmin() && (Str::startsWith($request->path(), 'settings') || $request->path() === 'admin')) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
if (! auth()->user()->hasVerifiedEmail()) {
|
if (! auth()->user()->hasVerifiedEmail()) {
|
||||||
if ($request->path() === 'verify' || in_array($request->path(), allowedPathsForInvalidAccounts()) || $request->routeIs('verify.verify')) {
|
if ($request->path() === 'verify' || in_array($request->path(), allowedPathsForInvalidAccounts()) || $request->routeIs('verify.verify')) {
|
||||||
return $next($request);
|
return $next($request);
|
||||||
|
|||||||
@@ -10,8 +10,7 @@ use Livewire\Component;
|
|||||||
|
|
||||||
class Advanced extends Component
|
class Advanced extends Component
|
||||||
{
|
{
|
||||||
#[Validate('required')]
|
public ?Server $server = null;
|
||||||
public Server $server;
|
|
||||||
|
|
||||||
public InstanceSettings $settings;
|
public InstanceSettings $settings;
|
||||||
|
|
||||||
@@ -44,7 +43,6 @@ class Advanced extends Component
|
|||||||
public function rules()
|
public function rules()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'server' => 'required',
|
|
||||||
'is_registration_enabled' => 'boolean',
|
'is_registration_enabled' => 'boolean',
|
||||||
'do_not_track' => 'boolean',
|
'do_not_track' => 'boolean',
|
||||||
'is_dns_validation_enabled' => 'boolean',
|
'is_dns_validation_enabled' => 'boolean',
|
||||||
@@ -62,7 +60,9 @@ class Advanced extends Component
|
|||||||
if (! isInstanceAdmin()) {
|
if (! isInstanceAdmin()) {
|
||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$this->server = Server::findOrFail(0);
|
if (! isCloud()) {
|
||||||
|
$this->server = Server::findOrFail(0);
|
||||||
|
}
|
||||||
$this->settings = instanceSettings();
|
$this->settings = instanceSettings();
|
||||||
$this->custom_dns_servers = $this->settings->custom_dns_servers;
|
$this->custom_dns_servers = $this->settings->custom_dns_servers;
|
||||||
$this->allowed_ips = $this->settings->allowed_ips;
|
$this->allowed_ips = $this->settings->allowed_ips;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class Index extends Component
|
|||||||
{
|
{
|
||||||
public InstanceSettings $settings;
|
public InstanceSettings $settings;
|
||||||
|
|
||||||
public Server $server;
|
public ?Server $server = null;
|
||||||
|
|
||||||
#[Validate('nullable|string|max:255')]
|
#[Validate('nullable|string|max:255')]
|
||||||
public ?string $fqdn = null;
|
public ?string $fqdn = null;
|
||||||
@@ -57,7 +57,9 @@ class Index extends Component
|
|||||||
return redirect()->route('dashboard');
|
return redirect()->route('dashboard');
|
||||||
}
|
}
|
||||||
$this->settings = instanceSettings();
|
$this->settings = instanceSettings();
|
||||||
$this->server = Server::findOrFail(0);
|
if (! isCloud()) {
|
||||||
|
$this->server = Server::findOrFail(0);
|
||||||
|
}
|
||||||
$this->fqdn = $this->settings->fqdn;
|
$this->fqdn = $this->settings->fqdn;
|
||||||
$this->public_port_min = $this->settings->public_port_min;
|
$this->public_port_min = $this->settings->public_port_min;
|
||||||
$this->public_port_max = $this->settings->public_port_max;
|
$this->public_port_max = $this->settings->public_port_max;
|
||||||
@@ -121,7 +123,7 @@ class Index extends Component
|
|||||||
}
|
}
|
||||||
$this->validate();
|
$this->validate();
|
||||||
|
|
||||||
if ($this->settings->is_dns_validation_enabled && $this->fqdn) {
|
if ($this->settings->is_dns_validation_enabled && $this->fqdn && $this->server) {
|
||||||
if (! validateDNSEntry($this->fqdn, $this->server)) {
|
if (! validateDNSEntry($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.");
|
$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;
|
$error_show = true;
|
||||||
@@ -145,7 +147,9 @@ class Index extends Component
|
|||||||
$this->instantSave(isSave: false);
|
$this->instantSave(isSave: false);
|
||||||
|
|
||||||
$this->settings->save();
|
$this->settings->save();
|
||||||
$this->server->setupDynamicProxyConfiguration();
|
if ($this->server) {
|
||||||
|
$this->server->setupDynamicProxyConfiguration();
|
||||||
|
}
|
||||||
if (! $error_show) {
|
if (! $error_show) {
|
||||||
$this->dispatch('success', 'Instance settings updated successfully!');
|
$this->dispatch('success', 'Instance settings updated successfully!');
|
||||||
}
|
}
|
||||||
@@ -163,6 +167,12 @@ class Index extends Component
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! $this->server) {
|
||||||
|
$this->dispatch('error', 'Server not available.');
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$version = $this->dev_helper_version ?: config('constants.coolify.helper_version');
|
$version = $this->dev_helper_version ?: config('constants.coolify.helper_version');
|
||||||
if (empty($version)) {
|
if (empty($version)) {
|
||||||
$this->dispatch('error', 'Please specify a version to build.');
|
$this->dispatch('error', 'Please specify a version to build.');
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class Updates extends Component
|
|||||||
{
|
{
|
||||||
public InstanceSettings $settings;
|
public InstanceSettings $settings;
|
||||||
|
|
||||||
public Server $server;
|
public ?Server $server = null;
|
||||||
|
|
||||||
#[Validate('string')]
|
#[Validate('string')]
|
||||||
public string $auto_update_frequency;
|
public string $auto_update_frequency;
|
||||||
@@ -25,7 +25,9 @@ class Updates extends Component
|
|||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->server = Server::findOrFail(0);
|
if (! isCloud()) {
|
||||||
|
$this->server = Server::findOrFail(0);
|
||||||
|
}
|
||||||
|
|
||||||
$this->settings = instanceSettings();
|
$this->settings = instanceSettings();
|
||||||
$this->auto_update_frequency = $this->settings->auto_update_frequency;
|
$this->auto_update_frequency = $this->settings->auto_update_frequency;
|
||||||
@@ -76,7 +78,9 @@ class Updates extends Component
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->instantSave();
|
$this->instantSave();
|
||||||
$this->server->setupDynamicProxyConfiguration();
|
if ($this->server) {
|
||||||
|
$this->server->setupDynamicProxyConfiguration();
|
||||||
|
}
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -297,7 +297,8 @@ class User extends Authenticatable implements SendsEmail
|
|||||||
{
|
{
|
||||||
$found_root_team = Auth::user()->teams->filter(function ($team) {
|
$found_root_team = Auth::user()->teams->filter(function ($team) {
|
||||||
if ($team->id == 0) {
|
if ($team->id == 0) {
|
||||||
if (! Auth::user()->isAdmin()) {
|
$role = $team->pivot->role;
|
||||||
|
if ($role !== 'admin' && $role !== 'owner') {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -384,7 +384,7 @@ function base_url(bool $withPort = true): string
|
|||||||
|
|
||||||
function isSubscribed()
|
function isSubscribed()
|
||||||
{
|
{
|
||||||
return isSubscriptionActive() || auth()->user()->isInstanceAdmin();
|
return isSubscriptionActive();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isProduction(): bool
|
function isProduction(): bool
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ function isSubscriptionActive()
|
|||||||
if (! $team) {
|
if (! $team) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// Root team (id=0) doesn't require subscription
|
||||||
|
if ($team->id === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
$subscription = $team?->subscription;
|
$subscription = $team?->subscription;
|
||||||
|
|
||||||
if (is_null($subscription)) {
|
if (is_null($subscription)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user