From acff543e09ae5c7f8da78e5a092ebb1e57f24dc0 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:17:56 +0100 Subject: [PATCH 1/6] fix(settings): fix 404 on /settings for root user on cloud instance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 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 --- app/Http/Middleware/DecideWhatToDoWithUser.php | 6 +++++- app/Livewire/Settings/Advanced.php | 8 ++++---- app/Livewire/Settings/Index.php | 18 ++++++++++++++---- app/Livewire/Settings/Updates.php | 10 +++++++--- app/Models/User.php | 3 ++- bootstrap/helpers/shared.php | 2 +- bootstrap/helpers/subscriptions.php | 4 ++++ 7 files changed, 37 insertions(+), 14 deletions(-) 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)) { From 2cf915aed813c666fadb43bc8e2376c460ffcaf9 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:37:48 +0100 Subject: [PATCH 2/6] fix(user): use $this instead of Auth::user() in User model methods MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix isInstanceAdmin(), currentTeam(), otherTeams(), and role() methods to operate on the actual User instance instead of always using the authenticated user. This ensures correct behavior when these methods are called on non-authenticated user instances (e.g., in ActivityMonitor). Also fix settings route check to use routeIs() instead of path matching. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- app/Http/Middleware/DecideWhatToDoWithUser.php | 2 +- app/Models/User.php | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/Http/Middleware/DecideWhatToDoWithUser.php b/app/Http/Middleware/DecideWhatToDoWithUser.php index 64952533f..b62e874cc 100644 --- a/app/Http/Middleware/DecideWhatToDoWithUser.php +++ b/app/Http/Middleware/DecideWhatToDoWithUser.php @@ -27,7 +27,7 @@ public function handle(Request $request, Closure $next): Response return $next($request); } // Instance admins can access settings and admin routes regardless of subscription - if (isInstanceAdmin() && (Str::startsWith($request->path(), 'settings') || $request->path() === 'admin')) { + if (isInstanceAdmin() && ($request->routeIs('settings.*') || $request->routeIs('settings.index') || $request->path() === 'admin')) { return $next($request); } if (! auth()->user()->hasVerifiedEmail()) { diff --git a/app/Models/User.php b/app/Models/User.php index bbc4e603c..0b0666c1a 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -295,7 +295,7 @@ public function isAdminFromSession() public function isInstanceAdmin() { - $found_root_team = Auth::user()->teams->filter(function ($team) { + $found_root_team = $this->teams->filter(function ($team) { if ($team->id == 0) { $role = $team->pivot->role; if ($role !== 'admin' && $role !== 'owner') { @@ -313,9 +313,9 @@ public function isInstanceAdmin() public function currentTeam() { - return Cache::remember('team:'.Auth::id(), 3600, function () { - if (is_null(data_get(session('currentTeam'), 'id')) && Auth::user()->teams->count() > 0) { - return Auth::user()->teams[0]; + return Cache::remember('team:'.$this->id, 3600, function () { + if (is_null(data_get(session('currentTeam'), 'id')) && $this->teams->count() > 0) { + return $this->teams[0]; } return Team::find(session('currentTeam')->id); @@ -324,7 +324,7 @@ public function currentTeam() public function otherTeams() { - return Auth::user()->teams->filter(function ($team) { + return $this->teams->filter(function ($team) { return $team->id != currentTeam()->id; }); } @@ -334,9 +334,9 @@ public function role() if (data_get($this, 'pivot')) { return $this->pivot->role; } - $user = Auth::user()->teams->where('id', currentTeam()->id)->first(); + $team = $this->teams->where('id', currentTeam()->id)->first(); - return data_get($user, 'pivot.role'); + return data_get($team, 'pivot.role'); } /** From 2743229cc49c342311f5daa55221f170bbcf70dc Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Sun, 28 Dec 2025 13:26:52 +0100 Subject: [PATCH 3/6] fix(user): complete User model fixes for non-web contexts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix currentTeam() to return null instead of crashing when no session - Fix role() to use $this->currentTeam() instead of global helper - Add roleInTeam() method for explicit team context - Remove unused otherTeams() method - Fix InviteLink authorization bypass when role() returns null - Fix confirmEmailChange() null safety for currentTeam() - Fix ActivityMonitor to handle null currentTeam with fallback chain 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- app/Livewire/ActivityMonitor.php | 6 +++-- app/Livewire/Team/InviteLink.php | 2 +- app/Models/User.php | 46 ++++++++++++++++++++------------ 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/app/Livewire/ActivityMonitor.php b/app/Livewire/ActivityMonitor.php index bc310e715..370ff1eaa 100644 --- a/app/Livewire/ActivityMonitor.php +++ b/app/Livewire/ActivityMonitor.php @@ -79,8 +79,10 @@ public function polling() $causer_id = data_get($this->activity, 'causer_id'); $user = User::find($causer_id); if ($user) { - $teamId = $user->currentTeam()->id; - if (! self::$eventDispatched) { + $teamId = data_get($this->activity, 'properties.team_id') + ?? $user->currentTeam()?->id + ?? $user->teams->first()?->id; + if ($teamId && ! self::$eventDispatched) { if (filled($this->eventData)) { $this->eventToDispatch::dispatch($teamId, $this->eventData); } else { diff --git a/app/Livewire/Team/InviteLink.php b/app/Livewire/Team/InviteLink.php index 45af53950..ee6d535e9 100644 --- a/app/Livewire/Team/InviteLink.php +++ b/app/Livewire/Team/InviteLink.php @@ -48,7 +48,7 @@ private function generateInviteLink(bool $sendEmail = false) // Prevent privilege escalation: users cannot invite someone with higher privileges $userRole = auth()->user()->role(); - if ($userRole === 'member' && in_array($this->role, ['admin', 'owner'])) { + if (is_null($userRole) || ($userRole === 'member' && in_array($this->role, ['admin', 'owner']))) { throw new \Exception('Members cannot invite admins or owners.'); } if ($userRole === 'admin' && $this->role === 'owner') { diff --git a/app/Models/User.php b/app/Models/User.php index 0b0666c1a..d64835c42 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -311,30 +311,41 @@ public function isInstanceAdmin() return $found_root_team->count() > 0; } - public function currentTeam() + public function currentTeam(): ?Team { - return Cache::remember('team:'.$this->id, 3600, function () { - if (is_null(data_get(session('currentTeam'), 'id')) && $this->teams->count() > 0) { - return $this->teams[0]; - } + $sessionTeamId = data_get(session('currentTeam'), 'id'); - return Team::find(session('currentTeam')->id); + if (is_null($sessionTeamId)) { + return null; + } + + return Cache::remember('team:'.$this->id, 3600, function () use ($sessionTeamId) { + return Team::find($sessionTeamId); }); } - public function otherTeams() - { - return $this->teams->filter(function ($team) { - return $team->id != currentTeam()->id; - }); - } - - public function role() + public function role(): ?string { if (data_get($this, 'pivot')) { return $this->pivot->role; } - $team = $this->teams->where('id', currentTeam()->id)->first(); + + $current = $this->currentTeam(); + if (is_null($current)) { + return null; + } + + $team = $this->teams->where('id', $current->id)->first(); + + return data_get($team, 'pivot.role'); + } + + /** + * Get the user's role in a specific team + */ + public function roleInTeam(int $teamId): ?string + { + $team = $this->teams->where('id', $teamId)->first(); return data_get($team, 'pivot.role'); } @@ -416,9 +427,10 @@ public function confirmEmailChange(string $code): bool ]); // For cloud users, dispatch job to update Stripe customer email asynchronously - if (isCloud() && $this->currentTeam()->subscription) { + $currentTeam = $this->currentTeam(); + if (isCloud() && $currentTeam?->subscription) { dispatch(new \App\Jobs\UpdateStripeCustomerEmailJob( - $this->currentTeam(), + $currentTeam, $this->id, $newEmail, $oldEmail From ddd78658e8c67754b2fb3bba648b56153545f535 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Sun, 28 Dec 2025 14:02:41 +0100 Subject: [PATCH 4/6] fix(user): improve cache key and remove redundant route check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Include sessionTeamId in currentTeam() cache key to prevent stale team data when users switch teams - Update refreshSession() to use new cache key format - Remove redundant routeIs('settings.index') check since settings.* already matches it 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- app/Http/Middleware/DecideWhatToDoWithUser.php | 2 +- app/Models/User.php | 2 +- bootstrap/helpers/shared.php | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/Http/Middleware/DecideWhatToDoWithUser.php b/app/Http/Middleware/DecideWhatToDoWithUser.php index b62e874cc..dea9f6a9d 100644 --- a/app/Http/Middleware/DecideWhatToDoWithUser.php +++ b/app/Http/Middleware/DecideWhatToDoWithUser.php @@ -27,7 +27,7 @@ public function handle(Request $request, Closure $next): Response return $next($request); } // Instance admins can access settings and admin routes regardless of subscription - if (isInstanceAdmin() && ($request->routeIs('settings.*') || $request->routeIs('settings.index') || $request->path() === 'admin')) { + if (isInstanceAdmin() && ($request->routeIs('settings.*') || $request->path() === 'admin')) { return $next($request); } if (! auth()->user()->hasVerifiedEmail()) { diff --git a/app/Models/User.php b/app/Models/User.php index d64835c42..560f21d0f 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -319,7 +319,7 @@ public function currentTeam(): ?Team return null; } - return Cache::remember('team:'.$this->id, 3600, function () use ($sessionTeamId) { + return Cache::remember('user:'.$this->id.':team:'.$sessionTeamId, 3600, function () use ($sessionTeamId) { return Team::find($sessionTeamId); }); } diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index f9645fd9f..d6b573965 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -182,8 +182,11 @@ function refreshSession(?Team $team = null): void $team = User::find(Auth::id())->teams->first(); } } + // Clear old cache key format for backwards compatibility Cache::forget('team:'.Auth::id()); - Cache::remember('team:'.Auth::id(), 3600, function () use ($team) { + // Use new cache key format that includes team ID + Cache::forget('user:'.Auth::id().':team:'.$team->id); + Cache::remember('user:'.Auth::id().':team:'.$team->id, 3600, function () use ($team) { return $team; }); session(['currentTeam' => $team]); From 8d212bc11062620ed4d66fd9a41f098fe6fd9d04 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Sun, 28 Dec 2025 14:50:59 +0100 Subject: [PATCH 5/6] fix(team): improve team retrieval and session handling for users --- app/Http/Controllers/Api/TeamController.php | 10 ++++++++-- app/Http/Middleware/DecideWhatToDoWithUser.php | 3 +++ app/Livewire/Team/Member.php | 6 +++--- app/Models/User.php | 8 ++++++++ 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Api/TeamController.php b/app/Http/Controllers/Api/TeamController.php index e12d83542..fd0282d96 100644 --- a/app/Http/Controllers/Api/TeamController.php +++ b/app/Http/Controllers/Api/TeamController.php @@ -218,7 +218,10 @@ public function current_team(Request $request) if (is_null($teamId)) { return invalidTokenResponse(); } - $team = auth()->user()->currentTeam(); + $team = auth()->user()->teams->where('id', $teamId)->first(); + if (is_null($team)) { + return response()->json(['message' => 'Team not found.'], 404); + } return response()->json( $this->removeSensitiveData($team), @@ -263,7 +266,10 @@ public function current_team_members(Request $request) if (is_null($teamId)) { return invalidTokenResponse(); } - $team = auth()->user()->currentTeam(); + $team = auth()->user()->teams->where('id', $teamId)->first(); + if (is_null($team)) { + return response()->json(['message' => 'Team not found.'], 404); + } $team->members->makeHidden([ 'pivot', 'email_change_code', diff --git a/app/Http/Middleware/DecideWhatToDoWithUser.php b/app/Http/Middleware/DecideWhatToDoWithUser.php index dea9f6a9d..dbf261f4d 100644 --- a/app/Http/Middleware/DecideWhatToDoWithUser.php +++ b/app/Http/Middleware/DecideWhatToDoWithUser.php @@ -18,6 +18,9 @@ public function handle(Request $request, Closure $next): Response } if (auth()?->user()?->currentTeam()) { refreshSession(auth()->user()->currentTeam()); + } elseif (auth()?->user()?->teams?->count() > 0) { + // User's session team is invalid (e.g., removed from team), switch to first available team + refreshSession(auth()->user()->teams->first()); } if (! auth()->user() || ! isCloud()) { if (! isCloud() && showBoarding() && ! in_array($request->path(), allowedPathsForBoardingAccounts())) { diff --git a/app/Livewire/Team/Member.php b/app/Livewire/Team/Member.php index 96c98c637..b1f692365 100644 --- a/app/Livewire/Team/Member.php +++ b/app/Livewire/Team/Member.php @@ -71,11 +71,11 @@ public function remove() || Role::from($this->getMemberRole())->gt(auth()->user()->role())) { throw new \Exception('You are not authorized to perform this action.'); } + $teamId = currentTeam()->id; $this->member->teams()->detach(currentTeam()); + // Clear cache for the removed user - both old and new key formats Cache::forget("team:{$this->member->id}"); - Cache::remember('team:'.$this->member->id, 3600, function () { - return $this->member->teams()->first(); - }); + Cache::forget("user:{$this->member->id}:team:{$teamId}"); $this->dispatch('reloadWindow'); } catch (\Exception $e) { $this->dispatch('error', $e->getMessage()); diff --git a/app/Models/User.php b/app/Models/User.php index 560f21d0f..9437e0747 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -319,6 +319,14 @@ public function currentTeam(): ?Team return null; } + // Check if user actually belongs to this team + if (! $this->teams->contains('id', $sessionTeamId)) { + session()->forget('currentTeam'); + Cache::forget('user:'.$this->id.':team:'.$sessionTeamId); + + return null; + } + return Cache::remember('user:'.$this->id.':team:'.$sessionTeamId, 3600, function () use ($sessionTeamId) { return Team::find($sessionTeamId); }); From b33962bf8202c4067bb9d91de4b6d725134dfaa5 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Thu, 1 Jan 2026 15:42:21 +0100 Subject: [PATCH 6/6] chore: remove unused $server property and add missing import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove unused $server property and Server import from Advanced.php - Add proper import for UpdateStripeCustomerEmailJob in User.php 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- app/Livewire/Settings/Advanced.php | 6 ------ app/Models/User.php | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/app/Livewire/Settings/Advanced.php b/app/Livewire/Settings/Advanced.php index 0a7ba319d..16361ce79 100644 --- a/app/Livewire/Settings/Advanced.php +++ b/app/Livewire/Settings/Advanced.php @@ -3,15 +3,12 @@ namespace App\Livewire\Settings; use App\Models\InstanceSettings; -use App\Models\Server; use App\Rules\ValidIpOrCidr; use Livewire\Attributes\Validate; use Livewire\Component; class Advanced extends Component { - public ?Server $server = null; - public InstanceSettings $settings; #[Validate('boolean')] @@ -60,9 +57,6 @@ public function mount() if (! isInstanceAdmin()) { return redirect()->route('dashboard'); } - 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/Models/User.php b/app/Models/User.php index 9437e0747..4561cddb2 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Jobs\UpdateStripeCustomerEmailJob; use App\Notifications\Channels\SendsEmail; use App\Notifications\TransactionalEmails\ResetPassword as TransactionalEmailsResetPassword; use App\Traits\DeletesUserSessions; @@ -437,7 +438,7 @@ public function confirmEmailChange(string $code): bool // For cloud users, dispatch job to update Stripe customer email asynchronously $currentTeam = $this->currentTeam(); if (isCloud() && $currentTeam?->subscription) { - dispatch(new \App\Jobs\UpdateStripeCustomerEmailJob( + dispatch(new UpdateStripeCustomerEmailJob( $currentTeam, $this->id, $newEmail,