Initial v2 launch notification.

This commit is contained in:
Burak Kaan Köse
2026-04-25 16:12:49 +02:00
parent 3ea8b8ac46
commit 55ae6e1f3a
5 changed files with 58 additions and 10 deletions
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Serilog;
using Wino.Core.Domain.Interfaces;
@@ -14,13 +15,16 @@ public sealed class ReleaseLocalAccountDataCleanupService
private readonly IConfigurationService _configurationService;
private readonly IApplicationConfiguration _applicationConfiguration;
private readonly INotificationBuilder _notificationBuilder;
private readonly ILogger _logger = Log.ForContext<ReleaseLocalAccountDataCleanupService>();
public ReleaseLocalAccountDataCleanupService(IConfigurationService configurationService,
IApplicationConfiguration applicationConfiguration)
IApplicationConfiguration applicationConfiguration,
INotificationBuilder notificationBuilder)
{
_configurationService = configurationService;
_applicationConfiguration = applicationConfiguration;
_notificationBuilder = notificationBuilder;
}
public async Task RunIfNeededAsync()
@@ -45,44 +49,70 @@ public sealed class ReleaseLocalAccountDataCleanupService
Path.Combine(publisherPath, LegacyDatabaseFileName)
};
var hadLegacyData = false;
foreach (var targetPath in cleanupTargets)
{
await DeletePathIfExistsAsync(localFolderPath, targetPath).ConfigureAwait(false);
hadLegacyData |= await DeletePathIfExistsAsync(targetPath, localFolderPath, publisherPath).ConfigureAwait(false);
}
_configurationService.Set(CleanupCompletedSettingKey, true);
if (hadLegacyData)
{
_notificationBuilder.CreateReleaseMigrationNotification();
}
_logger.Information("Completed one-time local account data cleanup for release migration.");
}
private async Task DeletePathIfExistsAsync(string localFolderPath, string targetPath)
private async Task<bool> DeletePathIfExistsAsync(string targetPath, params string[] allowedRootPaths)
{
try
{
var fullTargetPath = Path.GetFullPath(targetPath);
var fullLocalFolderPath = Path.GetFullPath(localFolderPath);
if (!fullTargetPath.StartsWith(fullLocalFolderPath, StringComparison.OrdinalIgnoreCase))
if (!allowedRootPaths.Any(rootPath => IsPathUnderAllowedRoot(fullTargetPath, rootPath)))
{
_logger.Warning("Skipped startup cleanup for path outside local folder: {TargetPath}", fullTargetPath);
return;
_logger.Warning("Skipped startup cleanup for path outside allowed roots: {TargetPath}", fullTargetPath);
return false;
}
var targetExists = Directory.Exists(fullTargetPath) || File.Exists(fullTargetPath);
if (Directory.Exists(fullTargetPath))
{
await Task.Run(() => Directory.Delete(fullTargetPath, recursive: true)).ConfigureAwait(false);
_logger.Information("Deleted legacy startup cleanup directory {TargetPath}", fullTargetPath);
return;
return true;
}
if (File.Exists(fullTargetPath))
{
File.Delete(fullTargetPath);
_logger.Information("Deleted legacy startup cleanup file {TargetPath}", fullTargetPath);
return true;
}
return targetExists;
}
catch (Exception ex)
{
_logger.Warning(ex, "Failed to delete legacy startup cleanup path {TargetPath}", targetPath);
}
return false;
}
private static bool IsPathUnderAllowedRoot(string fullTargetPath, string rootPath)
{
if (string.IsNullOrWhiteSpace(rootPath))
return false;
var fullRootPath = Path.GetFullPath(rootPath);
var relativePath = Path.GetRelativePath(fullRootPath, fullTargetPath);
return relativePath != "." &&
!relativePath.StartsWith("..", StringComparison.Ordinal) &&
!Path.IsPathRooted(relativePath);
}
}