Merge remote-tracking branch 'origin/main' into next

This commit is contained in:
github-actions[bot]
2026-10-30 11:16:06 +00:00
15 changed files with 307 additions and 78 deletions
+37 -1
View File
@@ -10,6 +10,7 @@ use App\Models\ApplicationSetting;
use App\Models\Environment;
use App\Models\EnvironmentVariable;
use App\Models\ServerSetting;
use App\Models\Service;
use App\Models\StandaloneDocker;
use App\Models\SwarmDocker;
use App\Rules\ManualWebhookSecret;
@@ -178,6 +179,41 @@ function exposeSensitiveFields(Model $model): Model
return $model;
}
/**
* Hide the locked (shown once) values that a serialized resource still contains, also for tokens
* that can read sensitive data: the generated compose of an application or service, and the
* connection URLs of a database with a locked password.
*
* @template T of array|SupportCollection
*
* @param T $payload
* @return T
*/
function redactLockedApiResourceValues(Model $resource, array|SupportCollection $payload): array|SupportCollection
{
if (($resource instanceof Application || $resource instanceof Service) && filled($payload['docker_compose'] ?? null)) {
$payload['docker_compose'] = redactLockedValuesInGeneratedCompose($payload['docker_compose'], $resource);
}
$urlKeys = array_filter(['internal_db_url', 'external_db_url'], fn (string $key): bool => filled($payload[$key] ?? null));
if ($urlKeys !== [] && method_exists($resource, 'isCredentialLocked') && $resource->isCredentialLocked()) {
foreach ($urlKeys as $key) {
$payload[$key] = null;
}
}
return $payload;
}
/**
* Serialize a resource for a list API response: sensitive fields when the token can read them,
* without locked values.
*/
function serializeApiResource(Model $resource): array
{
return redactLockedApiResourceValues($resource, exposeSensitiveFields($resource)->toArray());
}
/**
* Shared validation rules for application create and update API endpoints.
*
@@ -244,7 +280,7 @@ function sharedDataApplications(?Application $application = null): array
'build_command' => ValidationPatterns::shellSafeCommandRules(),
'start_command' => ValidationPatterns::shellSafeCommandRules(),
'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/',
'ports_mappings' => 'string|regex:/^(\d+:\d+)(,\d+:\d+)*$/|nullable',
'ports_mappings' => ValidationPatterns::portMappingRules(),
'custom_network_aliases' => 'string|nullable',
'base_directory' => ValidationPatterns::directoryPathRules(),
'publish_directory' => ValidationPatterns::directoryPathRules(),