diff --git a/Guard/Core/Icons/IconManager.cs b/Guard/Core/Icons/IconManager.cs index 179dd88..a47b1c1 100644 --- a/Guard/Core/Icons/IconManager.cs +++ b/Guard/Core/Icons/IconManager.cs @@ -18,7 +18,7 @@ internal class TotpIcon public required IconType Type { get; set; } public required string Name { get; set; } public string? Svg { get; set; } - public string? Path { get; set; } + public Uri? Path { get; set; } } private static readonly string customIconsPath = Path.Combine( @@ -60,6 +60,16 @@ public static TotpIcon GetIcon(string name, IconType type) return simpleIcon ?? defaultIcon; } + if (type == IconType.Custom) + { + return new TotpIcon + { + Type = IconType.Custom, + Name = name, + Path = new Uri(Path.Combine(customIconsPath, name)), + }; + } + return defaultIcon; } @@ -72,5 +82,48 @@ public static string GetLicense(TotpIcon icon) } return string.Empty; } + + public static async Task AddCustomIcon(string path) + { + if (!Directory.Exists(customIconsPath)) + { + Directory.CreateDirectory(customIconsPath); + } + + if (!File.Exists(path)) + { + throw new FileNotFoundException("The source file does not exist."); + } + + if (new FileInfo(path).Length > 1000000) + { + throw new Exception(I18n.GetString("i.td.customicon.tolarge")); + } + + string id = Guid.NewGuid().ToString(); + string ext = + Path.GetExtension(path) + ?? throw new Exception("The file extension could not be determined."); + string[] allowedExtensions = [".svg", ".png", ".jpg", ".jpeg"]; + if (!allowedExtensions.Contains(ext)) + { + throw new Exception("The file extension is not allowed."); + } + + string destPath = Path.Combine(customIconsPath, $"{id}{ext}"); + + await Task.Run(() => File.Copy(path, destPath)); + + return $"{id}{ext}"; + } + + public static void RemoveCustomIcon(string name) + { + string path = Path.Combine(customIconsPath, name); + if (File.Exists(path)) + { + File.Delete(path); + } + } } } diff --git a/Guard/Resources/Strings.de.xaml b/Guard/Resources/Strings.de.xaml index 3ea3afa..fdb99bf 100644 --- a/Guard/Resources/Strings.de.xaml +++ b/Guard/Resources/Strings.de.xaml @@ -207,6 +207,9 @@ Der geheime Schlüssel ist ungültig Die Anzahl der Ziffern ist ungültig Die Gültigkeitsdauer ist ungültig + Eigenes Icon + Eigenes Icon auswählen + Ein Icon darf maximal 1 MB groß sein Token diff --git a/Guard/Resources/Strings.en.xaml b/Guard/Resources/Strings.en.xaml index 35df96f..6b82e09 100644 --- a/Guard/Resources/Strings.en.xaml +++ b/Guard/Resources/Strings.en.xaml @@ -207,6 +207,9 @@ The number of digits is invalid The validity period is invalid License + Custom icon + Select an icon + Only images with a maximum size of 1MB are supported Token diff --git a/Guard/Views/Controls/TokenCard.xaml b/Guard/Views/Controls/TokenCard.xaml index 9d5e00e..a86c18c 100644 --- a/Guard/Views/Controls/TokenCard.xaml +++ b/Guard/Views/Controls/TokenCard.xaml @@ -47,7 +47,7 @@ Margin="22,0,0,0" VerticalAlignment="Center"> - + - + + HorizontalAlignment="Center"> + + + +