diff --git a/client/src/app/models/profile.model.ts b/client/src/app/models/profile.model.ts index ce0876c..041bc6d 100644 --- a/client/src/app/models/profile.model.ts +++ b/client/src/app/models/profile.model.ts @@ -4,4 +4,6 @@ export class Profile { public expiration: Date; public currentVersion: string; public latestVersion: string; + public isInsecure: boolean; + public disableUpdateNotification: boolean; } diff --git a/client/src/app/navbar/navbar.component.html b/client/src/app/navbar/navbar.component.html index 7a3ee62..a8a3b9f 100644 --- a/client/src/app/navbar/navbar.component.html +++ b/client/src/app/navbar/navbar.component.html @@ -62,9 +62,15 @@
- Version {{ profile.latestVersion }} of RealDebrid Client was found. You are currently on version - {{ profile.currentVersion }}. + + Your current version is insecure. + + + Version {{ profile.latestVersion }} of RealDebrid Client was found. You are currently on version + {{ profile.currentVersion }}. +
diff --git a/server/RdtClient.Data/Models/Internal/DbSettings.cs b/server/RdtClient.Data/Models/Internal/DbSettings.cs index 698b2b5..5ad2a57 100644 --- a/server/RdtClient.Data/Models/Internal/DbSettings.cs +++ b/server/RdtClient.Data/Models/Internal/DbSettings.cs @@ -74,6 +74,10 @@ Supports the following parameters: [DisplayName("Copy added torrent files")] [Description("When a torrent file or magnet is added, create a copy in this directory.")] public String? CopyAddedTorrents { get; set; } = null; + + [DisplayName("Disable update notifications")] + [Description("Ignore update notifications. You will still be notified if the version you are running has a security vulnerability.")] + public Boolean DisableUpdateNotifications { get; set; } = false; } public class DbSettingsDownloadClient diff --git a/server/RdtClient.Data/Models/Internal/Profile.cs b/server/RdtClient.Data/Models/Internal/Profile.cs index f09d77a..0f5ae9c 100644 --- a/server/RdtClient.Data/Models/Internal/Profile.cs +++ b/server/RdtClient.Data/Models/Internal/Profile.cs @@ -7,4 +7,6 @@ public class Profile public DateTimeOffset? Expiration { get; set; } public String? CurrentVersion { get; set; } public String? LatestVersion { get; set; } + public Boolean? IsInsecure { get; set; } + public Boolean? DisableUpdateNotification { get; set; } } \ No newline at end of file diff --git a/server/RdtClient.Service/BackgroundServices/UpdateChecker.cs b/server/RdtClient.Service/BackgroundServices/UpdateChecker.cs index 846c000..95de08b 100644 --- a/server/RdtClient.Service/BackgroundServices/UpdateChecker.cs +++ b/server/RdtClient.Service/BackgroundServices/UpdateChecker.cs @@ -9,6 +9,11 @@ public class UpdateChecker(ILogger logger) : BackgroundService { public static String? CurrentVersion { get; private set; } public static String? LatestVersion { get; private set; } + + public static Boolean? IsInsecure { get; private set; } + + private static readonly List KnownGhsaIds = [ + ]; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { @@ -34,18 +39,9 @@ public class UpdateChecker(ILogger logger) : BackgroundService { try { - var httpClient = new HttpClient(); - httpClient.DefaultRequestHeaders.UserAgent.Add(new("RdtClient", CurrentVersion)); - var response = await httpClient.GetStringAsync($"https://api.github.com/repos/rogerfar/rdt-client/tags?per_page=1", stoppingToken); + var gitHubReleases = await GitHubRequest>("/repos/rogerfar/rdt-client/tags?per_page=1", stoppingToken); - var gitHubReleases = JsonConvert.DeserializeObject>(response); - - if (gitHubReleases == null || gitHubReleases.Count == 0) - { - return; - } - - var latestRelease = gitHubReleases.FirstOrDefault(m => m.Name != null)?.Name; + var latestRelease = gitHubReleases?.FirstOrDefault(m => m.Name != null)?.Name; if (latestRelease == null) { @@ -59,6 +55,18 @@ public class UpdateChecker(ILogger logger) : BackgroundService } LatestVersion = latestRelease; + + var gitHubSecurityAdvisories = await GitHubRequest>("/repos/rogerfar/rdt-client/security-advisories", stoppingToken); + + var unseenGhsaIds = gitHubSecurityAdvisories?.Where(advisory => !KnownGhsaIds.Contains(advisory.GhsaId)); + + if (unseenGhsaIds == null) + { + logger.LogWarning($"Unable to find security advisories on GitHub"); + return; + } + + IsInsecure = unseenGhsaIds.Any(); } catch (Exception ex) { @@ -70,10 +78,25 @@ public class UpdateChecker(ILogger logger) : BackgroundService logger.LogInformation("UpdateChecker stopped."); } + + private async Task GitHubRequest(String endpoint, CancellationToken cancellationToken) + { + var httpClient = new HttpClient(); + httpClient.DefaultRequestHeaders.UserAgent.Add(new("RdtClient", CurrentVersion)); + var response = await httpClient.GetStringAsync($"https://api.github.com{endpoint}", cancellationToken); + + return JsonConvert.DeserializeObject(response); + } } public class GitHubReleasesResponse { [JsonProperty("name")] public String? Name { get; set; } +} + +public class GitHubSecurityAdvisoriesResponse +{ + [JsonProperty("ghsa_id")] + public required String GhsaId { get; set; } } \ No newline at end of file diff --git a/server/RdtClient.Service/Services/Torrents.cs b/server/RdtClient.Service/Services/Torrents.cs index a88087a..9004cb3 100644 --- a/server/RdtClient.Service/Services/Torrents.cs +++ b/server/RdtClient.Service/Services/Torrents.cs @@ -413,7 +413,9 @@ public class Torrents( UserName = user.Username, Expiration = user.Expiration, CurrentVersion = UpdateChecker.CurrentVersion, - LatestVersion = UpdateChecker.LatestVersion + LatestVersion = UpdateChecker.LatestVersion, + IsInsecure = UpdateChecker.IsInsecure, + DisableUpdateNotification = Settings.Get.General.DisableUpdateNotifications }; return profile;