mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix(api): keep omitted flags when patching application env variables
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
9395c415b3
commit
d9a22ce10e
@@ -4047,95 +4047,28 @@ class ApplicationsController extends Controller
|
||||
], 422);
|
||||
}
|
||||
$is_preview = $request->is_preview ?? false;
|
||||
$is_literal = $request->is_literal ?? false;
|
||||
$key = str($request->key)->trim()->replace(' ', '_')->value;
|
||||
if ($is_preview) {
|
||||
$env = $application->environment_variables_preview->where('key', $key)->first();
|
||||
if ($env) {
|
||||
$env->value = $request->value;
|
||||
if ($env->is_literal != $is_literal) {
|
||||
$env->is_literal = $is_literal;
|
||||
}
|
||||
if ($env->is_preview != $is_preview) {
|
||||
$env->is_preview = $is_preview;
|
||||
}
|
||||
if ($env->is_multiline != $request->is_multiline) {
|
||||
$env->is_multiline = $request->is_multiline;
|
||||
}
|
||||
if ($env->is_shown_once != $request->is_shown_once) {
|
||||
$env->is_shown_once = $request->is_shown_once;
|
||||
}
|
||||
if ($request->has('is_runtime') && $env->is_runtime != $request->is_runtime) {
|
||||
$env->is_runtime = $request->is_runtime;
|
||||
}
|
||||
if ($request->has('is_buildtime') && $env->is_buildtime != $request->is_buildtime) {
|
||||
$env->is_buildtime = $request->is_buildtime;
|
||||
}
|
||||
if ($request->has('comment') && $env->comment != $request->comment) {
|
||||
$env->comment = $request->comment;
|
||||
}
|
||||
$env->save();
|
||||
|
||||
auditLog('api.application.env_updated', [
|
||||
'team_id' => $teamId,
|
||||
'application_uuid' => $application->uuid,
|
||||
'env_uuid' => $env->uuid,
|
||||
'env_key' => $env->key,
|
||||
'is_preview' => (bool) $is_preview,
|
||||
]);
|
||||
|
||||
return response()->json($this->removeSensitiveData($env))->setStatusCode(201);
|
||||
} else {
|
||||
return response()->json([
|
||||
'message' => 'Environment variable not found.',
|
||||
], 404);
|
||||
}
|
||||
} else {
|
||||
$env = $application->environment_variables->where('key', $key)->first();
|
||||
if ($env) {
|
||||
$env->value = $request->value;
|
||||
if ($env->is_literal != $is_literal) {
|
||||
$env->is_literal = $is_literal;
|
||||
}
|
||||
if ($env->is_preview != $is_preview) {
|
||||
$env->is_preview = $is_preview;
|
||||
}
|
||||
if ($env->is_multiline != $request->is_multiline) {
|
||||
$env->is_multiline = $request->is_multiline;
|
||||
}
|
||||
if ($env->is_shown_once != $request->is_shown_once) {
|
||||
$env->is_shown_once = $request->is_shown_once;
|
||||
}
|
||||
if ($request->has('is_runtime') && $env->is_runtime != $request->is_runtime) {
|
||||
$env->is_runtime = $request->is_runtime;
|
||||
}
|
||||
if ($request->has('is_buildtime') && $env->is_buildtime != $request->is_buildtime) {
|
||||
$env->is_buildtime = $request->is_buildtime;
|
||||
}
|
||||
if ($request->has('comment') && $env->comment != $request->comment) {
|
||||
$env->comment = $request->comment;
|
||||
}
|
||||
$env->save();
|
||||
|
||||
auditLog('api.application.env_updated', [
|
||||
'team_id' => $teamId,
|
||||
'application_uuid' => $application->uuid,
|
||||
'env_uuid' => $env->uuid,
|
||||
'env_key' => $env->key,
|
||||
'is_preview' => (bool) $is_preview,
|
||||
]);
|
||||
|
||||
return response()->json($this->removeSensitiveData($env))->setStatusCode(201);
|
||||
} else {
|
||||
return response()->json([
|
||||
'message' => 'Environment variable not found.',
|
||||
], 404);
|
||||
}
|
||||
$environmentVariables = $is_preview ? $application->environment_variables_preview : $application->environment_variables;
|
||||
$env = $environmentVariables->where('key', $key)->first();
|
||||
if (! $env) {
|
||||
return response()->json([
|
||||
'message' => 'Environment variable not found.',
|
||||
], 404);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => 'Something is not okay. Are you okay?',
|
||||
], 500);
|
||||
$env->value = $request->value;
|
||||
$env->fill($request->only(['is_literal', 'is_multiline', 'is_shown_once', 'is_runtime', 'is_buildtime', 'comment']));
|
||||
$env->save();
|
||||
|
||||
auditLog('api.application.env_updated', [
|
||||
'team_id' => $teamId,
|
||||
'application_uuid' => $application->uuid,
|
||||
'env_uuid' => $env->uuid,
|
||||
'env_key' => $env->key,
|
||||
'is_preview' => (bool) $is_preview,
|
||||
]);
|
||||
|
||||
return response()->json($this->removeSensitiveData($env))->setStatusCode(201);
|
||||
}
|
||||
|
||||
#[OA\Patch(
|
||||
@@ -4280,25 +4213,7 @@ class ApplicationsController extends Controller
|
||||
$env = $application->environment_variables_preview()->where('key', $key)->first();
|
||||
if ($env) {
|
||||
$env->value = $item->get('value');
|
||||
|
||||
if ($env->is_literal != $is_literal) {
|
||||
$env->is_literal = $is_literal;
|
||||
}
|
||||
if ($env->is_multiline != $item->get('is_multiline')) {
|
||||
$env->is_multiline = $item->get('is_multiline');
|
||||
}
|
||||
if ($env->is_shown_once != $item->get('is_shown_once')) {
|
||||
$env->is_shown_once = $item->get('is_shown_once');
|
||||
}
|
||||
if ($item->has('is_runtime') && $env->is_runtime != $item->get('is_runtime')) {
|
||||
$env->is_runtime = $item->get('is_runtime');
|
||||
}
|
||||
if ($item->has('is_buildtime') && $env->is_buildtime != $item->get('is_buildtime')) {
|
||||
$env->is_buildtime = $item->get('is_buildtime');
|
||||
}
|
||||
if ($item->has('comment') && $env->comment != $item->get('comment')) {
|
||||
$env->comment = $item->get('comment');
|
||||
}
|
||||
$env->fill($item->only(['is_literal', 'is_multiline', 'is_shown_once', 'is_runtime', 'is_buildtime', 'comment'])->all());
|
||||
$env->save();
|
||||
} else {
|
||||
$env = $application->environment_variables()->create([
|
||||
@@ -4319,24 +4234,7 @@ class ApplicationsController extends Controller
|
||||
$env = $application->environment_variables()->where('key', $key)->first();
|
||||
if ($env) {
|
||||
$env->value = $item->get('value');
|
||||
if ($env->is_literal != $is_literal) {
|
||||
$env->is_literal = $is_literal;
|
||||
}
|
||||
if ($env->is_multiline != $item->get('is_multiline')) {
|
||||
$env->is_multiline = $item->get('is_multiline');
|
||||
}
|
||||
if ($env->is_shown_once != $item->get('is_shown_once')) {
|
||||
$env->is_shown_once = $item->get('is_shown_once');
|
||||
}
|
||||
if ($item->has('is_runtime') && $env->is_runtime != $item->get('is_runtime')) {
|
||||
$env->is_runtime = $item->get('is_runtime');
|
||||
}
|
||||
if ($item->has('is_buildtime') && $env->is_buildtime != $item->get('is_buildtime')) {
|
||||
$env->is_buildtime = $item->get('is_buildtime');
|
||||
}
|
||||
if ($item->has('comment') && $env->comment != $item->get('comment')) {
|
||||
$env->comment = $item->get('comment');
|
||||
}
|
||||
$env->fill($item->only(['is_literal', 'is_multiline', 'is_shown_once', 'is_runtime', 'is_buildtime', 'comment'])->all());
|
||||
$env->save();
|
||||
} else {
|
||||
$env = $application->environment_variables()->create([
|
||||
|
||||
@@ -253,6 +253,78 @@ describe('PATCH /api/v1/applications/{uuid}/envs', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('application env PATCH keeps omitted flags', function () {
|
||||
beforeEach(function () {
|
||||
$this->application = Application::factory()->create([
|
||||
'environment_id' => $this->environment->id,
|
||||
'destination_id' => $this->destination->id,
|
||||
'destination_type' => $this->destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
$this->env = EnvironmentVariable::create([
|
||||
'key' => 'FLAGGED_KEY',
|
||||
'value' => 'old-value',
|
||||
'resourceable_type' => Application::class,
|
||||
'resourceable_id' => $this->application->id,
|
||||
'is_preview' => false,
|
||||
'is_literal' => true,
|
||||
'is_multiline' => true,
|
||||
'is_shown_once' => true,
|
||||
]);
|
||||
|
||||
$this->headers = [
|
||||
'Authorization' => 'Bearer '.$this->bearerToken,
|
||||
'Content-Type' => 'application/json',
|
||||
];
|
||||
});
|
||||
|
||||
test('single update with only key and value keeps flags', function () {
|
||||
$this->withHeaders($this->headers)
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}/envs", [
|
||||
'key' => 'FLAGGED_KEY',
|
||||
'value' => 'new-value',
|
||||
])
|
||||
->assertStatus(201);
|
||||
|
||||
$env = $this->env->fresh();
|
||||
expect($env->value)->toBe('new-value')
|
||||
->and((bool) $env->is_literal)->toBeTrue()
|
||||
->and($env->is_multiline)->toBeTrue()
|
||||
->and((bool) $env->is_shown_once)->toBeTrue();
|
||||
});
|
||||
|
||||
test('bulk update with only key and value keeps flags', function () {
|
||||
$this->withHeaders($this->headers)
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}/envs/bulk", [
|
||||
'data' => [['key' => 'FLAGGED_KEY', 'value' => 'new-value']],
|
||||
])
|
||||
->assertStatus(201);
|
||||
|
||||
$env = $this->env->fresh();
|
||||
expect($env->value)->toBe('new-value')
|
||||
->and((bool) $env->is_literal)->toBeTrue()
|
||||
->and($env->is_multiline)->toBeTrue()
|
||||
->and((bool) $env->is_shown_once)->toBeTrue();
|
||||
});
|
||||
|
||||
test('explicit flags are still applied', function () {
|
||||
$this->withHeaders($this->headers)
|
||||
->patchJson("/api/v1/applications/{$this->application->uuid}/envs", [
|
||||
'key' => 'FLAGGED_KEY',
|
||||
'value' => 'new-value',
|
||||
'is_literal' => false,
|
||||
'is_multiline' => false,
|
||||
'is_shown_once' => false,
|
||||
])
|
||||
->assertStatus(201);
|
||||
|
||||
$env = $this->env->fresh();
|
||||
expect((bool) $env->is_literal)->toBeFalse()
|
||||
->and($env->is_multiline)->toBeFalse()
|
||||
->and((bool) $env->is_shown_once)->toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
describe('environment variable key validation for app and service APIs', function () {
|
||||
test('rejects invalid service environment variable keys on create update and bulk', function () {
|
||||
$service = Service::factory()->create([
|
||||
|
||||
Reference in New Issue
Block a user