From 2289de4489acef4a009f07ffc9e6ef62e579f2a6 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 24 Aug 2026 10:42:04 +0200 Subject: [PATCH] fix(audit): prevent duplicate API update events Suppress model audit logging during API application saves while preserving the explicit event, and improve audit log actor display spacing and token tooltips. --- .../Api/ApplicationsController.php | 2 +- app/Traits/Auditable.php | 16 +++++++++- .../views/livewire/team/audit-log.blade.php | 9 +++--- tests/Feature/AuditEventsTest.php | 32 +++++++++++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index b47db0e26f..aa5bceebb4 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -3122,7 +3122,7 @@ class ApplicationsController extends Controller if ($application->settings->is_container_label_readonly_enabled && ($requestHasDomains || $requestHasNoindexDomains || $requestHasHttpBasicAuth) && $server->isProxyShouldRun()) { $application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n"); } - $application->save(); + $application->withoutAuditLogging(fn () => $application->save()); auditLog('api.application.updated', [ 'team_id' => $teamId, diff --git a/app/Traits/Auditable.php b/app/Traits/Auditable.php index f0873be377..0b065db44e 100644 --- a/app/Traits/Auditable.php +++ b/app/Traits/Auditable.php @@ -4,11 +4,14 @@ namespace App\Traits; use App\Models\PersonalAccessToken; use App\Models\Team; +use Closure; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; trait Auditable { + private bool $auditLoggingEnabled = true; + public static function bootAuditable(): void { static::created(fn (Model $model) => $model->recordAuditMutation('created')); @@ -18,7 +21,7 @@ trait Auditable private function recordAuditMutation(string $action): void { - if (! auth()->check()) { + if (! $this->auditLoggingEnabled || ! auth()->check()) { return; } @@ -54,6 +57,17 @@ trait Auditable ]); } + public function withoutAuditLogging(Closure $callback): mixed + { + $this->auditLoggingEnabled = false; + + try { + return $callback(); + } finally { + $this->auditLoggingEnabled = true; + } + } + private function auditTeamId(): ?int { if ($this instanceof Team) { diff --git a/resources/views/livewire/team/audit-log.blade.php b/resources/views/livewire/team/audit-log.blade.php index d561e586a6..64bd1fa75c 100644 --- a/resources/views/livewire/team/audit-log.blade.php +++ b/resources/views/livewire/team/audit-log.blade.php @@ -37,7 +37,7 @@