fix(api): hide application compose PR fields

Add compose PR fields to the Application hidden attributes and allow database list queries to eager load nested server settings when sensitive access is permitted.
This commit is contained in:
Andras Bacsai 2026-05-11 11:46:05 +02:00
parent ffa494d391
commit c97f916052
7 changed files with 41 additions and 14 deletions

View file

@ -20,6 +20,7 @@
use App\Models\Server;
use App\Models\StandalonePostgresql;
use App\Support\ValidationPatterns;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
@ -59,7 +60,7 @@ private function removeSensitiveData($database)
* Expose sensitive fields on eager-loaded nested Server + ServerSetting
* relations for callers with the `read:sensitive` or `root` token ability.
*/
private function exposeNestedServerSecrets($model): void
private function exposeNestedServerSecrets(Model $model): void
{
$server = $model->destination?->server ?? null;
if (! $server) {
@ -118,8 +119,12 @@ public function databases(Request $request)
}
$projects = Project::where('team_id', $teamId)->get();
$databases = collect();
$databaseRelations = $request->attributes->get('can_read_sensitive', false) === true
? ['destination.server.settings']
: [];
foreach ($projects as $project) {
$databases = $databases->merge($project->databases());
$databases = $databases->merge($project->databases($databaseRelations));
}
$databaseIds = $databases->pluck('id')->toArray();

View file

@ -229,7 +229,9 @@ class Application extends BaseModel
'manual_webhook_secret_gitea',
'dockerfile',
'docker_compose',
'docker_compose_pr',
'docker_compose_raw',
'docker_compose_pr_raw',
'custom_labels',
];

View file

@ -5,6 +5,7 @@
use App\Traits\ClearsGlobalSearchCache;
use App\Traits\HasSafeStringAttribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Collection;
use OpenApi\Attributes as OA;
use Visus\Cuid2\Cuid2;
@ -156,9 +157,16 @@ public function isEmpty()
$this->services()->count() == 0;
}
public function databases()
public function databases(array $with = []): Collection
{
return $this->postgresqls()->get()->merge($this->redis()->get())->merge($this->mongodbs()->get())->merge($this->mysqls()->get())->merge($this->mariadbs()->get())->merge($this->keydbs()->get())->merge($this->dragonflies()->get())->merge($this->clickhouses()->get());
return $this->postgresqls()->with($with)->get()
->merge($this->redis()->with($with)->get())
->merge($this->mongodbs()->with($with)->get())
->merge($this->mysqls()->with($with)->get())
->merge($this->mariadbs()->with($with)->get())
->merge($this->keydbs()->with($with)->get())
->merge($this->dragonflies()->with($with)->get())
->merge($this->clickhouses()->with($with)->get());
}
public function navigateTo()

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -196,4 +196,14 @@ function makeTeamUser(): array
expect($body)->toContain('"internal_db_url":');
expect($body)->toContain('"sentinel_token":');
});
test('project database list can eager load nested destination server settings', function () {
$databases = $this->project->databases(['destination.server.settings']);
$database = $databases->firstWhere('id', $this->database->id);
expect($database)->not->toBeNull()
->and($database->relationLoaded('destination'))->toBeTrue()
->and($database->destination->relationLoaded('server'))->toBeTrue()
->and($database->destination->server->relationLoaded('settings'))->toBeTrue();
});
});

View file

@ -48,7 +48,9 @@
'manual_webhook_secret_gitea',
'dockerfile',
'docker_compose',
'docker_compose_pr',
'docker_compose_raw',
'docker_compose_pr_raw',
'custom_labels',
);
});