From 5dc55a9d1c8ec3142abfd2ada094f0bfe33f82b1 Mon Sep 17 00:00:00 2001 From: boban Date: Mon, 27 Apr 2026 02:21:42 +0200 Subject: [PATCH] Fix: Update-Erkennung via Gitea-API + Fallback-Kette verbessert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - CheckUpdates: Gitea REST-API als neuen Fallback (funktioniert ohne Auth bei öffentlichem Repo), git ls-remote als weiterer Fallback - $remoteFile vor dem Fallback-Block deklariert (undefined variable fix) - UpdateCard + UpdatePage: latNorm aus Cache normalisieren → kein doppeltes "v" - UpdateCard: openLogs()-Methode hinzugefügt (Logs-Button im Dashboard) - Setup-Wizard: Zeitzone automatisch aus Browser-Intl erkannt (@script) Co-Authored-By: Claude Sonnet 4.6 --- app/Console/Commands/CheckUpdates.php | 61 +++++++++++++++++-- app/Livewire/Ui/System/UpdateCard.php | 7 ++- app/Livewire/Ui/System/UpdatePage.php | 2 +- .../views/livewire/setup/wizard.blade.php | 8 +++ 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/app/Console/Commands/CheckUpdates.php b/app/Console/Commands/CheckUpdates.php index 2d6f0b5..04e9e85 100644 --- a/app/Console/Commands/CheckUpdates.php +++ b/app/Console/Commands/CheckUpdates.php @@ -14,12 +14,15 @@ class CheckUpdates extends Command $currentNorm = $this->readInstalledVersionNorm(); $currentRaw = $this->readInstalledVersionRaw() ?? ($currentNorm ? 'v'.$currentNorm : null); - $appPath = base_path(); + $appPath = base_path(); + $remoteFile = '/var/lib/mailwolt/version_remote'; // Fallback-Kette für Remote-Tags (erste funktionierende Methode gewinnt): // 1. mailwolt-update --check-only (sudoers: mailwolt-update) // 2. mailwolt-fetch-tags (sudoers: mailwolt-fetch-tags) - // 3. git fetch --tags als App-User direkt + // 3. Gitea/GitHub API (kein Auth nötig wenn Repo öffentlich) + // 4. git ls-remote (klappt wenn Credentials im git-Config) + // 5. git fetch --tags direkt $updateBin = '/usr/local/sbin/mailwolt-update'; $fetchHelper = '/usr/local/sbin/mailwolt-fetch-tags'; @@ -35,13 +38,63 @@ class CheckUpdates extends Command $fetched = ($rc === 0); } - // Direkter git fetch als Fallback (klappt wenn Credentials im Repo hinterlegt sind) + // Gitea/GitHub API – funktioniert ohne Credentials wenn Repo öffentlich + if (!$fetched) { + $remoteUrl = trim((string) @shell_exec('git -C ' . escapeshellarg($appPath) . ' remote get-url origin 2>/dev/null')); + if (preg_match('~https?://([^/]+)/([^/]+/[^/]+?)(?:\.git)?$~', $remoteUrl, $rm)) { + $host = $rm[1]; + $project = $rm[2]; + // Gitea API + $apiUrl = "https://{$host}/api/v1/repos/{$project}/tags?limit=50"; + $ctx = stream_context_create(['http' => ['timeout' => 5, 'ignore_errors' => true]]); + $json = @file_get_contents($apiUrl, false, $ctx); + if ($json) { + $tags = json_decode($json, true); + if (is_array($tags)) { + $versions = []; + foreach ($tags as $t) { + $name = $t['name'] ?? ''; + if (preg_match('/^v[\d.]+$/', $name)) { + $versions[] = $name; + } + } + usort($versions, 'version_compare'); + $latest = end($versions); + if ($latest) { + @mkdir(dirname($remoteFile), 0755, true); + file_put_contents($remoteFile, $latest); + $fetched = true; + } + } + } + } + } + + // git ls-remote (klappt wenn Credentials im git-Config hinterlegt sind) + if (!$fetched) { + $lsOut = []; + @exec('git -C ' . escapeshellarg($appPath) . ' ls-remote --tags origin \'v*\' 2>/dev/null', $lsOut); + $lsVersions = []; + foreach ($lsOut as $line) { + if (preg_match('~refs/tags/(v[\d.]+)$~', $line, $m)) { + $lsVersions[] = $m[1]; + } + } + if (!empty($lsVersions)) { + usort($lsVersions, 'version_compare'); + $latest = end($lsVersions); + @mkdir(dirname($remoteFile), 0755, true); + file_put_contents($remoteFile, $latest); + $fetched = true; + } + } + + // Direkter git fetch als letzter Fallback if (!$fetched) { @exec('git -C ' . escapeshellarg($appPath) . ' fetch --tags origin 2>/dev/null', $_, $rc); } // version_remote von Helfer geschrieben; als frisch wenn < 2h alt - $remoteFile = '/var/lib/mailwolt/version_remote'; $remoteRaw = ''; if (file_exists($remoteFile) && (time() - filemtime($remoteFile)) < 7200) { $remoteRaw = trim((string) file_get_contents($remoteFile)); diff --git a/app/Livewire/Ui/System/UpdateCard.php b/app/Livewire/Ui/System/UpdateCard.php index 7951932..8d04fc0 100644 --- a/app/Livewire/Ui/System/UpdateCard.php +++ b/app/Livewire/Ui/System/UpdateCard.php @@ -93,6 +93,11 @@ class UpdateCard extends Component $this->recomputeUi(); } + public function openLogs(): void + { + $this->dispatch('openModal', component: 'ui.system.modal.update-modal'); + } + public function refreshVersions(): void { if ($this->state === 'running') return; @@ -218,7 +223,7 @@ class UpdateCard extends Component // Update-Checker schreibt: // - updates:latest (normiert) // - updates:latest_raw (original) - $latNorm = Cache::get('updates:latest'); + $latNorm = $this->normalizeVersion(Cache::get('updates:latest') ?? ''); $latRaw = Cache::get('updates:latest_raw'); // Legacy-Fallback diff --git a/app/Livewire/Ui/System/UpdatePage.php b/app/Livewire/Ui/System/UpdatePage.php index 10a2ee6..549c4d9 100644 --- a/app/Livewire/Ui/System/UpdatePage.php +++ b/app/Livewire/Ui/System/UpdatePage.php @@ -169,7 +169,7 @@ class UpdatePage extends Component { $this->current = $this->readCurrentVersion(); - $latNorm = Cache::get('updates:latest'); + $latNorm = $this->normalizeVersion(Cache::get('updates:latest') ?? ''); $latRaw = Cache::get('updates:latest_raw'); if (!$latNorm && ($legacy = Cache::get('mailwolt.update_available'))) { diff --git a/resources/views/livewire/setup/wizard.blade.php b/resources/views/livewire/setup/wizard.blade.php index b5261d0..b3cc792 100644 --- a/resources/views/livewire/setup/wizard.blade.php +++ b/resources/views/livewire/setup/wizard.blade.php @@ -71,6 +71,14 @@ @endforeach + @script + + @endscript {{-- ── Schritt 2: Domains ── --}}