Fix: Version downgrade prevention - validate cache and add running version checks

## Changes
- **CheckForUpdatesJob**: Add triple version comparison (CDN vs cache vs running)
  - Never allows version downgrade from currently running version
  - Uses data_set() for safer nested array mutation
  - Prevents incorrect new_version_available flag setting

- **UpdateCoolify**: Add cache validation before fallback
  - Validates cache against running version on CDN failure
  - Throws exception if cache is corrupted/older than running
  - Applies to both manual and automated updates

- **Tests**: Add comprehensive test coverage
  - tests/Unit/CheckForUpdatesJobTest.php (5 tests)
  - tests/Unit/UpdateCoolifyTest.php (3 tests)

## Impact
- Prevents all downgrade scenarios (CDN rollback, corrupted cache, etc.)
- Maintains backward compatibility
- Provides clear logging for debugging

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras BacsaiandClaude committed 2025-11-28 16:05:41 +01:00
1 parent d9774d2968
commit cd10796612
4 files changed
+377 -11

No files matched your search

+23 -7
View File
@@ -38,19 +38,35 @@ class CheckForUpdatesJob implements ShouldBeEncrypted, ShouldQueue
$existingCoolifyVersion = data_get($existingVersions, 'coolify.v4.version');
}
// Detect CDN serving older Coolify version
if ($existingCoolifyVersion && version_compare($latest_version, $existingCoolifyVersion, '<')) {
Log::warning('CDN served older Coolify version', [
// Determine the BEST version to use (CDN, cache, or current)
$bestVersion = $latest_version;
// Check if cache has newer version than CDN
if ($existingCoolifyVersion && version_compare($existingCoolifyVersion, $bestVersion, '>')) {
Log::warning('CDN served older Coolify version than cache', [
'cdn_version' => $latest_version,
'cached_version' => $existingCoolifyVersion,
'current_version' => $current_version,
]);
// Keep the NEWER Coolify version from cache, but update other components
$versions['coolify']['v4']['version'] = $existingCoolifyVersion;
$latest_version = $existingCoolifyVersion;
$bestVersion = $existingCoolifyVersion;
}
// CRITICAL: Never allow bestVersion to be older than currently running version
if (version_compare($bestVersion, $current_version, '<')) {
Log::warning('Version downgrade prevented in CheckForUpdatesJob', [
'cdn_version' => $latest_version,
'cached_version' => $existingCoolifyVersion,
'current_version' => $current_version,
'attempted_best' => $bestVersion,
'using' => $current_version,
]);
$bestVersion = $current_version;
}
// Use data_set() for safe mutation (fixes #3)
data_set($versions, 'coolify.v4.version', $bestVersion);
$latest_version = $bestVersion;
// ALWAYS write versions.json (for Sentinel, Helper, Traefik updates)
File::put(base_path('versions.json'), json_encode($versions, JSON_PRETTY_PRINT));