mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
fix: require notification and log drain fields only when enabled (#12232)
This commit is contained in:
@@ -22,7 +22,7 @@ class Discord extends Component
|
||||
#[Validate(['boolean'])]
|
||||
public bool $discordEnabled = false;
|
||||
|
||||
#[Validate(['nullable', new SafeWebhookUrl])]
|
||||
#[Validate(['required_if:discordEnabled,true', 'nullable', new SafeWebhookUrl])]
|
||||
public ?string $discordWebhookUrl = null;
|
||||
|
||||
#[Validate(['boolean'])]
|
||||
|
||||
@@ -26,10 +26,10 @@ class Pushover extends Component
|
||||
#[Validate(['boolean'])]
|
||||
public bool $pushoverEnabled = false;
|
||||
|
||||
#[Validate(['nullable', 'string'])]
|
||||
#[Validate(['required_if:pushoverEnabled,true', 'nullable', 'string'])]
|
||||
public ?string $pushoverUserKey = null;
|
||||
|
||||
#[Validate(['nullable', 'string'])]
|
||||
#[Validate(['required_if:pushoverEnabled,true', 'nullable', 'string'])]
|
||||
public ?string $pushoverApiToken = null;
|
||||
|
||||
#[Validate(['boolean'])]
|
||||
|
||||
@@ -27,7 +27,7 @@ class Slack extends Component
|
||||
#[Validate(['boolean'])]
|
||||
public bool $slackEnabled = false;
|
||||
|
||||
#[Validate(['nullable', new SafeWebhookUrl])]
|
||||
#[Validate(['required_if:slackEnabled,true', 'nullable', new SafeWebhookUrl])]
|
||||
public ?string $slackWebhookUrl = null;
|
||||
|
||||
#[Validate(['boolean'])]
|
||||
|
||||
@@ -27,10 +27,10 @@ class Telegram extends Component
|
||||
#[Validate(['boolean'])]
|
||||
public bool $telegramEnabled = false;
|
||||
|
||||
#[Validate(['nullable', 'string'])]
|
||||
#[Validate(['required_if:telegramEnabled,true', 'nullable', 'string'])]
|
||||
public ?string $telegramToken = null;
|
||||
|
||||
#[Validate(['nullable', 'string'])]
|
||||
#[Validate(['required_if:telegramEnabled,true', 'nullable', 'string'])]
|
||||
public ?string $telegramChatId = null;
|
||||
|
||||
#[Validate(['boolean'])]
|
||||
|
||||
@@ -22,7 +22,7 @@ class Webhook extends Component
|
||||
#[Validate(['boolean'])]
|
||||
public bool $webhookEnabled = false;
|
||||
|
||||
#[Validate(['nullable', new SafeWebhookUrl])]
|
||||
#[Validate(['required_if:webhookEnabled,true', 'nullable', new SafeWebhookUrl])]
|
||||
public ?string $webhookUrl = null;
|
||||
|
||||
#[Validate(['boolean'])]
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
]" />
|
||||
<div class="lg:col-span-2">
|
||||
@can('update', $settings)
|
||||
<x-forms.input type="password" required id="discordWebhookUrl" label="Webhook URL"
|
||||
<x-forms.input type="password" :required="$discordEnabled" id="discordWebhookUrl" label="Webhook URL"
|
||||
helper="Create an incoming webhook in your Discord server settings." />
|
||||
@else
|
||||
<x-forms.input disabled label="Webhook URL" value="Hidden (only admins can view)" />
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
<div class="grid gap-4 lg:grid-cols-2">
|
||||
@can('update', $settings)
|
||||
<x-forms.input type="password" required id="pushoverUserKey" label="User key"
|
||||
<x-forms.input type="password" :required="$pushoverEnabled" id="pushoverUserKey" label="User key"
|
||||
helper="Find this in the Pushover dashboard." />
|
||||
<x-forms.input type="password" required id="pushoverApiToken" label="API token"
|
||||
<x-forms.input type="password" :required="$pushoverEnabled" id="pushoverApiToken" label="API token"
|
||||
helper="Create an application in Pushover to generate this token." />
|
||||
@else
|
||||
<x-forms.input disabled label="User key" value="Hidden (only admins can view)" />
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<div class="grid gap-4 lg:grid-cols-2">
|
||||
<div class="lg:col-span-2">
|
||||
@can('update', $settings)
|
||||
<x-forms.input type="password" required id="slackWebhookUrl" label="Webhook URL"
|
||||
<x-forms.input type="password" :required="$slackEnabled" id="slackWebhookUrl" label="Webhook URL"
|
||||
helper="Create an incoming webhook in your Slack app settings." />
|
||||
@else
|
||||
<x-forms.input disabled label="Webhook URL" value="Hidden (only admins can view)" />
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
|
||||
<div class="grid gap-4 lg:grid-cols-2">
|
||||
@can('update', $settings)
|
||||
<x-forms.input type="password" autocomplete="new-password" required id="telegramToken"
|
||||
<x-forms.input type="password" autocomplete="new-password" :required="$telegramEnabled" id="telegramToken"
|
||||
label="Bot API token" helper="Create a bot with BotFather to obtain this token." />
|
||||
<x-forms.input type="password" autocomplete="new-password" required id="telegramChatId"
|
||||
<x-forms.input type="password" autocomplete="new-password" :required="$telegramEnabled" id="telegramChatId"
|
||||
label="Chat ID" helper="Add the bot to your chat, then enter that chat ID." />
|
||||
@else
|
||||
<x-forms.input disabled label="Bot API token" value="Hidden (only admins can view)" />
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<div class="grid gap-4 lg:grid-cols-2">
|
||||
<div class="lg:col-span-2">
|
||||
@can('update', $settings)
|
||||
<x-forms.input type="password" required id="webhookUrl" label="Webhook URL"
|
||||
<x-forms.input type="password" :required="$webhookEnabled" id="webhookUrl" label="Webhook URL"
|
||||
helper="Coolify sends POST requests to this HTTP or HTTPS endpoint." />
|
||||
@else
|
||||
<x-forms.input disabled label="Webhook URL" value="Hidden (only admins can view)" />
|
||||
|
||||
@@ -35,10 +35,10 @@
|
||||
['value' => true, 'label' => 'Enabled'],
|
||||
]"
|
||||
:disabled="$isLogDrainAxiomEnabled || $isLogDrainCustomEnabled || !auth()->user()->can('update', $server)" />
|
||||
<x-forms.input canGate="update" :canResource="$server" type="password" required
|
||||
<x-forms.input canGate="update" :canResource="$server" type="password" :required="$isLogDrainNewRelicEnabled"
|
||||
id="logDrainNewRelicLicenseKey" label="License key"
|
||||
:disabled="$server->isLogDrainEnabled()" />
|
||||
<x-forms.input canGate="update" :canResource="$server" required
|
||||
<x-forms.input canGate="update" :canResource="$server" :required="$isLogDrainNewRelicEnabled"
|
||||
id="logDrainNewRelicBaseUri" label="Endpoint"
|
||||
placeholder="https://log-api.eu.newrelic.com/log/v1"
|
||||
helper="Use the EU or US New Relic Log API endpoint."
|
||||
@@ -54,10 +54,10 @@
|
||||
['value' => true, 'label' => 'Enabled'],
|
||||
]"
|
||||
:disabled="$isLogDrainNewRelicEnabled || $isLogDrainCustomEnabled || !auth()->user()->can('update', $server)" />
|
||||
<x-forms.input canGate="update" :canResource="$server" type="password" required
|
||||
<x-forms.input canGate="update" :canResource="$server" type="password" :required="$isLogDrainAxiomEnabled"
|
||||
id="logDrainAxiomApiKey" label="API key"
|
||||
:disabled="$server->isLogDrainEnabled()" />
|
||||
<x-forms.input canGate="update" :canResource="$server" required
|
||||
<x-forms.input canGate="update" :canResource="$server" :required="$isLogDrainAxiomEnabled"
|
||||
id="logDrainAxiomDatasetName" label="Dataset name"
|
||||
:disabled="$server->isLogDrainEnabled()" />
|
||||
</div>
|
||||
@@ -73,7 +73,7 @@
|
||||
:disabled="$isLogDrainNewRelicEnabled || $isLogDrainAxiomEnabled || !auth()->user()->can('update', $server)" />
|
||||
</div>
|
||||
<div class="grid gap-4 lg:grid-cols-2">
|
||||
<x-forms.textarea canGate="update" :canResource="$server" rows="8" required
|
||||
<x-forms.textarea canGate="update" :canResource="$server" rows="8" :required="$isLogDrainCustomEnabled"
|
||||
id="logDrainCustomConfig" label="Fluent Bit configuration"
|
||||
:disabled="$server->isLogDrainEnabled()" />
|
||||
<x-forms.textarea canGate="update" :canResource="$server" rows="8"
|
||||
|
||||
@@ -209,3 +209,46 @@ it('reverts the discord mention setting to the saved value when saving fails', f
|
||||
|
||||
expect($team->discordNotificationSettings->fresh()->discord_ping_enabled)->toBeTrue();
|
||||
});
|
||||
|
||||
it('saves cleared notification provider fields while the provider is disabled', function (string $component, string $settingsRelation, array $savedSettings, array $properties) {
|
||||
[, $team] = actingAsEnableActionOwner();
|
||||
$team->{$settingsRelation}->update($savedSettings);
|
||||
|
||||
$test = Livewire::test($component);
|
||||
foreach ($properties as $property) {
|
||||
$test->set($property, '');
|
||||
}
|
||||
$test->call('submit')
|
||||
->assertHasNoErrors()
|
||||
->assertDispatched('success');
|
||||
|
||||
$settings = $team->{$settingsRelation}->fresh();
|
||||
foreach (array_keys($savedSettings) as $column) {
|
||||
expect($settings->{$column})->toBeEmpty();
|
||||
}
|
||||
})->with([
|
||||
'discord' => [Discord::class, 'discordNotificationSettings', ['discord_webhook_url' => 'https://discord.com/api/webhooks/1/abc'], ['discordWebhookUrl']],
|
||||
'slack' => [Slack::class, 'slackNotificationSettings', ['slack_webhook_url' => 'https://hooks.slack.com/services/T/B/C'], ['slackWebhookUrl']],
|
||||
'telegram' => [Telegram::class, 'telegramNotificationSettings', ['telegram_token' => '123:abc', 'telegram_chat_id' => '42'], ['telegramToken', 'telegramChatId']],
|
||||
'pushover' => [Pushover::class, 'pushoverNotificationSettings', ['pushover_user_key' => 'user', 'pushover_api_token' => 'token'], ['pushoverUserKey', 'pushoverApiToken']],
|
||||
'webhook' => [Webhook::class, 'webhookNotificationSettings', ['webhook_url' => 'https://hooks.example.com/coolify'], ['webhookUrl']],
|
||||
]);
|
||||
|
||||
it('rejects cleared notification provider fields while the provider is enabled', function (string $component, string $settingsRelation, array $savedSettings, string $property) {
|
||||
[, $team] = actingAsEnableActionOwner();
|
||||
$team->{$settingsRelation}->update($savedSettings);
|
||||
|
||||
Livewire::test($component)
|
||||
->set($property, '')
|
||||
->call('submit')
|
||||
->assertNotDispatched('success')
|
||||
->assertDispatched('error');
|
||||
|
||||
expect($team->{$settingsRelation}->fresh()->{array_keys($savedSettings)[1]})->not->toBeEmpty();
|
||||
})->with([
|
||||
'discord' => [Discord::class, 'discordNotificationSettings', ['discord_enabled' => true, 'discord_webhook_url' => 'https://discord.com/api/webhooks/1/abc'], 'discordWebhookUrl'],
|
||||
'slack' => [Slack::class, 'slackNotificationSettings', ['slack_enabled' => true, 'slack_webhook_url' => 'https://hooks.slack.com/services/T/B/C'], 'slackWebhookUrl'],
|
||||
'telegram' => [Telegram::class, 'telegramNotificationSettings', ['telegram_enabled' => true, 'telegram_token' => '123:abc', 'telegram_chat_id' => '42'], 'telegramToken'],
|
||||
'pushover' => [Pushover::class, 'pushoverNotificationSettings', ['pushover_enabled' => true, 'pushover_user_key' => 'user', 'pushover_api_token' => 'token'], 'pushoverUserKey'],
|
||||
'webhook' => [Webhook::class, 'webhookNotificationSettings', ['webhook_enabled' => true, 'webhook_url' => 'https://hooks.example.com/coolify'], 'webhookUrl'],
|
||||
]);
|
||||
|
||||
@@ -200,3 +200,16 @@ test('the UI does not enable an unsupported custom log drain', function () {
|
||||
|
||||
expect((bool) $this->server->settings->fresh()->is_logdrain_custom_enabled)->toBeFalse();
|
||||
});
|
||||
|
||||
test('the UI saves a cleared custom config while the custom log drain is disabled', function () {
|
||||
$this->actingAs($this->user);
|
||||
$this->server->settings->update(['logdrain_custom_config' => SAFE_CUSTOM_LOG_DRAIN_CONFIG]);
|
||||
|
||||
Livewire::test(LogDrains::class, ['server_uuid' => $this->server->uuid])
|
||||
->set('logDrainCustomConfig', '')
|
||||
->call('submit')
|
||||
->assertHasNoErrors()
|
||||
->assertDispatched('success');
|
||||
|
||||
expect($this->server->settings->fresh()->logdrain_custom_config)->toBeEmpty();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user