Merge remote-tracking branch 'origin/next' into fix/application-branch-validation

This commit is contained in:
Andras Bacsai
2026-06-02 11:10:33 +02:00
17 changed files with 306 additions and 29 deletions
@@ -28,12 +28,11 @@ class DynamicConfigurationNavbar extends Component
// Decode filename: pipes are used to encode dots for Livewire property binding
// (e.g., 'my|service.yaml' -> 'my.service.yaml')
// This must happen BEFORE validation because validateShellSafePath() correctly
// rejects pipe characters as dangerous shell metacharacters
// This must happen BEFORE validation because validateFilenameSafe()
// rejects pipe characters through validateShellSafePath().
$file = str_replace('|', '.', $fileName);
// Validate filename to prevent command injection
validateShellSafePath($file, 'proxy configuration filename');
validateFilenameSafe($file, 'proxy configuration filename');
if ($proxy_type === 'CADDY' && $file === 'Caddyfile') {
$this->dispatch('error', 'Cannot delete Caddyfile.');
@@ -43,8 +43,7 @@ class NewDynamicConfiguration extends Component
'value' => 'required',
]);
// Additional security validation to prevent command injection
validateShellSafePath($this->fileName, 'proxy configuration filename');
validateFilenameSafe($this->fileName, 'proxy configuration filename');
if (data_get($this->parameters, 'server_uuid')) {
$this->server = Server::ownedByCurrentTeam()->whereUuid(data_get($this->parameters, 'server_uuid'))->first();
+11 -3
View File
@@ -2,6 +2,7 @@
namespace App\Livewire\Team;
use App\Actions\User\RevokeUserTeamTokens;
use App\Enums\Role;
use App\Models\User;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
@@ -23,7 +24,9 @@ class Member extends Component
|| Role::from($this->getMemberRole())->gt(auth()->user()->role())) {
throw new \Exception('You are not authorized to perform this action.');
}
$this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => Role::ADMIN->value]);
$teamId = currentTeam()->id;
$this->member->teams()->updateExistingPivot($teamId, ['role' => Role::ADMIN->value]);
RevokeUserTeamTokens::forUserTeam($this->member, $teamId);
$this->dispatch('reloadWindow');
} catch (\Exception $e) {
$this->dispatch('error', $e->getMessage());
@@ -39,7 +42,9 @@ class Member extends Component
|| Role::from($this->getMemberRole())->gt(auth()->user()->role())) {
throw new \Exception('You are not authorized to perform this action.');
}
$this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => Role::OWNER->value]);
$teamId = currentTeam()->id;
$this->member->teams()->updateExistingPivot($teamId, ['role' => Role::OWNER->value]);
RevokeUserTeamTokens::forUserTeam($this->member, $teamId);
$this->dispatch('reloadWindow');
} catch (\Exception $e) {
$this->dispatch('error', $e->getMessage());
@@ -55,7 +60,9 @@ class Member extends Component
|| Role::from($this->getMemberRole())->gt(auth()->user()->role())) {
throw new \Exception('You are not authorized to perform this action.');
}
$this->member->teams()->updateExistingPivot(currentTeam()->id, ['role' => Role::MEMBER->value]);
$teamId = currentTeam()->id;
$this->member->teams()->updateExistingPivot($teamId, ['role' => Role::MEMBER->value]);
RevokeUserTeamTokens::forUserTeam($this->member, $teamId);
$this->dispatch('reloadWindow');
} catch (\Exception $e) {
$this->dispatch('error', $e->getMessage());
@@ -73,6 +80,7 @@ class Member extends Component
}
$teamId = currentTeam()->id;
$this->member->teams()->detach(currentTeam());
RevokeUserTeamTokens::forUserTeam($this->member, $teamId);
// Clear cache for the removed user - both old and new key formats
Cache::forget("team:{$this->member->id}");
Cache::forget("user:{$this->member->id}:team:{$teamId}");