Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion app/Console/Commands/ClearGlobalSearchCache.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,14 @@ public function handle(): int
return Command::FAILURE;
}

$teamId = auth()->user()->currentTeam()->id;
$user = auth()->user();
$teamId = $user?->currentTeam()?->id;

if (! $teamId) {
$this->error('Current user has no team assigned. Use --team=ID or --all option.');

return Command::FAILURE;
}

return $this->clearTeamCache($teamId);
}
Expand Down
14 changes: 11 additions & 3 deletions app/Http/Controllers/Api/TeamController.php
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,17 @@ public function members_by_id(Request $request)
),
]
)]
public function current_team(Request $request)
public function current_team(Request $request): \Illuminate\Http\JsonResponse
{
$teamId = getTeamIdFromToken();
if (is_null($teamId)) {
return invalidTokenResponse();
}
$team = auth()->user()->currentTeam();
$user = auth()->user();
$team = $user?->currentTeam();
if (is_null($team)) {
return response()->json(['message' => 'No team assigned to user.'], 404);
}
Comment on lines +215 to +225
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Null‑safe current_team implementation is fine; tighten signature/docs around unused $request

The switch to $user?->currentTeam() with an explicit 404 JSON response for “no team assigned” addresses the null‑safety problem and gives clients a clear error payload. However, $request is now unused and PHPMD flags it; if you don’t actually need it, consider dropping the parameter or renaming to $_request / adding a PHPMD suppression so static analysis stays green. Also, the OA metadata for /teams/current doesn’t advertise a 404, while the method now can return one—worth updating the OpenAPI response list for accuracy.

🧰 Tools
🪛 PHPMD (2.15.0)

215-215: Avoid unused parameters such as '$request'. (undefined)

(UnusedFormalParameter)

🤖 Prompt for AI Agents
In app/Http/Controllers/Api/TeamController.php around lines 215 to 225, the
Request $request parameter is no longer used and PHPMD flags it; remove the
unused parameter (or, if signature must remain, rename to $_request or add a
PHPMD suppression comment) and update the method signature accordingly, and also
update the OpenAPI/Swagger annotations for the /teams/current endpoint to
include a 404 response schema matching the JSON payload returned when no team is
assigned so the docs reflect the actual behavior.


return response()->json(
$this->removeSensitiveData($team),
Expand Down Expand Up @@ -263,7 +267,11 @@ public function current_team_members(Request $request)
if (is_null($teamId)) {
return invalidTokenResponse();
}
$team = auth()->user()->currentTeam();
$user = auth()->user();
$team = $user?->currentTeam();
if (is_null($team)) {
return response()->json(['message' => 'No team assigned to user.'], 404);
}
$team->members->makeHidden([
'pivot',
'email_change_code',
Expand Down
18 changes: 16 additions & 2 deletions app/Http/Controllers/MagicController.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,16 @@ public function environments()

public function newProject()
{
$team = currentTeam();
if (! $team) {
return response()->json([
'message' => 'No team assigned to user.',
], 404);
}

$project = Project::firstOrCreate(
['name' => request()->query('name') ?? generate_random_name()],
['team_id' => currentTeam()->id]
['team_id' => $team->id]
);

return response()->json([
Expand All @@ -70,13 +77,20 @@ public function newEnvironment()

public function newTeam()
{
$user = auth()->user();
if (! $user) {
return response()->json([
'message' => 'Unauthenticated.',
], 401);
}

$team = Team::create(
[
'name' => request()->query('name') ?? generate_random_name(),
'personal_team' => false,
],
);
auth()->user()->teams()->attach($team, ['role' => 'admin']);
$user->teams()->attach($team, ['role' => 'admin']);
refreshSession();

return redirect(request()->header('Referer'));
Expand Down
24 changes: 20 additions & 4 deletions app/Livewire/GlobalSearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -248,12 +248,23 @@ private function canCreateResource(string $type): bool
private function loadSearchableItems()
{
// Try to get from Redis cache first
$cacheKey = self::getCacheKey(auth()->user()->currentTeam()->id);
$user = auth()->user();
if (! $user) {
$this->allSearchableItems = [];

return;
}
$team = $user->currentTeam();
if (! $team) {
$this->allSearchableItems = [];

return;
}
$cacheKey = self::getCacheKey($team->id);

$this->allSearchableItems = Cache::remember($cacheKey, 300, function () {
$this->allSearchableItems = Cache::remember($cacheKey, 300, function () use ($team) {
ray()->showQueries();
$items = collect();
$team = auth()->user()->currentTeam();

// Get all applications
$applications = Application::ownedByCurrentTeam()
Expand Down Expand Up @@ -1232,7 +1243,12 @@ public function loadProjects()
{
$this->loadingProjects = true;
$user = auth()->user();
$team = $user->currentTeam();
$team = $user?->currentTeam();
if (! $team) {
$this->loadingProjects = false;

return $this->dispatch('error', message: 'No team assigned to user');
}
$projects = Project::where('team_id', $team->id)->get();

if ($projects->isEmpty()) {
Expand Down
6 changes: 5 additions & 1 deletion app/Livewire/Notifications/Discord.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ class Discord extends Component
public function mount()
{
try {
$this->team = auth()->user()->currentTeam();
$user = auth()->user();
$this->team = $user?->currentTeam();
if (! $this->team) {
return handleError(new \Exception('Team not found.'), $this);
}
$this->settings = $this->team->discordNotificationSettings;
$this->authorize('view', $this->settings);
$this->syncData();
Expand Down
13 changes: 10 additions & 3 deletions app/Livewire/Notifications/Email.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,19 @@ class Email extends Component
public function mount()
{
try {
$this->team = auth()->user()->currentTeam();
$this->emails = auth()->user()->email;
$user = auth()->user();
if (! $user) {
return handleError(new \Exception('User not authenticated.'), $this);
}
$this->team = $user->currentTeam();
if (! $this->team) {
return handleError(new \Exception('Team not found.'), $this);
}
$this->emails = $user->email;
$this->settings = $this->team->emailNotificationSettings;
$this->authorize('view', $this->settings);
$this->syncData();
$this->testEmailAddress = auth()->user()->email;
$this->testEmailAddress = $user->email;
} catch (\Throwable $e) {
return handleError($e, $this);
}
Expand Down
6 changes: 5 additions & 1 deletion app/Livewire/Notifications/Pushover.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ class Pushover extends Component
public function mount()
{
try {
$this->team = auth()->user()->currentTeam();
$user = auth()->user();
$this->team = $user?->currentTeam();
if (! $this->team) {
return handleError(new \Exception('Team not found.'), $this);
}
$this->settings = $this->team->pushoverNotificationSettings;
$this->authorize('view', $this->settings);
$this->syncData();
Expand Down
6 changes: 5 additions & 1 deletion app/Livewire/Notifications/Slack.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,11 @@ class Slack extends Component
public function mount()
{
try {
$this->team = auth()->user()->currentTeam();
$user = auth()->user();
$this->team = $user?->currentTeam();
if (! $this->team) {
return handleError(new \Exception('Team not found.'), $this);
}
$this->settings = $this->team->slackNotificationSettings;
$this->authorize('view', $this->settings);
$this->syncData();
Expand Down
6 changes: 5 additions & 1 deletion app/Livewire/Notifications/Telegram.php
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,11 @@ class Telegram extends Component
public function mount()
{
try {
$this->team = auth()->user()->currentTeam();
$user = auth()->user();
$this->team = $user?->currentTeam();
if (! $this->team) {
return handleError(new \Exception('Team not found.'), $this);
}
$this->settings = $this->team->telegramNotificationSettings;
$this->authorize('view', $this->settings);
$this->syncData();
Expand Down
6 changes: 5 additions & 1 deletion app/Livewire/Notifications/Webhook.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,11 @@ class Webhook extends Component
public function mount()
{
try {
$this->team = auth()->user()->currentTeam();
$user = auth()->user();
$this->team = $user?->currentTeam();
if (! $this->team) {
return handleError(new \Exception('Team not found.'), $this);
}
$this->settings = $this->team->webhookNotificationSettings;
$this->authorize('view', $this->settings);
$this->syncData();
Expand Down
11 changes: 9 additions & 2 deletions app/Livewire/SettingsEmail.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,17 @@ public function mount()
if (isInstanceAdmin() === false) {
return redirect()->route('dashboard');
}
$user = auth()->user();
if (! $user) {
return redirect()->route('login');
}
$this->settings = instanceSettings();
$this->syncData();
$this->team = auth()->user()->currentTeam();
$this->testEmailAddress = auth()->user()->email;
$this->team = $user->currentTeam();
if (! $this->team) {
return redirect()->route('dashboard');
}
$this->testEmailAddress = $user->email;
}

public function syncData(bool $toModel = false)
Expand Down
28 changes: 28 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,34 @@ public function teams()
return $this->belongsToMany(Team::class)->withPivot('role');
}

public function organizations()
{
return $this->belongsToMany(Organization::class, 'organization_users')
->using(OrganizationUser::class)
->withPivot('role', 'permissions', 'is_active')
->withTimestamps();
}

public function currentOrganization()
{
return $this->belongsTo(Organization::class, 'current_organization_id');
}

public function canPerformAction($action, $resource = null)
{
$organization = $this->currentOrganization;
if (! $organization) {
return false;
}

return $organization->canUserPerformAction($this, $action, $resource);
}

public function hasLicenseFeature($feature)
{
return $this->currentOrganization?->activeLicense?->hasFeature($feature) ?? false;
}

public function changelogReads()
{
return $this->hasMany(UserChangelogRead::class);
Expand Down
Loading