From 64bcfe74e79e9393df86e04205dbc649eac91484 Mon Sep 17 00:00:00 2001 From: Marcel Baumgartner Date: Thu, 1 Feb 2024 14:57:10 +0100 Subject: [PATCH] Refactored whole solution to use the MoonCore and MoonCoreUI library --- .../Actions/Dummy/DummyServiceDefinition.cs | 1 - Moonlight/Core/Configuration/ConfigV1.cs | 2 +- Moonlight/Core/Database/DataContext.cs | 6 +- Moonlight/Core/Exceptions/DisplayException.cs | 16 - .../Attributes/SelectorAttribute.cs | 8 - .../ConfigurationBuilderExtensions.cs | 13 - Moonlight/Core/Helpers/ComponentHelper.cs | 23 -- Moonlight/Core/Helpers/Formatter.cs | 280 ------------------ Moonlight/Core/Helpers/HashHelper.cs | 172 ----------- Moonlight/Core/Helpers/HttpApiClient.cs | 117 -------- .../Helpers/LogMigrator/LogMigrateProvider.cs | 11 - .../Core/Helpers/LogMigrator/MigrateLogger.cs | 53 ---- Moonlight/Core/Helpers/Logger.cs | 112 ------- Moonlight/Core/Helpers/PathBuilder.cs | 34 --- Moonlight/Core/Helpers/PropBinder.cs | 57 ---- Moonlight/Core/Helpers/ValidatorHelper.cs | 33 --- Moonlight/Core/Helpers/WsPacketConnection.cs | 124 -------- .../Controllers/Api/AssetProxyController.cs | 2 +- .../Controllers/Api/Auth/ResetController.cs | 3 +- .../Controllers/Api/Auth/VerifyController.cs | 2 +- .../Http/Controllers/Api/BucketController.cs | 2 +- .../{Repository.cs => GenericRepository.cs} | 15 +- .../Background/AutoMailSendService.cs | 10 +- Moonlight/Core/Services/BucketService.cs | 4 +- Moonlight/Core/Services/ConfigService.cs | 102 ------- Moonlight/Core/Services/IdentityService.cs | 8 +- .../Core/Services/Interop/AlertService.cs | 50 ---- .../Core/Services/Interop/ClipboardService.cs | 18 -- .../Core/Services/Interop/CookieService.cs | 63 ---- .../Services/Interop/FileDownloadService.cs | 34 --- .../Core/Services/Interop/ModalService.cs | 37 --- .../Core/Services/Interop/ToastService.cs | 55 ---- Moonlight/Core/Services/MailService.cs | 10 +- Moonlight/Core/Services/MoonlightService.cs | 16 +- Moonlight/Core/Services/PluginService.cs | 2 +- Moonlight/Core/Services/SessionService.cs | 4 +- .../Core/Services/Users/UserAuthService.cs | 16 +- .../Core/Services/Users/UserDeleteService.cs | 5 +- .../Core/Services/Users/UserDetailsService.cs | 7 +- Moonlight/Core/Services/Users/UserService.cs | 8 +- .../Core/Services/Utils/ConnectionService.cs | 10 +- Moonlight/Core/Services/Utils/JwtService.cs | 10 +- .../UI/Components/Auth/ChangePassword.razor | 2 +- Moonlight/Core/UI/Components/Auth/Login.razor | 2 +- .../Core/UI/Components/Auth/Register.razor | 4 +- .../Core/UI/Components/Forms/AutoCrud.razor | 242 --------------- .../Core/UI/Components/Forms/AutoForm.razor | 27 -- .../UI/Components/Forms/AutoListCrud.razor | 255 ---------------- .../UI/Components/Forms/AutoProperty.razor | 157 ---------- .../UI/Components/Forms/ConfirmButton.razor | 66 ----- .../Forms/DynamicTypedAutoForm.razor | 20 -- .../Forms/SmartCustomFileSelect.razor | 58 ---- .../UI/Components/Forms/SmartDropdown.razor | 141 --------- .../UI/Components/Forms/SmartEnumSelect.razor | 27 -- .../UI/Components/Forms/SmartFileSelect.razor | 59 ---- .../Core/UI/Components/Forms/SmartForm.razor | 132 --------- .../UI/Components/Forms/SmartSelect.razor | 71 ----- .../Core/UI/Components/Forms/TextEditor.razor | 2 +- .../Core/UI/Components/Forms/WButton.razor | 48 --- .../UI/Components/Partials/LazyLoader.razor | 67 ----- .../UI/Components/Partials/PageHeader.razor | 6 +- .../UI/Components/Partials/SmartModal.razor | 46 --- .../Partials/SoftErrorHandler.razor | 4 +- Moonlight/Core/UI/Layouts/MainLayout.razor | 6 +- Moonlight/Core/UI/Views/Account/Index.razor | 5 +- .../Core/UI/Views/Account/Payments.razor | 11 +- .../Core/UI/Views/Account/Security.razor | 4 +- .../Core/UI/Views/Admin/Sys/Diagnose.razor | 2 +- .../Core/UI/Views/Admin/Sys/Settings.razor | 9 +- .../Core/UI/Views/Admin/Users/Index.razor | 4 +- .../Core/UI/Views/Admin/Users/Sessions.razor | 2 +- .../Core/UI/Views/Admin/Users/View.razor | 10 +- .../Advertisement/Services/AdBlockService.cs | 4 +- .../Community/Services/PostService.cs | 6 +- .../UI/Components/CreatePostModal.razor | 2 +- .../Community/UI/Components/PostView.razor | 7 +- .../Community/UI/Views/Admin/Filter.razor | 3 +- .../Features/Community/UI/Views/Events.razor | 3 +- .../Features/Community/UI/Views/Index.razor | 3 +- .../Community/UI/Views/Projects.razor | 3 +- .../Features/Servers/Actions/ServerActions.cs | 6 +- .../Actions/ServerServiceDefinition.cs | 2 +- .../Http/Controllers/NodeController.cs | 3 +- .../Http/Controllers/ServersControllers.cs | 6 +- .../Servers/Http/Middleware/NodeMiddleware.cs | 3 +- .../Features/Servers/Services/NodeService.cs | 2 + .../Servers/Services/ServerService.cs | 8 +- .../UI/Components/ParseConfigEditor.razor | 3 +- .../Servers/UI/Components/Terminal.razor | 3 +- .../Servers/UI/Layouts/UserLayout.razor | 9 +- .../Servers/UI/Views/Admin/Images/Index.razor | 9 +- .../Servers/UI/Views/Admin/Images/New.razor | 6 +- .../Admin/Images/View/ConfigParsing.razor | 9 +- .../UI/Views/Admin/Images/View/Details.razor | 6 +- .../Admin/Images/View/DockerImages.razor | 6 +- .../UI/Views/Admin/Images/View/Index.razor | 6 +- .../Admin/Images/View/Installation.razor | 6 +- .../Views/Admin/Images/View/Variables.razor | 3 +- .../Servers/UI/Views/Admin/Index.razor | 9 +- .../Models/Abstractions/ServiceViewContext.cs | 3 +- .../Services/ServiceAdminService.cs | 8 +- .../Services/ServiceDefinitionService.cs | 5 +- .../Services/ServiceManageService.cs | 5 +- .../Services/ServiceService.cs | 8 +- .../UI/Components/ServiceItem.razor | 13 +- .../UI/Views/Admin/Index.razor | 3 +- .../UI/Views/Admin/View.razor | 3 +- .../ServiceManagement/UI/Views/Index.razor | 3 +- .../ServiceManagement/UI/Views/View.razor | 6 +- .../Models/Forms/AddProductForm.cs | 1 + .../StoreSystem/Services/StoreAdminService.cs | 8 +- .../StoreSystem/Services/StoreGiftService.cs | 8 +- .../StoreSystem/Services/StoreOrderService.cs | 8 +- .../Services/StorePaymentService.cs | 4 +- .../StoreSystem/Services/StoreService.cs | 5 +- .../Services/TransactionService.cs | 6 +- .../UI/Components/StoreModals.razor | 6 +- .../StoreSystem/UI/Views/Admin/Coupons.razor | 6 +- .../StoreSystem/UI/Views/Admin/Expired.razor | 6 +- .../StoreSystem/UI/Views/Admin/Gifts.razor | 6 +- .../Features/StoreSystem/UI/Views/Index.razor | 13 +- .../Features/StoreSystem/UI/Views/Order.razor | 16 +- .../Features/Theming/Services/ThemeService.cs | 11 +- .../Theming/UI/Views/Admin/Themes.razor | 9 +- .../Ticketing/Services/TicketChatService.cs | 4 +- .../Ticketing/Services/TicketCreateService.cs | 6 +- .../Ticketing/Services/TicketService.cs | 5 +- .../UI/Components/ChatFileSelect.razor | 4 +- .../UI/Components/TicketPopupCreate.razor | 5 +- .../UI/Components/TicketPopupOverview.razor | 5 +- .../UI/Components/TicketPopupView.razor | 2 +- .../Ticketing/UI/Views/Admin/Index.razor | 6 +- .../Ticketing/UI/Views/Admin/View.razor | 9 +- Moonlight/Moonlight.csproj | 27 +- Moonlight/Pages/_Host.cshtml | 1 + Moonlight/Program.cs | 114 ++----- Moonlight/_Imports.razor | 3 + 137 files changed, 402 insertions(+), 3139 deletions(-) delete mode 100644 Moonlight/Core/Exceptions/DisplayException.cs delete mode 100644 Moonlight/Core/Extensions/Attributes/SelectorAttribute.cs delete mode 100644 Moonlight/Core/Extensions/ConfigurationBuilderExtensions.cs delete mode 100644 Moonlight/Core/Helpers/ComponentHelper.cs delete mode 100644 Moonlight/Core/Helpers/Formatter.cs delete mode 100644 Moonlight/Core/Helpers/HashHelper.cs delete mode 100644 Moonlight/Core/Helpers/HttpApiClient.cs delete mode 100644 Moonlight/Core/Helpers/LogMigrator/LogMigrateProvider.cs delete mode 100644 Moonlight/Core/Helpers/LogMigrator/MigrateLogger.cs delete mode 100644 Moonlight/Core/Helpers/Logger.cs delete mode 100644 Moonlight/Core/Helpers/PathBuilder.cs delete mode 100644 Moonlight/Core/Helpers/PropBinder.cs delete mode 100644 Moonlight/Core/Helpers/ValidatorHelper.cs delete mode 100644 Moonlight/Core/Helpers/WsPacketConnection.cs rename Moonlight/Core/Repositories/{Repository.cs => GenericRepository.cs} (62%) delete mode 100644 Moonlight/Core/Services/ConfigService.cs delete mode 100644 Moonlight/Core/Services/Interop/AlertService.cs delete mode 100644 Moonlight/Core/Services/Interop/ClipboardService.cs delete mode 100644 Moonlight/Core/Services/Interop/CookieService.cs delete mode 100644 Moonlight/Core/Services/Interop/FileDownloadService.cs delete mode 100644 Moonlight/Core/Services/Interop/ModalService.cs delete mode 100644 Moonlight/Core/Services/Interop/ToastService.cs delete mode 100644 Moonlight/Core/UI/Components/Forms/AutoCrud.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/AutoForm.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/AutoListCrud.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/AutoProperty.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/ConfirmButton.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/DynamicTypedAutoForm.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/SmartCustomFileSelect.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/SmartDropdown.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/SmartEnumSelect.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/SmartFileSelect.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/SmartForm.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/SmartSelect.razor delete mode 100644 Moonlight/Core/UI/Components/Forms/WButton.razor delete mode 100644 Moonlight/Core/UI/Components/Partials/LazyLoader.razor delete mode 100644 Moonlight/Core/UI/Components/Partials/SmartModal.razor diff --git a/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs b/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs index dfa375c7..91da0bfc 100644 --- a/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs +++ b/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs @@ -1,6 +1,5 @@ using Moonlight.Core.Actions.Dummy.Layouts; using Moonlight.Core.Actions.Dummy.Pages; -using Moonlight.Core.Helpers; using Moonlight.Features.ServiceManagement.Models.Abstractions; namespace Moonlight.Core.Actions.Dummy; diff --git a/Moonlight/Core/Configuration/ConfigV1.cs b/Moonlight/Core/Configuration/ConfigV1.cs index 251f5f80..1e611326 100644 --- a/Moonlight/Core/Configuration/ConfigV1.cs +++ b/Moonlight/Core/Configuration/ConfigV1.cs @@ -1,5 +1,5 @@ using System.ComponentModel; -using Moonlight.Core.Helpers; +using MoonCore.Helpers; using Moonlight.Features.Advertisement.Configuration; using Moonlight.Features.StoreSystem.Configuration; using Moonlight.Features.Theming.Configuration; diff --git a/Moonlight/Core/Database/DataContext.cs b/Moonlight/Core/Database/DataContext.cs index a45034ca..d8f8fe1a 100644 --- a/Moonlight/Core/Database/DataContext.cs +++ b/Moonlight/Core/Database/DataContext.cs @@ -1,4 +1,6 @@ using Microsoft.EntityFrameworkCore; +using MoonCore.Services; +using Moonlight.Core.Configuration; using Moonlight.Core.Database.Entities; using Moonlight.Core.Services; using Moonlight.Features.Community.Entities; @@ -12,7 +14,7 @@ namespace Moonlight.Core.Database; public class DataContext : DbContext { - private readonly ConfigService ConfigService; + private readonly ConfigService ConfigService; public DbSet Users { get; set; } @@ -50,7 +52,7 @@ public class DataContext : DbContext public DbSet ServerDockerImages { get; set; } public DbSet ServerImageVariables { get; set; } - public DataContext(ConfigService configService) + public DataContext(ConfigService configService) { ConfigService = configService; } diff --git a/Moonlight/Core/Exceptions/DisplayException.cs b/Moonlight/Core/Exceptions/DisplayException.cs deleted file mode 100644 index cc8c04a9..00000000 --- a/Moonlight/Core/Exceptions/DisplayException.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Moonlight.Core.Exceptions; - -public class DisplayException : Exception -{ - public DisplayException() - { - } - - public DisplayException(string message) : base(message) - { - } - - public DisplayException(string message, Exception inner) : base(message, inner) - { - } -} \ No newline at end of file diff --git a/Moonlight/Core/Extensions/Attributes/SelectorAttribute.cs b/Moonlight/Core/Extensions/Attributes/SelectorAttribute.cs deleted file mode 100644 index 4caf59af..00000000 --- a/Moonlight/Core/Extensions/Attributes/SelectorAttribute.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Core.Extensions.Attributes; - -public class SelectorAttribute : Attribute -{ - public string SelectorProp { get; set; } = ""; - public string DisplayProp { get; set; } = ""; - public bool UseDropdown { get; set; } = false; -} \ No newline at end of file diff --git a/Moonlight/Core/Extensions/ConfigurationBuilderExtensions.cs b/Moonlight/Core/Extensions/ConfigurationBuilderExtensions.cs deleted file mode 100644 index 89c69a65..00000000 --- a/Moonlight/Core/Extensions/ConfigurationBuilderExtensions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Text; - -namespace Moonlight.Core.Extensions; - -public static class ConfigurationBuilderExtensions -{ - public static IConfigurationBuilder AddJsonString(this IConfigurationBuilder configurationBuilder, string json) - { - var bytes = Encoding.UTF8.GetBytes(json); - var stream = new MemoryStream(bytes); - return configurationBuilder.AddJsonStream(stream); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/ComponentHelper.cs b/Moonlight/Core/Helpers/ComponentHelper.cs deleted file mode 100644 index a8296d9c..00000000 --- a/Moonlight/Core/Helpers/ComponentHelper.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Microsoft.AspNetCore.Components; - -namespace Moonlight.Core.Helpers; - -public static class ComponentHelper -{ - public static RenderFragment FromType(Type type, Action>? buildAttributes = null) => builder => - { - builder.OpenComponent(0, type); - - if (buildAttributes != null) - { - Dictionary parameters = new(); - buildAttributes.Invoke(parameters); - builder.AddMultipleAttributes(1, parameters); - } - - builder.CloseComponent(); - }; - - public static RenderFragment FromType(Action>? buildAttributes = null) where T : ComponentBase => - FromType(typeof(T), buildAttributes); -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/Formatter.cs b/Moonlight/Core/Helpers/Formatter.cs deleted file mode 100644 index ce8c3436..00000000 --- a/Moonlight/Core/Helpers/Formatter.cs +++ /dev/null @@ -1,280 +0,0 @@ -using System.Text; -using Microsoft.AspNetCore.Components; - -namespace Moonlight.Core.Helpers; - -public static class Formatter -{ - public static string GenerateString(int length) - { - var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - var stringBuilder = new StringBuilder(); - var random = new Random(); - - for (int i = 0; i < length; i++) - { - stringBuilder.Append(chars[random.Next(chars.Length)]); - } - - return stringBuilder.ToString(); - } - - public static string IntToStringWithLeadingZeros(int number, int n) - { - string result = number.ToString(); - int length = result.Length; - - for (int i = length; i < n; i++) - { - result = "0" + result; - } - - return result; - } - - public static string CapitalizeFirstCharacter(string input) - { - if (string.IsNullOrEmpty(input)) - { - return input; - } - - char firstChar = char.ToUpper(input[0]); - string restOfString = input.Substring(1); - - return firstChar + restOfString; - } - - public static string CutInHalf(string input) - { - if (string.IsNullOrEmpty(input)) - return input; - - int length = input.Length; - int halfLength = length / 2; - - return input.Substring(0, halfLength); - } - - public static bool EndsInOneOf(string suffix, IEnumerable strings) - { - foreach (string str in strings) - { - if (suffix.EndsWith(str)) - { - return true; - } - } - - return false; - } - - public static bool ContainsOneOf(string textToSearch, IEnumerable strings, out string foundText) - { - foreach (string str in strings) - { - if (textToSearch.Contains(str)) - { - foundText = str; - return true; - } - } - - foundText = ""; - return false; - } - - public static bool ContainsOneOf(string textToSearch, IEnumerable strings) - { - return ContainsOneOf(textToSearch, strings, out _); - } - - public static string FormatSize(long bytes) - { - var i = Math.Abs(bytes) / 1024D; - if (i < 1) - { - return bytes + " B"; - } - else if (i / 1024D < 1) - { - return i.Round(2) + " KB"; - } - else if (i / (1024D * 1024D) < 1) - { - return (i / 1024D).Round(2) + " MB"; - } - else - { - return (i / (1024D * 1024D)).Round(2) + " GB"; - } - } - - private static double Round(this double d, int decimals) - { - return Math.Round(d, decimals); - } - - public static string ReplaceEnd(string input, string substringToReplace, string newSubstring) - { - int lastIndexOfSubstring = input.LastIndexOf(substringToReplace); - if (lastIndexOfSubstring >= 0) - { - input = input.Remove(lastIndexOfSubstring, substringToReplace.Length) - .Insert(lastIndexOfSubstring, newSubstring); - } - - return input; - } - - public static string ConvertCamelCaseToSpaces(string input) - { - StringBuilder output = new StringBuilder(); - - foreach (char c in input) - { - if (char.IsUpper(c)) - { - output.Append(' '); - } - - output.Append(c); - } - - return output.ToString().Trim(); - } - - public static string FormatUptime(double uptime) - { - TimeSpan t = TimeSpan.FromMilliseconds(uptime); - - return FormatUptime(t); - } - - public static string FormatUptime(TimeSpan t) - { - if (t.Days > 0) - { - return $"{t.Days}d {t.Hours}h {t.Minutes}m {t.Seconds}s"; - } - else - { - return $"{t.Hours}h {t.Minutes}m {t.Seconds}s"; - } - } - - public static string FormatDate(DateTime e) - { - string i2s(int i) - { - if (i.ToString().Length < 2) - return "0" + i; - return i.ToString(); - } - - return $"{i2s(e.Day)}.{i2s(e.Month)}.{e.Year} {i2s(e.Hour)}:{i2s(e.Minute)}"; - } - - public static string FormatDateOnly(DateTime e) - { - string i2s(int i) - { - if (i.ToString().Length < 2) - return "0" + i; - return i.ToString(); - } - - return $"{i2s(e.Day)}.{i2s(e.Month)}.{e.Year}"; - } - - public static string FormatSize(double bytes) - { - var i = Math.Abs(bytes) / 1024D; - if (i < 1) - { - return bytes + " B"; - } - else if (i / 1024D < 1) - { - return i.Round(2) + " KB"; - } - else if (i / (1024D * 1024D) < 1) - { - return (i / 1024D).Round(2) + " MB"; - } - else - { - return (i / (1024D * 1024D)).Round(2) + " GB"; - } - } - - public static RenderFragment FormatLineBreaks(string content) - { - return builder => - { - int i = 0; - var arr = content.Split("\n"); - - foreach (var line in arr) - { - builder.AddContent(i, line); - if (i++ != arr.Length - 1) - { - builder.AddMarkupContent(i, "
"); - } - } - }; - } - - public static string FormatAgoFromDateTime(DateTime dt) - { - TimeSpan timeSince = DateTime.UtcNow.Subtract(dt); - - if (timeSince.TotalMilliseconds < 1) - return "just now"; - - if (timeSince.TotalMinutes < 1) - return "less than a minute ago"; - - if (timeSince.TotalMinutes < 2) - return "1 minute ago"; - - if (timeSince.TotalMinutes < 60) - return Math.Round(timeSince.TotalMinutes) + " minutes ago"; - - if (timeSince.TotalHours < 2) - return "1 hour ago"; - - if (timeSince.TotalHours < 24) - return Math.Round(timeSince.TotalHours) + " hours ago"; - - if (timeSince.TotalDays < 2) - return "1 day ago"; - - return Math.Round(timeSince.TotalDays) + " days ago"; - } - - // This will replace every placeholder with the respective value if specified in the model - // For example: - // A instance of the user model has been passed in the 'models' parameter of the function. - // So the placeholder {{User.Email}} will be replaced by the value of the Email property of the model - public static string ProcessTemplating(string text, params object[] models) - { - foreach (var model in models) - { - foreach (var property in model.GetType().GetProperties()) - { - var value = property.GetValue(model); - - if(value == null) - continue; - - var placeholder = "{{" + $"{model.GetType().Name}.{property.Name}" + "}}"; - - text = text.Replace(placeholder, value.ToString()); - } - } - - return text; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/HashHelper.cs b/Moonlight/Core/Helpers/HashHelper.cs deleted file mode 100644 index 9e5b46c7..00000000 --- a/Moonlight/Core/Helpers/HashHelper.cs +++ /dev/null @@ -1,172 +0,0 @@ -using System.Security.Cryptography; -using Microsoft.AspNetCore.Cryptography.KeyDerivation; - -namespace Moonlight.Core.Helpers; - -// Src: https://codereview.stackexchange.com/questions/176697/net-core-mvc-future-proof-hashing-of-passwords -public static class HashHelper -{ - /// - /// The default number of Iterations - /// - private const int DefaultIterations = 10000; - - /// - /// Provides Information about a specific Hash Version - /// - private class HashVersion - { - public short Version { get; set; } - public int SaltSize { get; set; } - public int HashSize { get; set; } - public KeyDerivationPrf KeyDerivation { get; set; } - } - - /// - /// Holds all possible Hash Versions - /// - private static readonly Dictionary _versions = new Dictionary - { - { - 1, new HashVersion - { - Version = 1, - KeyDerivation = KeyDerivationPrf.HMACSHA512, - HashSize = 256 / 8, - SaltSize = 128 / 8 - } - } - }; - - /// - /// The default Hash Version, which should be used, if a new Hash is Created - /// - private static HashVersion DefaultVersion => _versions[1]; - - /// - /// Checks if a given hash uses the latest version - /// - /// The hash - /// Is the hash of the latest version? - public static bool IsLatestHashVersion(byte[] data) - { - var version = BitConverter.ToInt16(data, 0); - return version == DefaultVersion.Version; - } - - /// - /// Checks if a given hash uses the latest version - /// - /// The hash - /// Is the hash of the latest version? - public static bool IsLatestHashVersion(string data) - { - var dataBytes = Convert.FromBase64String(data); - return IsLatestHashVersion(dataBytes); - } - - /// - /// Gets a random byte array - /// - /// The length of the byte array - /// The random byte array - public static byte[] GetRandomBytes(int length) - { - var data = new byte[length]; - using (var randomNumberGenerator = RandomNumberGenerator.Create()) - { - randomNumberGenerator.GetBytes(data); - } - - return data; - } - - /// - /// Creates a Hash of a clear text - /// - /// the clear text - /// the number of iteration the hash alogrythm should run - /// the Hash - public static byte[] Hash(string clearText, int iterations = DefaultIterations) - { - //get current version - var currentVersion = DefaultVersion; - - //get the byte arrays of the hash and meta information - var saltBytes = GetRandomBytes(currentVersion.SaltSize); - var versionBytes = BitConverter.GetBytes(currentVersion.Version); - var iterationBytes = BitConverter.GetBytes(iterations); - var hashBytes = KeyDerivation.Pbkdf2(clearText, saltBytes, currentVersion.KeyDerivation, iterations, - currentVersion.HashSize); - - //calculate the indexes for the combined hash - var indexVersion = 0; - var indexIteration = indexVersion + 2; - var indexSalt = indexIteration + 4; - var indexHash = indexSalt + currentVersion.SaltSize; - - //combine all data to one result hash - var resultBytes = new byte[2 + 4 + currentVersion.SaltSize + currentVersion.HashSize]; - Array.Copy(versionBytes, 0, resultBytes, indexVersion, 2); - Array.Copy(iterationBytes, 0, resultBytes, indexIteration, 4); - Array.Copy(saltBytes, 0, resultBytes, indexSalt, currentVersion.SaltSize); - Array.Copy(hashBytes, 0, resultBytes, indexHash, currentVersion.HashSize); - return resultBytes; - } - - /// - /// Creates a Hash of a clear text and convert it to a Base64 String representation - /// - /// the clear text - /// the number of iteration the hash alogrythm should run - /// the Hash - public static string HashToString(string clearText, int iterations = DefaultIterations) - { - var data = Hash(clearText, iterations); - return Convert.ToBase64String(data); - } - - /// - /// Verifies a given clear Text against a hash - /// - /// The clear text - /// The hash - /// Is the hash equal to the clear text? - public static bool Verify(string clearText, byte[] data) - { - //Get the current version and number of iterations - var currentVersion = _versions[BitConverter.ToInt16(data, 0)]; - var iteration = BitConverter.ToInt32(data, 2); - - //Create the byte arrays for the salt and hash - var saltBytes = new byte[currentVersion.SaltSize]; - var hashBytes = new byte[currentVersion.HashSize]; - - //Calculate the indexes of the salt and the hash - var indexSalt = 2 + 4; // Int16 (Version) and Int32 (Iteration) - var indexHash = indexSalt + currentVersion.SaltSize; - - //Fill the byte arrays with salt and hash - Array.Copy(data, indexSalt, saltBytes, 0, currentVersion.SaltSize); - Array.Copy(data, indexHash, hashBytes, 0, currentVersion.HashSize); - - //Hash the current clearText with the parameters given via the data - var verificationHashBytes = KeyDerivation.Pbkdf2(clearText, saltBytes, currentVersion.KeyDerivation, iteration, - currentVersion.HashSize); - - //Check if generated hashes are equal - return hashBytes.SequenceEqual(verificationHashBytes); - } - - /// - /// Verifies a given clear Text against a hash - /// - /// The clear text - /// The hash - /// Is the hash equal to the clear text? - public static bool Verify(string clearText, string data) - { - var dataBytes = Convert.FromBase64String(data); - return Verify(clearText, dataBytes); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/HttpApiClient.cs b/Moonlight/Core/Helpers/HttpApiClient.cs deleted file mode 100644 index c16084d7..00000000 --- a/Moonlight/Core/Helpers/HttpApiClient.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System.Net.Http.Headers; -using System.Text; -using Newtonsoft.Json; - -namespace Moonlight.Core.Helpers; - -public class HttpApiClient : IDisposable where TException : Exception -{ - private readonly HttpClient Client; - private readonly string BaseUrl; - - public HttpApiClient(string baseUrl, string token) - { - Client = new(); - Client.DefaultRequestHeaders.Add("Authorization", token); - - BaseUrl = baseUrl.EndsWith("/") ? baseUrl : baseUrl + "/"; - } - - public async Task Send(HttpMethod method, string path, string? body = null, - string contentType = "text/plain") - { - var request = new HttpRequestMessage(); - - request.RequestUri = new Uri(BaseUrl + path); - request.Method = method; - - if (body != null) - request.Content = new StringContent(body, Encoding.UTF8, new MediaTypeHeaderValue(contentType)); - - var response = await Client.SendAsync(request); - - if (!response.IsSuccessStatusCode) - { - await HandleRequestError(response, path); - return ""; - } - - return await response.Content.ReadAsStringAsync(); - } - - private async Task HandleRequestError(HttpResponseMessage response, string path) - { - var content = await response.Content.ReadAsStringAsync(); - var message = $"[{path}] ({response.StatusCode}): {content}"; - var exception = Activator.CreateInstance(typeof(TException), message) as Exception; - - throw exception!; - } - - #region GET - - public async Task GetAsString(string path) => - await Send(HttpMethod.Get, path); - - public async Task Get(string path) => - JsonConvert.DeserializeObject(await Send(HttpMethod.Get, path))!; - - #endregion - - #region POST - - public async Task PostAsString(string path, string body, string contentType = "text/plain") => - await Send(HttpMethod.Post, path, body, contentType); - - public async Task Post(string path, object body) => - JsonConvert.DeserializeObject(await Send(HttpMethod.Post, path, JsonConvert.SerializeObject(body), - "application/json"))!; - - public async Task Post(string path, object? body = null) => await Send(HttpMethod.Post, path, - body == null ? "" : JsonConvert.SerializeObject(body)); - - #endregion - - #region PUT - - public async Task PutAsString(string path, string body, string contentType = "text/plain") => - await Send(HttpMethod.Put, path, body, contentType); - - public async Task Put(string path, object body) => - JsonConvert.DeserializeObject(await Send(HttpMethod.Put, path, JsonConvert.SerializeObject(body), - "application/json"))!; - - public async Task Put(string path, object? body = null) => await Send(HttpMethod.Put, path, - body == null ? "" : JsonConvert.SerializeObject(body)); - - #endregion - - #region PATCH - - public async Task PatchAsString(string path, string body, string contentType = "text/plain") => - await Send(HttpMethod.Patch, path, body, contentType); - - public async Task Patch(string path, object body) => - JsonConvert.DeserializeObject(await Send(HttpMethod.Patch, path, JsonConvert.SerializeObject(body), - "application/json"))!; - - public async Task Patch(string path, object? body = null) => await Send(HttpMethod.Patch, path, - body == null ? "" : JsonConvert.SerializeObject(body)); - - #endregion - - #region DELETE - - public async Task DeleteAsString(string path) => - await Send(HttpMethod.Delete, path); - - public async Task Delete(string path) => - JsonConvert.DeserializeObject(await Send(HttpMethod.Delete, path))!; - - #endregion - - public void Dispose() - { - Client.Dispose(); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/LogMigrator/LogMigrateProvider.cs b/Moonlight/Core/Helpers/LogMigrator/LogMigrateProvider.cs deleted file mode 100644 index 9d7d4dea..00000000 --- a/Moonlight/Core/Helpers/LogMigrator/LogMigrateProvider.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Moonlight.Core.Helpers.LogMigrator; - -public class LogMigrateProvider : ILoggerProvider -{ - public void Dispose() {} - - public ILogger CreateLogger(string categoryName) - { - return new MigrateLogger(); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/LogMigrator/MigrateLogger.cs b/Moonlight/Core/Helpers/LogMigrator/MigrateLogger.cs deleted file mode 100644 index a0de98e1..00000000 --- a/Moonlight/Core/Helpers/LogMigrator/MigrateLogger.cs +++ /dev/null @@ -1,53 +0,0 @@ -namespace Moonlight.Core.Helpers.LogMigrator; - -public class MigrateLogger : ILogger -{ - public IDisposable? BeginScope(TState state) where TState : notnull => null; - - public bool IsEnabled(LogLevel logLevel) - { - return true; - } - - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func formatter) - { - switch (logLevel) - { - case LogLevel.Critical: - Logger.Fatal(formatter(state, exception)); - - if(exception != null) - Logger.Fatal(exception); - - break; - case LogLevel.Warning: - Logger.Warn(formatter(state, exception)); - - if(exception != null) - Logger.Warn(exception); - - break; - case LogLevel.Debug: - Logger.Debug(formatter(state, exception)); - - if(exception != null) - Logger.Debug(exception); - - break; - case LogLevel.Error: - Logger.Error(formatter(state, exception)); - - if(exception != null) - Logger.Error(exception); - - break; - case LogLevel.Information: - Logger.Info(formatter(state, exception)); - - if(exception != null) - Logger.Info(exception); - - break; - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/Logger.cs b/Moonlight/Core/Helpers/Logger.cs deleted file mode 100644 index 068ed3c3..00000000 --- a/Moonlight/Core/Helpers/Logger.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Diagnostics; -using System.Reflection; -using Serilog; - -namespace Moonlight.Core.Helpers; - -public class Logger -{ - #region String logger - public static void Verbose(string message, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Verbose("{Message}", message); - } - - public static void Info(string message, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Information("{Message}", message); - } - - public static void Debug(string message, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Debug("{Message}", message); - } - - public static void Error(string message, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Error("{Message}", message); - } - - public static void Warn(string message, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Warning("{Message}", message); - } - - public static void Fatal(string message, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Fatal("{Message}", message); - } - - #endregion - - #region Exception method calls - - public static void Verbose(Exception exception, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Verbose(exception, ""); - } - - public static void Info(Exception exception, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Information(exception, ""); - } - - public static void Debug(Exception exception, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Debug(exception, ""); - } - - public static void Error(Exception exception, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Error(exception, ""); - } - - public static void Warn(Exception exception, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Warning(exception, ""); - } - - public static void Fatal(Exception exception, string channel = "default") - { - Log.ForContext("SourceContext", GetNameOfCallingClass()) - .Fatal(exception, ""); - } - - #endregion - - private static string GetNameOfCallingClass(int skipFrames = 4) - { - string fullName; - Type declaringType; - - do - { - MethodBase method = new StackFrame(skipFrames, false).GetMethod(); - declaringType = method.DeclaringType; - if (declaringType == null) - { - return method.Name; - } - - skipFrames++; - if (declaringType.Name.Contains("<")) - fullName = declaringType.ReflectedType.Name; - else - fullName = declaringType.Name; - } while (declaringType.Module.Name.Equals("mscorlib.dll", StringComparison.OrdinalIgnoreCase) | - fullName.Contains("Logger")); - - return fullName; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/PathBuilder.cs b/Moonlight/Core/Helpers/PathBuilder.cs deleted file mode 100644 index 5388208e..00000000 --- a/Moonlight/Core/Helpers/PathBuilder.cs +++ /dev/null @@ -1,34 +0,0 @@ -namespace Moonlight.Core.Helpers; - -public static class PathBuilder -{ - public static string Dir(params string[] parts) - { - var res = ""; - - foreach (var part in parts) - { - res += part + Path.DirectorySeparatorChar; - } - - return res.Replace( - $"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}", - $"{Path.DirectorySeparatorChar}" - ); - } - - public static string File(params string[] parts) - { - var res = ""; - - foreach (var part in parts) - { - res += part + (part == parts.Last() ? "" : Path.DirectorySeparatorChar); - } - - return res.Replace( - $"{Path.DirectorySeparatorChar}{Path.DirectorySeparatorChar}", - $"{Path.DirectorySeparatorChar}" - ); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/PropBinder.cs b/Moonlight/Core/Helpers/PropBinder.cs deleted file mode 100644 index 39b0c6d5..00000000 --- a/Moonlight/Core/Helpers/PropBinder.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System.Reflection; - -namespace Moonlight.Core.Helpers; - -public class PropBinder -{ - private PropertyInfo PropertyInfo; - private object DataObject; - - public PropBinder(PropertyInfo propertyInfo, object dataObject) - { - PropertyInfo = propertyInfo; - DataObject = dataObject; - } - - public string StringValue - { - get => (string)PropertyInfo.GetValue(DataObject)!; - set => PropertyInfo.SetValue(DataObject, value); - } - - public int IntValue - { - get => (int)PropertyInfo.GetValue(DataObject)!; - set => PropertyInfo.SetValue(DataObject, value); - } - - public long LongValue - { - get => (long)PropertyInfo.GetValue(DataObject)!; - set => PropertyInfo.SetValue(DataObject, value); - } - - public bool BoolValue - { - get => (bool)PropertyInfo.GetValue(DataObject)!; - set => PropertyInfo.SetValue(DataObject, value); - } - - public DateTime DateTimeValue - { - get => (DateTime)PropertyInfo.GetValue(DataObject)!; - set => PropertyInfo.SetValue(DataObject, value); - } - - public T Class - { - get => (T)PropertyInfo.GetValue(DataObject)!; - set => PropertyInfo.SetValue(DataObject, value); - } - - public double DoubleValue - { - get => (double)PropertyInfo.GetValue(DataObject)!; - set => PropertyInfo.SetValue(DataObject, value); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/ValidatorHelper.cs b/Moonlight/Core/Helpers/ValidatorHelper.cs deleted file mode 100644 index 35614cf4..00000000 --- a/Moonlight/Core/Helpers/ValidatorHelper.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using Moonlight.Core.Exceptions; - -namespace Moonlight.Core.Helpers; - -public class ValidatorHelper -{ - public static Task Validate(object objectToValidate) - { - var context = new ValidationContext(objectToValidate, null, null); - var results = new List(); - - var isValid = Validator.TryValidateObject(objectToValidate, context, results, true); - - if (!isValid) - { - var errorMsg = "Unknown form error"; - - if (results.Any()) - errorMsg = results.First().ErrorMessage ?? errorMsg; - - throw new DisplayException(errorMsg); - } - - return Task.CompletedTask; - } - - public static async Task ValidateRange(IEnumerable objectToValidate) - { - foreach (var o in objectToValidate) - await Validate(o); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Helpers/WsPacketConnection.cs b/Moonlight/Core/Helpers/WsPacketConnection.cs deleted file mode 100644 index c9e9ad98..00000000 --- a/Moonlight/Core/Helpers/WsPacketConnection.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System.Net.WebSockets; -using System.Text; -using Newtonsoft.Json; - -namespace Moonlight.Core.Helpers; - -public class WsPacketConnection -{ - private readonly Dictionary Packets = new(); - private readonly WebSocket WebSocket; - - public WsPacketConnection(WebSocket webSocket) - { - WebSocket = webSocket; - } - - public Task RegisterPacket(string id) - { - lock (Packets) - Packets.Add(id, typeof(T)); - - return Task.CompletedTask; - } - - public async Task Send(object packet) - { - string? packetId = null; - - // Search packet registration - lock (Packets) - { - if (Packets.Any(x => x.Value == packet.GetType())) - packetId = Packets.First(x => x.Value == packet.GetType()).Key; - - if (packetId == null) - throw new ArgumentException($"A packet with the type {packet.GetType().FullName} is not registered"); - } - - // Build raw packet - var rawPacket = new RawPacket() - { - Id = packetId, - Data = packet - }; - - // Serialize, encode and build buffer - var json = JsonConvert.SerializeObject(rawPacket); - var buffer = Encoding.UTF8.GetBytes(json); - - await WebSocket.SendAsync(buffer, WebSocketMessageType.Text, WebSocketMessageFlags.None, - CancellationToken.None); - } - - public async Task Receive() - { - // Build buffer and read - var buffer = new byte[1024]; - await WebSocket.ReceiveAsync(buffer, CancellationToken.None); - - // Decode and deserialize - var json = Encoding.UTF8.GetString(buffer); - var rawPacket = JsonConvert.DeserializeObject(json)!; - - object? packetType = null; - - // Search packet registration - lock (Packets) - { - if (Packets.ContainsKey(rawPacket.Id)) - packetType = Packets[rawPacket.Id]; - - if (packetType == null) - throw new ArgumentException($"A packet with the type {rawPacket.Id} is not registered"); - } - - var typedPacketType = typeof(RawPacket<>).MakeGenericType((packetType as Type)!); - var typedPacket = JsonConvert.DeserializeObject(json, typedPacketType); - - return typedPacketType.GetProperty("Data")!.GetValue(typedPacket); - } - - public async Task Receive() where T : class - { - var o = await Receive(); - - if (o == null) - return default; - - return (T)o; - } - - public async Task Close() - { - if(WebSocket.State == WebSocketState.Open) - await WebSocket.CloseOutputAsync(WebSocketCloseStatus.Empty, null, CancellationToken.None); - } - - public async Task WaitForClose() - { - var source = new TaskCompletionSource(); - - Task.Run(async () => - { - while (WebSocket.State == WebSocketState.Open) - await Task.Delay(10); - - source.SetResult(); - }); - - await source.Task; - } - - public class RawPacket - { - public string Id { get; set; } - public object Data { get; set; } - } - - public class RawPacket - { - public string Id { get; set; } - public T Data { get; set; } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Http/Controllers/Api/AssetProxyController.cs b/Moonlight/Core/Http/Controllers/Api/AssetProxyController.cs index e38b5a44..401d72e2 100644 --- a/Moonlight/Core/Http/Controllers/Api/AssetProxyController.cs +++ b/Moonlight/Core/Http/Controllers/Api/AssetProxyController.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Mvc; -using Moonlight.Core.Helpers; +using MoonCore.Helpers; using Moonlight.Features.Theming.Services; namespace Moonlight.Core.Http.Controllers.Api; diff --git a/Moonlight/Core/Http/Controllers/Api/Auth/ResetController.cs b/Moonlight/Core/Http/Controllers/Api/Auth/ResetController.cs index 4905a557..f1a4f51b 100644 --- a/Moonlight/Core/Http/Controllers/Api/Auth/ResetController.cs +++ b/Moonlight/Core/Http/Controllers/Api/Auth/ResetController.cs @@ -1,7 +1,8 @@ using Microsoft.AspNetCore.Mvc; +using MoonCore.Abstractions; using Moonlight.Core.Database.Entities; using Moonlight.Core.Models.Enums; -using Moonlight.Core.Repositories; + using Moonlight.Core.Services; using Moonlight.Core.Services.Utils; diff --git a/Moonlight/Core/Http/Controllers/Api/Auth/VerifyController.cs b/Moonlight/Core/Http/Controllers/Api/Auth/VerifyController.cs index 518fb72b..f03a4b30 100644 --- a/Moonlight/Core/Http/Controllers/Api/Auth/VerifyController.cs +++ b/Moonlight/Core/Http/Controllers/Api/Auth/VerifyController.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Mvc; -using Moonlight.Core.Helpers; +using MoonCore.Helpers; using Moonlight.Core.Models.Enums; using Moonlight.Core.Services; using Moonlight.Core.Services.Utils; diff --git a/Moonlight/Core/Http/Controllers/Api/BucketController.cs b/Moonlight/Core/Http/Controllers/Api/BucketController.cs index 5525d4e5..bc7dfe60 100644 --- a/Moonlight/Core/Http/Controllers/Api/BucketController.cs +++ b/Moonlight/Core/Http/Controllers/Api/BucketController.cs @@ -1,5 +1,5 @@ using Microsoft.AspNetCore.Mvc; -using Moonlight.Core.Helpers; +using MoonCore.Helpers; using Moonlight.Core.Services; namespace Moonlight.Core.Http.Controllers.Api; diff --git a/Moonlight/Core/Repositories/Repository.cs b/Moonlight/Core/Repositories/GenericRepository.cs similarity index 62% rename from Moonlight/Core/Repositories/Repository.cs rename to Moonlight/Core/Repositories/GenericRepository.cs index 874ea064..ed97af2d 100644 --- a/Moonlight/Core/Repositories/Repository.cs +++ b/Moonlight/Core/Repositories/GenericRepository.cs @@ -1,38 +1,41 @@ using Microsoft.EntityFrameworkCore; +using MoonCore.Abstractions; +using MoonCore.Attributes; using Moonlight.Core.Database; namespace Moonlight.Core.Repositories; -public class Repository where TEntity : class +[Scoped] +public class GenericRepository : Repository where TEntity : class { private readonly DataContext DataContext; private readonly DbSet DbSet; - public Repository(DataContext dbContext) + public GenericRepository(DataContext dbContext) { DataContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); DbSet = DataContext.Set(); } - public DbSet Get() + public override DbSet Get() { return DbSet; } - public TEntity Add(TEntity entity) + public override TEntity Add(TEntity entity) { var x = DbSet.Add(entity); DataContext.SaveChanges(); return x.Entity; } - public void Update(TEntity entity) + public override void Update(TEntity entity) { DbSet.Update(entity); DataContext.SaveChanges(); } - public void Delete(TEntity entity) + public override void Delete(TEntity entity) { DbSet.Remove(entity); DataContext.SaveChanges(); diff --git a/Moonlight/Core/Services/Background/AutoMailSendService.cs b/Moonlight/Core/Services/Background/AutoMailSendService.cs index 3cbff631..b4e945bc 100644 --- a/Moonlight/Core/Services/Background/AutoMailSendService.cs +++ b/Moonlight/Core/Services/Background/AutoMailSendService.cs @@ -2,20 +2,26 @@ using Moonlight.Core.Event; using Moonlight.Core.Event.Args; using Moonlight.Features.ServiceManagement.Entities; +using BackgroundService = MoonCore.Abstractions.BackgroundService; namespace Moonlight.Core.Services.Background; -public class AutoMailSendService // This service is responsible for sending mails automatically +public class AutoMailSendService : BackgroundService // This service is responsible for sending mails automatically { private readonly MailService MailService; public AutoMailSendService(MailService mailService) { MailService = mailService; - + } + + public override Task Run() + { Events.OnUserRegistered += OnUserRegistered; Events.OnServiceOrdered += OnServiceOrdered; Events.OnTransactionCreated += OnTransactionCreated; + + return Task.CompletedTask; } private async void OnTransactionCreated(object? sender, TransactionCreatedEventArgs eventArgs) diff --git a/Moonlight/Core/Services/BucketService.cs b/Moonlight/Core/Services/BucketService.cs index 260d7e8d..37bf0a01 100644 --- a/Moonlight/Core/Services/BucketService.cs +++ b/Moonlight/Core/Services/BucketService.cs @@ -1,7 +1,9 @@ -using Moonlight.Core.Helpers; +using MoonCore.Attributes; +using MoonCore.Helpers; namespace Moonlight.Core.Services; +[Singleton] public class BucketService { private readonly string BasePath; diff --git a/Moonlight/Core/Services/ConfigService.cs b/Moonlight/Core/Services/ConfigService.cs deleted file mode 100644 index c8d0f67b..00000000 --- a/Moonlight/Core/Services/ConfigService.cs +++ /dev/null @@ -1,102 +0,0 @@ -using Moonlight.Core.Configuration; -using Moonlight.Core.Helpers; -using Newtonsoft.Json; - -namespace Moonlight.Core.Services; - -public class ConfigService -{ - private readonly string Path = PathBuilder.File("storage", "config.json"); - private ConfigV1 Data; - - public ConfigService() - { - Reload(); - } - - public void Reload() - { - if(!File.Exists(Path)) - File.WriteAllText(Path, "{}"); - - var text = File.ReadAllText(Path); - Data = JsonConvert.DeserializeObject(text) ?? new(); - - ApplyEnvironmentVariables("Moonlight", Data); - - Save(); - } - - public void Save() - { - var text = JsonConvert.SerializeObject(Data, Formatting.Indented); - File.WriteAllText(Path, text); - } - - public ConfigV1 Get() - { - return Data; - } - - public string GetDiagnoseJson() - { - var text = File.ReadAllText(Path); - var data = JsonConvert.DeserializeObject(text) ?? new(); - - // Security token - data.Security.Token = ""; - - // Database - if (string.IsNullOrEmpty(data.Database.Password)) - data.Database.Password = "WAS EMPTY"; - else - data.Database.Password = "WAS NOT EMPTY"; - - // Mailserver - if (string.IsNullOrEmpty(data.MailServer.Password)) - data.MailServer.Password = "WAS EMPTY"; - else - data.MailServer.Password = "WAS NOT EMPTY"; - - return JsonConvert.SerializeObject(data, Formatting.Indented); - } - - private void ApplyEnvironmentVariables(string prefix, object objectToLookAt) - { - foreach (var property in objectToLookAt.GetType().GetProperties()) - { - var envName = $"{prefix}_{property.Name}"; - - if (property.PropertyType.Assembly == GetType().Assembly) - { - ApplyEnvironmentVariables(envName, property.GetValue(objectToLookAt)!); - } - else - { - if(!Environment.GetEnvironmentVariables().Contains(envName)) - continue; - - var envValue = Environment.GetEnvironmentVariable(envName)!; - - if (property.PropertyType == typeof(string)) - { - property.SetValue(objectToLookAt, envValue); - } - else if (property.PropertyType == typeof(int)) - { - if(!int.TryParse(envValue, out int envIntValue)) - continue; - - property.SetValue(objectToLookAt, envIntValue); - } - else if (property.PropertyType == typeof(bool)) - { - if(!bool.TryParse(envValue, out bool envBoolValue)) - continue; - - property.SetValue(objectToLookAt, envBoolValue); - } - } - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/IdentityService.cs b/Moonlight/Core/Services/IdentityService.cs index 7f217691..5ea75267 100644 --- a/Moonlight/Core/Services/IdentityService.cs +++ b/Moonlight/Core/Services/IdentityService.cs @@ -1,10 +1,11 @@ using Microsoft.EntityFrameworkCore; +using MoonCore.Abstractions; +using MoonCore.Attributes; +using MoonCore.Exceptions; +using MoonCore.Helpers; using Moonlight.Core.Database.Entities; -using Moonlight.Core.Exceptions; -using Moonlight.Core.Helpers; using Moonlight.Core.Models.Abstractions; using Moonlight.Core.Models.Enums; -using Moonlight.Core.Repositories; using Moonlight.Core.Services.Utils; using Moonlight.Features.StoreSystem.Entities; using OtpNet; @@ -13,6 +14,7 @@ namespace Moonlight.Core.Services; // This service allows you to reauthenticate, login and force login // It does also contain the permission system accessor for the current user +[Scoped] public class IdentityService { private readonly Repository UserRepository; diff --git a/Moonlight/Core/Services/Interop/AlertService.cs b/Moonlight/Core/Services/Interop/AlertService.cs deleted file mode 100644 index c66a2218..00000000 --- a/Moonlight/Core/Services/Interop/AlertService.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Microsoft.JSInterop; - -namespace Moonlight.Core.Services.Interop; - -public class AlertService -{ - private readonly IJSRuntime JsRuntime; - - public AlertService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - } - - public async Task Info(string title, string message) - { - await JsRuntime.InvokeVoidAsync("moonlight.alerts.info", title, message); - } - - public async Task Success(string title, string message) - { - await JsRuntime.InvokeVoidAsync("moonlight.alerts.success", title, message); - } - - public async Task Warning(string title, string message) - { - await JsRuntime.InvokeVoidAsync("moonlight.alerts.warning", title, message); - } - - public async Task Error(string title, string message) - { - await JsRuntime.InvokeVoidAsync("moonlight.alerts.error", title, message); - } - - public async Task Text(string title, string message) - { - return await JsRuntime.InvokeAsync("moonlight.alerts.text", title, message); - } - - public async Task YesNo(string title, string yes, string no) - { - try - { - return await JsRuntime.InvokeAsync("moonlight.alerts.yesno", title, yes, no); - } - catch (Exception) - { - return false; - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Interop/ClipboardService.cs b/Moonlight/Core/Services/Interop/ClipboardService.cs deleted file mode 100644 index 6fb7b765..00000000 --- a/Moonlight/Core/Services/Interop/ClipboardService.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Microsoft.JSInterop; - -namespace Moonlight.Core.Services.Interop; - -public class ClipboardService -{ - private readonly IJSRuntime JsRuntime; - - public ClipboardService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - } - - public async Task Copy(string content) - { - await JsRuntime.InvokeVoidAsync("moonlight.clipboard.copy", content); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Interop/CookieService.cs b/Moonlight/Core/Services/Interop/CookieService.cs deleted file mode 100644 index d1711742..00000000 --- a/Moonlight/Core/Services/Interop/CookieService.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Microsoft.JSInterop; - -namespace Moonlight.Core.Services.Interop; - -public class CookieService -{ - private readonly IJSRuntime JsRuntime; - private string Expires = ""; - - public CookieService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - ExpireDays = 300; - } - - public async Task SetValue(string key, string value, int? days = null) - { - var curExp = (days != null) ? (days > 0 ? DateToUTC(days.Value) : "") : Expires; - await SetCookie($"{key}={value}; expires={curExp}; path=/"); - } - - public async Task GetValue(string key, string def = "") - { - var cookieString = await GetCookie(); - - var cookieParts = cookieString.Split(";"); - - foreach (var cookiePart in cookieParts) - { - if(string.IsNullOrEmpty(cookiePart)) - continue; - - var cookieKeyValue = cookiePart.Split("=") - .Select(x => x.Trim()) // There may be spaces e.g. with the "AspNetCore.Culture" key - .ToArray(); - - if (cookieKeyValue.Length == 2) - { - if (cookieKeyValue[0] == key) - return cookieKeyValue[1]; - } - } - - return def; - } - - private async Task SetCookie(string value) - { - await JsRuntime.InvokeVoidAsync("eval", $"document.cookie = \"{value}\""); - } - - private async Task GetCookie() - { - return await JsRuntime.InvokeAsync("eval", $"document.cookie"); - } - - private int ExpireDays - { - set => Expires = DateToUTC(value); - } - - private static string DateToUTC(int days) => DateTime.Now.AddDays(days).ToUniversalTime().ToString("R"); -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Interop/FileDownloadService.cs b/Moonlight/Core/Services/Interop/FileDownloadService.cs deleted file mode 100644 index 7b9b5987..00000000 --- a/Moonlight/Core/Services/Interop/FileDownloadService.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Text; -using Microsoft.JSInterop; - -namespace Moonlight.Core.Services.Interop; - -public class FileDownloadService -{ - private readonly IJSRuntime JsRuntime; - - public FileDownloadService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - } - - public async Task DownloadStream(string fileName, Stream stream) - { - using var streamRef = new DotNetStreamReference(stream); - - await JsRuntime.InvokeVoidAsync("moonlight.utils.download", fileName, streamRef); - } - - public async Task DownloadBytes(string fileName, byte[] bytes) - { - var ms = new MemoryStream(bytes); - - await DownloadStream(fileName, ms); - - ms.Close(); - await ms.DisposeAsync(); - } - - public async Task DownloadString(string fileName, string content) => - await DownloadBytes(fileName, Encoding.UTF8.GetBytes(content)); -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Interop/ModalService.cs b/Moonlight/Core/Services/Interop/ModalService.cs deleted file mode 100644 index c9f8819e..00000000 --- a/Moonlight/Core/Services/Interop/ModalService.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.JSInterop; - -namespace Moonlight.Core.Services.Interop; - -public class ModalService -{ - private readonly IJSRuntime JsRuntime; - - public ModalService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - } - - public async Task Show(string id, bool focus = true) // Focus can be specified to fix issues with other components - { - try - { - await JsRuntime.InvokeVoidAsync("moonlight.modals.show", id, focus); - } - catch (Exception) - { - // ignored - } - } - - public async Task Hide(string id) - { - try - { - await JsRuntime.InvokeVoidAsync("moonlight.modals.hide", id); - } - catch (Exception) - { - // Ignored - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Interop/ToastService.cs b/Moonlight/Core/Services/Interop/ToastService.cs deleted file mode 100644 index 3e83dac7..00000000 --- a/Moonlight/Core/Services/Interop/ToastService.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Microsoft.JSInterop; - -namespace Moonlight.Core.Services.Interop; - -public class ToastService -{ - private readonly IJSRuntime JsRuntime; - - public ToastService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - } - - public async Task Success(string title, string message, int timeout = 5000) - { - await JsRuntime.InvokeVoidAsync("moonlight.toasts.success", title, message, timeout); - } - - public async Task Info(string title, string message, int timeout = 5000) - { - await JsRuntime.InvokeVoidAsync("moonlight.toasts.info", title, message, timeout); - } - - public async Task Danger(string title, string message, int timeout = 5000) - { - await JsRuntime.InvokeVoidAsync("moonlight.toasts.danger", title, message, timeout); - } - - public async Task Warning(string title, string message, int timeout = 5000) - { - await JsRuntime.InvokeVoidAsync("moonlight.toasts.warning", title, message, timeout); - } - - // Overloads - - public async Task Success(string message, int timeout = 5000) - { - await Success("", message, timeout); - } - - public async Task Info(string message, int timeout = 5000) - { - await Info("", message, timeout); - } - - public async Task Danger(string message, int timeout = 5000) - { - await Danger("", message, timeout); - } - - public async Task Warning(string message, int timeout = 5000) - { - await Warning("", message, timeout); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/MailService.cs b/Moonlight/Core/Services/MailService.cs index c025d27b..e5a94e4f 100644 --- a/Moonlight/Core/Services/MailService.cs +++ b/Moonlight/Core/Services/MailService.cs @@ -1,16 +1,20 @@ using MailKit.Net.Smtp; using MimeKit; +using MoonCore.Attributes; +using MoonCore.Helpers; +using MoonCore.Services; +using Moonlight.Core.Configuration; using Moonlight.Core.Database.Entities; -using Moonlight.Core.Helpers; namespace Moonlight.Core.Services; +[Singleton] public class MailService { - private readonly ConfigService ConfigService; + private readonly ConfigService ConfigService; private readonly string BasePath; - public MailService(ConfigService configService) + public MailService(ConfigService configService) { ConfigService = configService; diff --git a/Moonlight/Core/Services/MoonlightService.cs b/Moonlight/Core/Services/MoonlightService.cs index 44e65214..cbfbc0f2 100644 --- a/Moonlight/Core/Services/MoonlightService.cs +++ b/Moonlight/Core/Services/MoonlightService.cs @@ -1,21 +1,25 @@ using System.IO.Compression; +using MoonCore.Attributes; +using MoonCore.Helpers; +using MoonCore.Services; +using Moonlight.Core.Configuration; using Moonlight.Core.Event; using Moonlight.Core.Extensions; -using Moonlight.Core.Helpers; using Moonlight.Features.Theming.Services; namespace Moonlight.Core.Services; +[Singleton] public class MoonlightService // This service can be used to perform strictly panel specific actions { - private readonly ConfigService ConfigService; + private readonly ConfigService ConfigService; private readonly IServiceProvider ServiceProvider; public WebApplication Application { get; set; } // Do NOT modify using a plugin public string LogPath { get; set; } // Do NOT modify using a plugin public ThemeService Theme => ServiceProvider.GetRequiredService(); - public MoonlightService(ConfigService configService, IServiceProvider serviceProvider) + public MoonlightService(ConfigService configService, IServiceProvider serviceProvider) { ConfigService = configService; ServiceProvider = serviceProvider; @@ -53,9 +57,11 @@ public class MoonlightService // This service can be used to perform strictly pa // TODO: Add node settings here + // TODO: Reimplement as extension here + // Add config - var config = ConfigService.GetDiagnoseJson(); - await zip.AddFromText("config.json", config); + //var config = ConfigService.GetDiagnoseJson(); + //await zip.AddFromText("config.json", config); // Make a list of plugins var pluginService = scope.ServiceProvider.GetRequiredService(); diff --git a/Moonlight/Core/Services/PluginService.cs b/Moonlight/Core/Services/PluginService.cs index 74f70a39..a4334bf2 100644 --- a/Moonlight/Core/Services/PluginService.cs +++ b/Moonlight/Core/Services/PluginService.cs @@ -1,5 +1,5 @@ using System.Reflection; -using Moonlight.Core.Helpers; +using MoonCore.Helpers; using Moonlight.Core.Plugins; using Moonlight.Core.Plugins.Contexts; using Moonlight.Features.ServiceManagement.Models.Abstractions; diff --git a/Moonlight/Core/Services/SessionService.cs b/Moonlight/Core/Services/SessionService.cs index 61c7adf8..c66452d2 100644 --- a/Moonlight/Core/Services/SessionService.cs +++ b/Moonlight/Core/Services/SessionService.cs @@ -1,7 +1,9 @@ -using Moonlight.Core.Models.Abstractions; +using MoonCore.Attributes; +using Moonlight.Core.Models.Abstractions; namespace Moonlight.Core.Services; +[Singleton] public class SessionService { private readonly List AllSessions = new(); diff --git a/Moonlight/Core/Services/Users/UserAuthService.cs b/Moonlight/Core/Services/Users/UserAuthService.cs index 78217cc6..f09ca716 100644 --- a/Moonlight/Core/Services/Users/UserAuthService.cs +++ b/Moonlight/Core/Services/Users/UserAuthService.cs @@ -1,28 +1,32 @@ -using Moonlight.Core.Database.Entities; +using MoonCore.Abstractions; +using MoonCore.Attributes; +using MoonCore.Exceptions; +using MoonCore.Helpers; +using MoonCore.Services; +using Moonlight.Core.Configuration; +using Moonlight.Core.Database.Entities; using Moonlight.Core.Event; -using Moonlight.Core.Exceptions; using Moonlight.Core.Extensions; -using Moonlight.Core.Helpers; using Moonlight.Core.Models.Abstractions; using Moonlight.Core.Models.Enums; using Moonlight.Core.Models.Templates; -using Moonlight.Core.Repositories; using Moonlight.Core.Services.Utils; using OtpNet; namespace Moonlight.Core.Services.Users; +[Scoped] public class UserAuthService { private readonly Repository UserRepository; private readonly JwtService JwtService; - private readonly ConfigService ConfigService; + private readonly ConfigService ConfigService; private readonly MailService MailService; public UserAuthService( Repository userRepository, JwtService jwtService, - ConfigService configService, + ConfigService configService, MailService mailService) { UserRepository = userRepository; diff --git a/Moonlight/Core/Services/Users/UserDeleteService.cs b/Moonlight/Core/Services/Users/UserDeleteService.cs index 07a31acb..502a8aac 100644 --- a/Moonlight/Core/Services/Users/UserDeleteService.cs +++ b/Moonlight/Core/Services/Users/UserDeleteService.cs @@ -1,6 +1,8 @@ using Microsoft.EntityFrameworkCore; +using MoonCore.Abstractions; +using MoonCore.Attributes; using Moonlight.Core.Database.Entities; -using Moonlight.Core.Repositories; + using Moonlight.Features.Community.Entities; using Moonlight.Features.Community.Services; using Moonlight.Features.ServiceManagement.Entities; @@ -10,6 +12,7 @@ using Moonlight.Features.Ticketing.Entities; namespace Moonlight.Core.Services.Users; +[Scoped] public class UserDeleteService { private readonly Repository ServiceRepository; diff --git a/Moonlight/Core/Services/Users/UserDetailsService.cs b/Moonlight/Core/Services/Users/UserDetailsService.cs index 96b3178d..1d56c1b7 100644 --- a/Moonlight/Core/Services/Users/UserDetailsService.cs +++ b/Moonlight/Core/Services/Users/UserDetailsService.cs @@ -1,8 +1,11 @@ -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Repositories; +using MoonCore.Abstractions; +using MoonCore.Attributes; +using Moonlight.Core.Database.Entities; + namespace Moonlight.Core.Services.Users; +[Scoped] public class UserDetailsService { private readonly BucketService BucketService; diff --git a/Moonlight/Core/Services/Users/UserService.cs b/Moonlight/Core/Services/Users/UserService.cs index 798e8493..dc54a9f1 100644 --- a/Moonlight/Core/Services/Users/UserService.cs +++ b/Moonlight/Core/Services/Users/UserService.cs @@ -1,9 +1,11 @@ -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Exceptions; -using Moonlight.Core.Repositories; +using MoonCore.Abstractions; +using MoonCore.Attributes; +using MoonCore.Exceptions; +using Moonlight.Core.Database.Entities; namespace Moonlight.Core.Services.Users; +[Scoped] public class UserService { private readonly Repository UserRepository; diff --git a/Moonlight/Core/Services/Utils/ConnectionService.cs b/Moonlight/Core/Services/Utils/ConnectionService.cs index e79e10b9..3888cd63 100644 --- a/Moonlight/Core/Services/Utils/ConnectionService.cs +++ b/Moonlight/Core/Services/Utils/ConnectionService.cs @@ -1,13 +1,17 @@ -using Moonlight.Core.Helpers; +using MoonCore.Attributes; +using MoonCore.Helpers; +using MoonCore.Services; +using Moonlight.Core.Configuration; namespace Moonlight.Core.Services.Utils; +[Scoped] public class ConnectionService { private readonly IHttpContextAccessor ContextAccessor; - private readonly ConfigService ConfigService; + private readonly ConfigService ConfigService; - public ConnectionService(IHttpContextAccessor contextAccessor, ConfigService configService) + public ConnectionService(IHttpContextAccessor contextAccessor, ConfigService configService) { ContextAccessor = contextAccessor; ConfigService = configService; diff --git a/Moonlight/Core/Services/Utils/JwtService.cs b/Moonlight/Core/Services/Utils/JwtService.cs index 2712ea12..ef671370 100644 --- a/Moonlight/Core/Services/Utils/JwtService.cs +++ b/Moonlight/Core/Services/Utils/JwtService.cs @@ -1,16 +1,20 @@ using JWT.Algorithms; using JWT.Builder; -using Moonlight.Core.Helpers; +using MoonCore.Attributes; +using MoonCore.Helpers; +using MoonCore.Services; +using Moonlight.Core.Configuration; using Newtonsoft.Json; namespace Moonlight.Core.Services.Utils; +[Singleton] public class JwtService { - private readonly ConfigService ConfigService; + private readonly ConfigService ConfigService; private readonly TimeSpan DefaultDuration = TimeSpan.FromDays(365 * 10); - public JwtService(ConfigService configService) + public JwtService(ConfigService configService) { ConfigService = configService; } diff --git a/Moonlight/Core/UI/Components/Auth/ChangePassword.razor b/Moonlight/Core/UI/Components/Auth/ChangePassword.razor index 58c87695..dbc3369f 100644 --- a/Moonlight/Core/UI/Components/Auth/ChangePassword.razor +++ b/Moonlight/Core/UI/Components/Auth/ChangePassword.razor @@ -1,9 +1,9 @@ @using Moonlight.Core.Models.Forms -@using Moonlight.Core.Exceptions @using Moonlight.Core.Models.Enums @using Moonlight.Core.Models.Forms.Auth @using Moonlight.Core.Services @using Moonlight.Core.Services.Users +@using MoonCore.Exceptions @inject IdentityService IdentityService @inject UserService UserService diff --git a/Moonlight/Core/UI/Components/Auth/Login.razor b/Moonlight/Core/UI/Components/Auth/Login.razor index a4520e20..489414fe 100644 --- a/Moonlight/Core/UI/Components/Auth/Login.razor +++ b/Moonlight/Core/UI/Components/Auth/Login.razor @@ -3,7 +3,7 @@ @using Moonlight.Core.Models.Forms @using Moonlight.Core.Models.Forms.Auth @using Moonlight.Core.Services -@using Moonlight.Core.Services.Interop +@using MoonCoreUI.Services @inject IdentityService IdentityService @inject CookieService CookieService diff --git a/Moonlight/Core/UI/Components/Auth/Register.razor b/Moonlight/Core/UI/Components/Auth/Register.razor index 69997637..9ed149c1 100644 --- a/Moonlight/Core/UI/Components/Auth/Register.razor +++ b/Moonlight/Core/UI/Components/Auth/Register.razor @@ -1,11 +1,11 @@ @page "/register" @* Virtual route to trick blazor *@ @using Moonlight.Core.Models.Forms -@using Moonlight.Core.Exceptions @using Moonlight.Core.Models.Forms.Auth @using Moonlight.Core.Services -@using Moonlight.Core.Services.Interop @using Moonlight.Core.Services.Users +@using MoonCore.Exceptions +@using MoonCoreUI.Services @inject IdentityService IdentityService @inject UserService UserService diff --git a/Moonlight/Core/UI/Components/Forms/AutoCrud.razor b/Moonlight/Core/UI/Components/Forms/AutoCrud.razor deleted file mode 100644 index 0cdd39cc..00000000 --- a/Moonlight/Core/UI/Components/Forms/AutoCrud.razor +++ /dev/null @@ -1,242 +0,0 @@ -@using BlazorTable -@using System.Linq.Expressions -@using Mappy.Net -@using Moonlight.Core.Repositories -@using Moonlight.Core.Services.Interop - -@typeparam TItem where TItem : class -@typeparam TCreateForm -@typeparam TUpdateForm - -@inject Repository ItemRepository -@inject ToastService ToastService - -
-
-

@(Title)

-
- @Toolbar - -
-
-
- - - @View - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - -@code -{ - [Parameter] - public string Title { get; set; } = ""; - - [Parameter] - public Func, TItem[]> Load { get; set; } - - [Parameter] - public RenderFragment View { get; set; } - - [Parameter] - public RenderFragment Toolbar { get; set; } - - [Parameter] - public Func? ValidateAdd { get; set; } - - [Parameter] - public Func? ValidateUpdate { get; set; } - - [Parameter] - public Func? ValidateDelete { get; set; } - - private TItem[] Items; - private TCreateForm CreateForm; - private TUpdateForm UpdateForm; - private TItem ItemToUpdate; - private TItem ItemToDelete; - - private SmartModal CreateModal; - private SmartModal UpdateModal; - private SmartModal DeleteModal; - - private Expression> IdExpression; - private LazyLoader LazyLoader; - - protected override void OnInitialized() - { - if (Load == null) - throw new ArgumentNullException(nameof(Load)); - - CreateForm = Activator.CreateInstance()!; - UpdateForm = Activator.CreateInstance()!; - - IdExpression = CreateExpression(); - } - - public async Task Reload() => await LazyLoader.Reload(); - - private Task LoadItems(LazyLoader _) - { - Items = Load.Invoke(ItemRepository); - - return Task.CompletedTask; - } - - private async Task StartUpdate(TItem item) - { - UpdateForm = Mapper.Map(item); - ItemToUpdate = item; - await UpdateModal.Show(); - } - - private async Task FinishUpdate() - { - var item = Mapper.Map(ItemToUpdate, UpdateForm!); - - if (ValidateUpdate != null) // Optional additional validation - await ValidateUpdate.Invoke(item); - - ItemRepository.Update(item); - - // Reset - await UpdateModal.Hide(); - await LazyLoader.Reload(); - await ToastService.Success("Successfully updated item"); - } - - private async Task StartCreate() - { - CreateForm = Activator.CreateInstance()!; - await CreateModal.Show(); - } - - private async Task FinishCreate() - { - var item = Mapper.Map(CreateForm!); - - if (ValidateAdd != null) // Optional additional validation - await ValidateAdd.Invoke(item); - - ItemRepository.Add(item); - - // Reset - await CreateModal.Hide(); - await LazyLoader.Reload(); - await ToastService.Success("Successfully added item"); - } - - private async Task StartDelete(TItem item) - { - ItemToDelete = item; - await DeleteModal.Show(); - } - - private async Task FinishDelete() - { - if (ValidateDelete != null) // Optional additional validation - await ValidateDelete.Invoke(ItemToDelete); - - ItemRepository.Delete(ItemToDelete); - - // Reset - await DeleteModal.Hide(); - await LazyLoader.Reload(); - await ToastService.Success("Successfully deleted item"); - } - - private Expression> CreateExpression() - { - // Parameter expression for the input object - var inputParam = Expression.Parameter(typeof(TItem), "input"); - - // Convert the input object to the actual model type (MyModel in this example) - var castedInput = Expression.Convert(inputParam, typeof(TItem)); - - // Create a property access expression using the property name - var propertyAccess = Expression.Property(castedInput, "Id"); - - // Convert the property value to an object - var castedResult = Expression.Convert(propertyAccess, typeof(object)); - - // Create a lambda expression - var lambda = Expression.Lambda>(castedResult, inputParam); - - return lambda; - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Forms/AutoForm.razor b/Moonlight/Core/UI/Components/Forms/AutoForm.razor deleted file mode 100644 index b3d248e8..00000000 --- a/Moonlight/Core/UI/Components/Forms/AutoForm.razor +++ /dev/null @@ -1,27 +0,0 @@ -@using Moonlight.Core.Helpers -@typeparam TForm - -@foreach (var prop in typeof(TForm).GetProperties()) -{ -
- @{ - var typeToCreate = typeof(AutoProperty<>).MakeGenericType(prop.PropertyType); - var rf = ComponentHelper.FromType(typeToCreate, parameters => - { - parameters.Add("Data", Model); - parameters.Add("Property", prop); - }); - } - - @rf -
-} - -@code -{ - [Parameter] - public TForm Model { get; set; } - - [Parameter] - public int Columns { get; set; } = 6; -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Forms/AutoListCrud.razor b/Moonlight/Core/UI/Components/Forms/AutoListCrud.razor deleted file mode 100644 index 6d1dc2d8..00000000 --- a/Moonlight/Core/UI/Components/Forms/AutoListCrud.razor +++ /dev/null @@ -1,255 +0,0 @@ -@using BlazorTable -@using System.Linq.Expressions -@using Mappy.Net -@using Moonlight.Core.Repositories -@using Moonlight.Core.Services.Interop - -@typeparam TItem where TItem : class -@typeparam TRootItem where TRootItem : class -@typeparam TCreateForm -@typeparam TUpdateForm - -@inject ToastService ToastService -@inject Repository RootRepository -@inject Repository ItemRepository - -
-
-

@(Title)

-
- @Toolbar - -
-
-
- - - @View - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - -@code -{ - [Parameter] - public string Title { get; set; } = ""; - - [Parameter] - public TRootItem RootItem { get; set; } - - [Parameter] - public Func> Field { get; set; } - - [Parameter] - public RenderFragment View { get; set; } - - [Parameter] - public RenderFragment Toolbar { get; set; } - - [Parameter] - public Func? ValidateAdd { get; set; } - - [Parameter] - public Func? ValidateUpdate { get; set; } - - [Parameter] - public Func? ValidateDelete { get; set; } - - private TItem[] Items; - private TCreateForm CreateForm; - private TUpdateForm UpdateForm; - private TItem ItemToUpdate; - private TItem ItemToDelete; - - private SmartModal CreateModal; - private SmartModal UpdateModal; - private SmartModal DeleteModal; - - private Expression> IdExpression; - private LazyLoader LazyLoader; - - protected override void OnInitialized() - { - if (Field == null) - throw new ArgumentNullException(nameof(Field)); - - CreateForm = Activator.CreateInstance()!; - UpdateForm = Activator.CreateInstance()!; - - IdExpression = CreateExpression(); - } - - public async Task Reload() => await LazyLoader.Reload(); - - private Task LoadItems(LazyLoader _) - { - Items = Field.Invoke(RootItem).ToArray(); - - return Task.CompletedTask; - } - - private async Task StartUpdate(TItem item) - { - UpdateForm = Mapper.Map(item); - ItemToUpdate = item; - await UpdateModal.Show(); - } - - private async Task FinishUpdate() - { - var item = Mapper.Map(ItemToUpdate, UpdateForm!); - - if (ValidateUpdate != null) // Optional additional validation - await ValidateUpdate.Invoke(item); - - ItemRepository.Update(item); - - // Reset - await UpdateModal.Hide(); - await LazyLoader.Reload(); - await ToastService.Success("Successfully updated item"); - } - - private async Task StartCreate() - { - CreateForm = Activator.CreateInstance()!; - await CreateModal.Show(); - } - - private async Task FinishCreate() - { - var item = Mapper.Map(CreateForm!); - - if (ValidateAdd != null) // Optional additional validation - await ValidateAdd.Invoke(item); - - Field.Invoke(RootItem).Add(item); - RootRepository.Update(RootItem); - - // Reset - await CreateModal.Hide(); - await LazyLoader.Reload(); - await ToastService.Success("Successfully added item"); - } - - private async Task StartDelete(TItem item) - { - ItemToDelete = item; - await DeleteModal.Show(); - } - - private async Task FinishDelete() - { - if (ValidateDelete != null) // Optional additional validation - await ValidateDelete.Invoke(ItemToDelete); - - Field.Invoke(RootItem).Remove(ItemToDelete); - RootRepository.Update(RootItem); - - try - { - ItemRepository.Delete(ItemToDelete); - } - catch (Exception) { /* ignored, as we dont want such an operation to fail the request */ } - - // Reset - await DeleteModal.Hide(); - await LazyLoader.Reload(); - await ToastService.Success("Successfully deleted item"); - } - - private Expression> CreateExpression() - { - // Parameter expression for the input object - var inputParam = Expression.Parameter(typeof(TItem), "input"); - - // Convert the input object to the actual model type (MyModel in this example) - var castedInput = Expression.Convert(inputParam, typeof(TItem)); - - // Create a property access expression using the property name - var propertyAccess = Expression.Property(castedInput, "Id"); - - // Convert the property value to an object - var castedResult = Expression.Convert(propertyAccess, typeof(object)); - - // Create a lambda expression - var lambda = Expression.Lambda>(castedResult, inputParam); - - return lambda; - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Forms/AutoProperty.razor b/Moonlight/Core/UI/Components/Forms/AutoProperty.razor deleted file mode 100644 index 71afe7e8..00000000 --- a/Moonlight/Core/UI/Components/Forms/AutoProperty.razor +++ /dev/null @@ -1,157 +0,0 @@ -@using System.Reflection -@using System.ComponentModel -@using Microsoft.AspNetCore.Components.Forms -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Helpers -@using Moonlight.Core.Repositories - -@typeparam TProp -@inject IServiceProvider ServiceProvider - - - -@* Description using attribute *@ - -@{ - var attrs = Property.GetCustomAttributes(true); - - var descAttr = attrs - .FirstOrDefault(x => x.GetType() == typeof(DescriptionAttribute)); -} - -@if (descAttr != null) -{ - var attribute = descAttr as DescriptionAttribute; - -
- @(attribute!.Description) -
-} - -@* Actual value binding *@ - -
- @if (Property.PropertyType == typeof(string)) - { -
- -
- } - else if (Property.PropertyType == typeof(int)) - { - - } - else if (Property.PropertyType == typeof(double)) - { - - } - else if (Property.PropertyType == typeof(long)) - { - - } - else if (Property.PropertyType == typeof(bool)) - { -
- -
- } - else if (Property.PropertyType == typeof(DateTime)) - { - - } - else if (Property.PropertyType == typeof(decimal)) - { - - } - else if (Property.PropertyType.IsEnum) - { - - } - else if (Property.PropertyType.IsClass) - { - var attribute = Property.GetCustomAttributes(true) - .FirstOrDefault(x => x.GetType() == typeof(SelectorAttribute)) as SelectorAttribute; - - if (attribute != null) - { - if (attribute.UseDropdown) - { - var displayFunc = new Func(x => - { - var prop = typeof(TProp).GetProperties().First(x => x.Name == attribute.DisplayProp); - return prop.GetValue(x) as string ?? "N/A"; - }); - - var searchFunc = new Func(x => - { - var prop = typeof(TProp).GetProperties().First(x => x.Name == attribute.SelectorProp); - return prop.GetValue(x) as string ?? "N/A"; - }); - - - } - else - { - var displayFunc = new Func(x => - { - var prop = typeof(TProp).GetProperties().First(x => x.Name == attribute.DisplayProp); - return prop.GetValue(x) as string ?? "N/A"; - }); - - - } - } - } -
- -@code -{ - [Parameter] - public object Data { get; set; } - - [Parameter] - public PropertyInfo Property { get; set; } - - private PropBinder Binder; - private TProp[] Items = Array.Empty(); - - protected override void OnInitialized() - { - Binder = new(Property, Data); - } - - protected override void OnParametersSet() - { - Binder = new(Property, Data); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - if (Property.GetCustomAttributes(true).Any(x => x.GetType() == typeof(SelectorAttribute))) - { - var typeToGetByDi = typeof(Repository<>).MakeGenericType(typeof(TProp)); - var repo = ServiceProvider.GetRequiredService(typeToGetByDi); - var dbSet = repo.GetType().GetMethods().First(x => x.Name == "Get").Invoke(repo, null) as IEnumerable; - Items = dbSet!.ToArray(); - - await InvokeAsync(StateHasChanged); - } - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Forms/ConfirmButton.razor b/Moonlight/Core/UI/Components/Forms/ConfirmButton.razor deleted file mode 100644 index fc920b8f..00000000 --- a/Moonlight/Core/UI/Components/Forms/ConfirmButton.razor +++ /dev/null @@ -1,66 +0,0 @@ -@if (ShowConfirm) -{ -
- - -
-} -else -{ - if (Working) - { - - } - else - { - - } -} - -@code -{ - private bool Working { get; set; } = false; - private bool ShowConfirm = false; - - [Parameter] - public string CssClasses { get; set; } = "btn-primary"; - - [Parameter] - public string Text { get; set; } = ""; - - [Parameter] - public string WorkingText { get; set; } = ""; - - [Parameter] - public Func? OnClick { get; set; } - - [Parameter] - public RenderFragment ChildContent { get; set; } - - private async Task SetConfirm(bool b) - { - ShowConfirm = b; - await InvokeAsync(StateHasChanged); - } - - private async Task Do() - { - Working = true; - ShowConfirm = false; - StateHasChanged(); - await Task.Run(async () => - { - if (OnClick != null) - await OnClick.Invoke(); - - Working = false; - await InvokeAsync(StateHasChanged); - }); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Forms/DynamicTypedAutoForm.razor b/Moonlight/Core/UI/Components/Forms/DynamicTypedAutoForm.razor deleted file mode 100644 index cd918127..00000000 --- a/Moonlight/Core/UI/Components/Forms/DynamicTypedAutoForm.razor +++ /dev/null @@ -1,20 +0,0 @@ -@using Moonlight.Core.Helpers -@{ - var typeToCreate = typeof(AutoForm<>).MakeGenericType(Model.GetType()); - var rf = ComponentHelper.FromType(typeToCreate, parameter => - { - parameter.Add("Model", Model); - parameter.Add("Columns", Columns); - }); -} - -@rf - -@code -{ - [Parameter] - public object Model { get; set; } - - [Parameter] - public int Columns { get; set; } = 6; -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Forms/SmartCustomFileSelect.razor b/Moonlight/Core/UI/Components/Forms/SmartCustomFileSelect.razor deleted file mode 100644 index 0897bba2..00000000 --- a/Moonlight/Core/UI/Components/Forms/SmartCustomFileSelect.razor +++ /dev/null @@ -1,58 +0,0 @@ -@using Microsoft.AspNetCore.Components.Forms -@using Moonlight.Core.Helpers -@using Moonlight.Core.Services.Interop - -@inject ToastService ToastService - -