diff --git a/app/Http/Middleware/DecideWhatToDoWithUser.php b/app/Http/Middleware/DecideWhatToDoWithUser.php
index 8b1c550df..64952533f 100644
--- a/app/Http/Middleware/DecideWhatToDoWithUser.php
+++ b/app/Http/Middleware/DecideWhatToDoWithUser.php
@@ -19,13 +19,17 @@ public function handle(Request $request, Closure $next): Response
if (auth()?->user()?->currentTeam()) {
refreshSession(auth()->user()->currentTeam());
}
- if (! auth()->user() || ! isCloud() || isInstanceAdmin()) {
+ if (! auth()->user() || ! isCloud()) {
if (! isCloud() && showBoarding() && ! in_array($request->path(), allowedPathsForBoardingAccounts())) {
return redirect()->route('onboarding');
}
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 ($request->path() === 'verify' || in_array($request->path(), allowedPathsForInvalidAccounts()) || $request->routeIs('verify.verify')) {
return $next($request);
diff --git a/app/Livewire/Settings/Advanced.php b/app/Livewire/Settings/Advanced.php
index fb9c91263..0a7ba319d 100644
--- a/app/Livewire/Settings/Advanced.php
+++ b/app/Livewire/Settings/Advanced.php
@@ -10,8 +10,7 @@
class Advanced extends Component
{
- #[Validate('required')]
- public Server $server;
+ public ?Server $server = null;
public InstanceSettings $settings;
@@ -44,7 +43,6 @@ class Advanced extends Component
public function rules()
{
return [
- 'server' => 'required',
'is_registration_enabled' => 'boolean',
'do_not_track' => 'boolean',
'is_dns_validation_enabled' => 'boolean',
@@ -62,7 +60,9 @@ public function mount()
if (! isInstanceAdmin()) {
return redirect()->route('dashboard');
}
- $this->server = Server::findOrFail(0);
+ if (! isCloud()) {
+ $this->server = Server::findOrFail(0);
+ }
$this->settings = instanceSettings();
$this->custom_dns_servers = $this->settings->custom_dns_servers;
$this->allowed_ips = $this->settings->allowed_ips;
diff --git a/app/Livewire/Settings/Index.php b/app/Livewire/Settings/Index.php
index 7a96eabb2..ae7448807 100644
--- a/app/Livewire/Settings/Index.php
+++ b/app/Livewire/Settings/Index.php
@@ -12,7 +12,7 @@ class Index extends Component
{
public InstanceSettings $settings;
- public Server $server;
+ public ?Server $server = null;
#[Validate('nullable|string|max:255')]
public ?string $fqdn = null;
@@ -57,7 +57,9 @@ public function mount()
return redirect()->route('dashboard');
}
$this->settings = instanceSettings();
- $this->server = Server::findOrFail(0);
+ if (! isCloud()) {
+ $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;
@@ -121,7 +123,7 @@ public function submit()
}
$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)) {
$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;
@@ -145,7 +147,9 @@ public function submit()
$this->instantSave(isSave: false);
$this->settings->save();
- $this->server->setupDynamicProxyConfiguration();
+ if ($this->server) {
+ $this->server->setupDynamicProxyConfiguration();
+ }
if (! $error_show) {
$this->dispatch('success', 'Instance settings updated successfully!');
}
@@ -163,6 +167,12 @@ public function buildHelperImage()
return;
}
+ if (! $this->server) {
+ $this->dispatch('error', 'Server not available.');
+
+ return;
+ }
+
$version = $this->dev_helper_version ?: config('constants.coolify.helper_version');
if (empty($version)) {
$this->dispatch('error', 'Please specify a version to build.');
diff --git a/app/Livewire/Settings/Updates.php b/app/Livewire/Settings/Updates.php
index fe20763b6..01a67c38c 100644
--- a/app/Livewire/Settings/Updates.php
+++ b/app/Livewire/Settings/Updates.php
@@ -12,7 +12,7 @@ class Updates extends Component
{
public InstanceSettings $settings;
- public Server $server;
+ public ?Server $server = null;
#[Validate('string')]
public string $auto_update_frequency;
@@ -25,7 +25,9 @@ class Updates extends Component
public function mount()
{
- $this->server = Server::findOrFail(0);
+ if (! isCloud()) {
+ $this->server = Server::findOrFail(0);
+ }
$this->settings = instanceSettings();
$this->auto_update_frequency = $this->settings->auto_update_frequency;
@@ -76,7 +78,9 @@ public function submit()
}
$this->instantSave();
- $this->server->setupDynamicProxyConfiguration();
+ if ($this->server) {
+ $this->server->setupDynamicProxyConfiguration();
+ }
} catch (\Exception $e) {
return handleError($e, $this);
}
diff --git a/app/Models/User.php b/app/Models/User.php
index b790efcf1..bbc4e603c 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -297,7 +297,8 @@ public function isInstanceAdmin()
{
$found_root_team = Auth::user()->teams->filter(function ($team) {
if ($team->id == 0) {
- if (! Auth::user()->isAdmin()) {
+ $role = $team->pivot->role;
+ if ($role !== 'admin' && $role !== 'owner') {
return false;
}
diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php
index 9fc1e6f1c..f9645fd9f 100644
--- a/bootstrap/helpers/shared.php
+++ b/bootstrap/helpers/shared.php
@@ -384,7 +384,7 @@ function base_url(bool $withPort = true): string
function isSubscribed()
{
- return isSubscriptionActive() || auth()->user()->isInstanceAdmin();
+ return isSubscriptionActive();
}
function isProduction(): bool
diff --git a/bootstrap/helpers/subscriptions.php b/bootstrap/helpers/subscriptions.php
index 1a0ae0fbd..4b84fb7f6 100644
--- a/bootstrap/helpers/subscriptions.php
+++ b/bootstrap/helpers/subscriptions.php
@@ -13,6 +13,10 @@ function isSubscriptionActive()
if (! $team) {
return false;
}
+ // Root team (id=0) doesn't require subscription
+ if ($team->id === 0) {
+ return true;
+ }
$subscription = $team?->subscription;
if (is_null($subscription)) {