diff --git a/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs b/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs index 72f0c84..91da0bf 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; @@ -11,14 +10,14 @@ public class DummyServiceDefinition : ServiceDefinition public override Type ConfigType => typeof(DummyConfig); public override async Task BuildUserView(ServiceViewContext context) { - context.Layout = ComponentHelper.FromType(); + context.Layout = typeof(DummyUser); await context.AddPage("Demo", "/demo"); } public override Task BuildAdminView(ServiceViewContext context) { - context.Layout = ComponentHelper.FromType(); + context.Layout = typeof(DummyAdmin); return Task.CompletedTask; } diff --git a/Moonlight/Core/Configuration/ConfigV1.cs b/Moonlight/Core/Configuration/ConfigV1.cs index 251f5f8..51a378f 100644 --- a/Moonlight/Core/Configuration/ConfigV1.cs +++ b/Moonlight/Core/Configuration/ConfigV1.cs @@ -1,6 +1,8 @@ using System.ComponentModel; -using Moonlight.Core.Helpers; +using MoonCore.Helpers; using Moonlight.Features.Advertisement.Configuration; +using Moonlight.Features.FileManager.Configuration; +using Moonlight.Features.Servers.Configuration; using Moonlight.Features.StoreSystem.Configuration; using Moonlight.Features.Theming.Configuration; using Newtonsoft.Json; @@ -22,6 +24,19 @@ public class ConfigV1 [JsonProperty("Theme")] public ThemeData Theme { get; set; } = new(); [JsonProperty("Advertisement")] public AdvertisementData Advertisement { get; set; } = new(); + [JsonProperty("FileManager")] public FileManagerData FileManager { get; set; } = new(); + + [JsonProperty("WebServer")] public WebServerData WebServer { get; set; } = new(); + + [JsonProperty("Servers")] public ServersData Servers { get; set; } = new(); + + public class WebServerData + { + [JsonProperty("HttpUploadLimit")] + [Description("This sets the kestrel upload limit in megabytes. Changing this will need an restart")] + public int HttpUploadLimit { get; set; } = 100 * 1024; + } + public class SecurityData { [JsonProperty("Token")] diff --git a/Moonlight/Core/Database/DataContext.cs b/Moonlight/Core/Database/DataContext.cs index 6667857..53a354a 100644 --- a/Moonlight/Core/Database/DataContext.cs +++ b/Moonlight/Core/Database/DataContext.cs @@ -1,7 +1,10 @@ using Microsoft.EntityFrameworkCore; +using MoonCore.Services; +using Moonlight.Core.Configuration; using Moonlight.Core.Database.Entities; using Moonlight.Core.Services; using Moonlight.Features.Community.Entities; +using Moonlight.Features.Servers.Entities; using Moonlight.Features.ServiceManagement.Entities; using Moonlight.Features.StoreSystem.Entities; using Moonlight.Features.Theming.Entities; @@ -11,7 +14,7 @@ namespace Moonlight.Core.Database; public class DataContext : DbContext { - private readonly ConfigService ConfigService; + private readonly ConfigService ConfigService; public DbSet Users { get; set; } @@ -39,8 +42,18 @@ public class DataContext : DbContext // Themes public DbSet Themes { get; set; } + + // Servers + public DbSet Servers { get; set; } + public DbSet ServerAllocations { get; set; } + public DbSet ServerImages { get; set; } + public DbSet ServerNodes { get; set; } + public DbSet ServerVariables { get; set; } + public DbSet ServerDockerImages { get; set; } + public DbSet ServerImageVariables { get; set; } + public DbSet ServerSchedules { get; set; } - public DataContext(ConfigService configService) + public DataContext(ConfigService configService) { ConfigService = configService; } diff --git a/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.Designer.cs b/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.Designer.cs new file mode 100644 index 0000000..0fb9d13 --- /dev/null +++ b/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.Designer.cs @@ -0,0 +1,1026 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Moonlight.Core.Database; + +#nullable disable + +namespace Moonlight.Core.Database.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20240127110558_AddedServerModels")] + partial class AddedServerModels + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); + + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Avatar") + .HasColumnType("TEXT"); + + b.Property("Balance") + .HasColumnType("REAL"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Flags") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Permissions") + .HasColumnType("INTEGER"); + + b.Property("TokenValidTimestamp") + .HasColumnType("TEXT"); + + b.Property("TotpKey") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("PostId"); + + b.ToTable("PostComments"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostLikes"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.WordFilter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Filter") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("WordFilters"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Cpu") + .HasColumnType("INTEGER"); + + b.Property("Disk") + .HasColumnType("INTEGER"); + + b.Property("DockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MainAllocationId") + .HasColumnType("INTEGER"); + + b.Property("Memory") + .HasColumnType("INTEGER"); + + b.Property("NodeId") + .HasColumnType("INTEGER"); + + b.Property("OverrideStartupCommand") + .HasColumnType("TEXT"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("MainAllocationId"); + + b.HasIndex("NodeId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Servers"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("ServerNodeId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("ServerNodeId"); + + b.ToTable("ServerAllocations"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AutoPull") + .HasColumnType("INTEGER"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerDockerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllocationsNeeded") + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DefaultDockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("InstallDockerImage") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallScript") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallShell") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OnlineDetection") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParseConfigurations") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StartupCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StopCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdateUrl") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ServerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowUserToEdit") + .HasColumnType("INTEGER"); + + b.Property("AllowUserToView") + .HasColumnType("INTEGER"); + + b.Property("DefaultValue") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ServerImageVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Fqdn") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FtpPort") + .HasColumnType("INTEGER"); + + b.Property("HttpPort") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Token") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UseSsl") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ServerNodes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConfigJsonOverride") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Nickname") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("INTEGER"); + + b.Property("ProductId") + .HasColumnType("INTEGER"); + + b.Property("RenewAt") + .HasColumnType("TEXT"); + + b.Property("Suspended") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.HasIndex("ProductId"); + + b.ToTable("Services"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServiceId"); + + b.HasIndex("UserId"); + + b.ToTable("ServiceShares"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Coupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Percent") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Coupons"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CouponId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CouponId"); + + b.HasIndex("UserId"); + + b.ToTable("CouponUses"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("REAL"); + + b.HasKey("Id"); + + b.ToTable("GiftCodes"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GiftCodeId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GiftCodeId"); + + b.HasIndex("UserId"); + + b.ToTable("GiftCodeUses"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.Property("ConfigJson") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Duration") + .HasColumnType("INTEGER"); + + b.Property("MaxPerUser") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Stock") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.Property("Text") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Transaction"); + }); + + modelBuilder.Entity("Moonlight.Features.Theming.Entities.Theme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CssUrl") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("JsUrl") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Themes"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatorId") + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Open") + .HasColumnType("INTEGER"); + + b.Property("Priority") + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("Tries") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Tickets"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attachment") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsSupport") + .HasColumnType("INTEGER"); + + b.Property("SenderId") + .HasColumnType("INTEGER"); + + b.Property("TicketId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("SenderId"); + + b.HasIndex("TicketId"); + + b.ToTable("TicketMessages"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Community.Entities.Post", null) + .WithMany("Comments") + .HasForeignKey("PostId"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => + { + b.HasOne("Moonlight.Features.Community.Entities.Post", null) + .WithMany("Likes") + .HasForeignKey("PostId"); + + b.HasOne("Moonlight.Core.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerAllocation", "MainAllocation") + .WithMany() + .HasForeignKey("MainAllocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", "Node") + .WithMany() + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + + b.Navigation("MainAllocation"); + + b.Navigation("Node"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Allocations") + .HasForeignKey("ServerId"); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", null) + .WithMany("Allocations") + .HasForeignKey("ServerNodeId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("DockerImages") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Variables") + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.StoreSystem.Entities.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Owner"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", null) + .WithMany("Shares") + .HasForeignKey("ServiceId"); + + b.HasOne("Moonlight.Core.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Coupon", "Coupon") + .WithMany() + .HasForeignKey("CouponId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("CouponUses") + .HasForeignKey("UserId"); + + b.Navigation("Coupon"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.GiftCode", "GiftCode") + .WithMany() + .HasForeignKey("GiftCodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("GiftCodeUses") + .HasForeignKey("UserId"); + + b.Navigation("GiftCode"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("Transactions") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId"); + + b.Navigation("Creator"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Sender") + .WithMany() + .HasForeignKey("SenderId"); + + b.HasOne("Moonlight.Features.Ticketing.Entities.Ticket", null) + .WithMany("Messages") + .HasForeignKey("TicketId"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Navigation("CouponUses"); + + b.Navigation("GiftCodeUses"); + + b.Navigation("Transactions"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Navigation("Comments"); + + b.Navigation("Likes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Navigation("Allocations"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Navigation("DockerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Navigation("Allocations"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Navigation("Shares"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Navigation("Messages"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.cs b/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.cs new file mode 100644 index 0000000..7c53f5d --- /dev/null +++ b/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.cs @@ -0,0 +1,266 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Moonlight.Core.Database.Migrations +{ + /// + public partial class AddedServerModels : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ServerImages", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: false), + AllocationsNeeded = table.Column(type: "INTEGER", nullable: false), + StartupCommand = table.Column(type: "TEXT", nullable: false), + StopCommand = table.Column(type: "TEXT", nullable: false), + OnlineDetection = table.Column(type: "TEXT", nullable: false), + ParseConfigurations = table.Column(type: "TEXT", nullable: false), + InstallDockerImage = table.Column(type: "TEXT", nullable: false), + InstallShell = table.Column(type: "TEXT", nullable: false), + InstallScript = table.Column(type: "TEXT", nullable: false), + Author = table.Column(type: "TEXT", nullable: false), + DonateUrl = table.Column(type: "TEXT", nullable: true), + UpdateUrl = table.Column(type: "TEXT", nullable: true), + DefaultDockerImageIndex = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerImages", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ServerImageVariables", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Key = table.Column(type: "TEXT", nullable: false), + DefaultValue = table.Column(type: "TEXT", nullable: false), + DisplayName = table.Column(type: "TEXT", nullable: false), + Description = table.Column(type: "TEXT", nullable: false), + AllowUserToEdit = table.Column(type: "INTEGER", nullable: false), + AllowUserToView = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerImageVariables", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ServerNodes", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: false), + Fqdn = table.Column(type: "TEXT", nullable: false), + UseSsl = table.Column(type: "INTEGER", nullable: false), + Token = table.Column(type: "TEXT", nullable: false), + HttpPort = table.Column(type: "INTEGER", nullable: false), + FtpPort = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerNodes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ServerDockerImages", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: false), + DisplayName = table.Column(type: "TEXT", nullable: false), + AutoPull = table.Column(type: "INTEGER", nullable: false), + ServerImageId = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerDockerImages", x => x.Id); + table.ForeignKey( + name: "FK_ServerDockerImages_ServerImages_ServerImageId", + column: x => x.ServerImageId, + principalTable: "ServerImages", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "ServerAllocations", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + IpAddress = table.Column(type: "TEXT", nullable: false), + Port = table.Column(type: "INTEGER", nullable: false), + ServerId = table.Column(type: "INTEGER", nullable: true), + ServerNodeId = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerAllocations", x => x.Id); + table.ForeignKey( + name: "FK_ServerAllocations_ServerNodes_ServerNodeId", + column: x => x.ServerNodeId, + principalTable: "ServerNodes", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Servers", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ServiceId = table.Column(type: "INTEGER", nullable: false), + Cpu = table.Column(type: "INTEGER", nullable: false), + Memory = table.Column(type: "INTEGER", nullable: false), + Disk = table.Column(type: "INTEGER", nullable: false), + ImageId = table.Column(type: "INTEGER", nullable: false), + DockerImageIndex = table.Column(type: "INTEGER", nullable: false), + OverrideStartupCommand = table.Column(type: "TEXT", nullable: true), + NodeId = table.Column(type: "INTEGER", nullable: false), + MainAllocationId = table.Column(type: "INTEGER", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Servers", x => x.Id); + table.ForeignKey( + name: "FK_Servers_ServerAllocations_MainAllocationId", + column: x => x.MainAllocationId, + principalTable: "ServerAllocations", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Servers_ServerImages_ImageId", + column: x => x.ImageId, + principalTable: "ServerImages", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Servers_ServerNodes_NodeId", + column: x => x.NodeId, + principalTable: "ServerNodes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Servers_Services_ServiceId", + column: x => x.ServiceId, + principalTable: "Services", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ServerVariables", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Key = table.Column(type: "TEXT", nullable: false), + Value = table.Column(type: "TEXT", nullable: false), + ServerId = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerVariables", x => x.Id); + table.ForeignKey( + name: "FK_ServerVariables_Servers_ServerId", + column: x => x.ServerId, + principalTable: "Servers", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_ServerAllocations_ServerId", + table: "ServerAllocations", + column: "ServerId"); + + migrationBuilder.CreateIndex( + name: "IX_ServerAllocations_ServerNodeId", + table: "ServerAllocations", + column: "ServerNodeId"); + + migrationBuilder.CreateIndex( + name: "IX_ServerDockerImages_ServerImageId", + table: "ServerDockerImages", + column: "ServerImageId"); + + migrationBuilder.CreateIndex( + name: "IX_Servers_ImageId", + table: "Servers", + column: "ImageId"); + + migrationBuilder.CreateIndex( + name: "IX_Servers_MainAllocationId", + table: "Servers", + column: "MainAllocationId"); + + migrationBuilder.CreateIndex( + name: "IX_Servers_NodeId", + table: "Servers", + column: "NodeId"); + + migrationBuilder.CreateIndex( + name: "IX_Servers_ServiceId", + table: "Servers", + column: "ServiceId"); + + migrationBuilder.CreateIndex( + name: "IX_ServerVariables_ServerId", + table: "ServerVariables", + column: "ServerId"); + + migrationBuilder.AddForeignKey( + name: "FK_ServerAllocations_Servers_ServerId", + table: "ServerAllocations", + column: "ServerId", + principalTable: "Servers", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ServerAllocations_ServerNodes_ServerNodeId", + table: "ServerAllocations"); + + migrationBuilder.DropForeignKey( + name: "FK_Servers_ServerNodes_NodeId", + table: "Servers"); + + migrationBuilder.DropForeignKey( + name: "FK_ServerAllocations_Servers_ServerId", + table: "ServerAllocations"); + + migrationBuilder.DropTable( + name: "ServerDockerImages"); + + migrationBuilder.DropTable( + name: "ServerImageVariables"); + + migrationBuilder.DropTable( + name: "ServerVariables"); + + migrationBuilder.DropTable( + name: "ServerNodes"); + + migrationBuilder.DropTable( + name: "Servers"); + + migrationBuilder.DropTable( + name: "ServerAllocations"); + + migrationBuilder.DropTable( + name: "ServerImages"); + } + } +} diff --git a/Moonlight/Core/Database/Migrations/20240127164420_FixedMissingPropertyInServerImage.Designer.cs b/Moonlight/Core/Database/Migrations/20240127164420_FixedMissingPropertyInServerImage.Designer.cs new file mode 100644 index 0000000..5be6d5e --- /dev/null +++ b/Moonlight/Core/Database/Migrations/20240127164420_FixedMissingPropertyInServerImage.Designer.cs @@ -0,0 +1,1040 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Moonlight.Core.Database; + +#nullable disable + +namespace Moonlight.Core.Database.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20240127164420_FixedMissingPropertyInServerImage")] + partial class FixedMissingPropertyInServerImage + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); + + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Avatar") + .HasColumnType("TEXT"); + + b.Property("Balance") + .HasColumnType("REAL"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Flags") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Permissions") + .HasColumnType("INTEGER"); + + b.Property("TokenValidTimestamp") + .HasColumnType("TEXT"); + + b.Property("TotpKey") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("PostId"); + + b.ToTable("PostComments"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostLikes"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.WordFilter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Filter") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("WordFilters"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Cpu") + .HasColumnType("INTEGER"); + + b.Property("Disk") + .HasColumnType("INTEGER"); + + b.Property("DockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MainAllocationId") + .HasColumnType("INTEGER"); + + b.Property("Memory") + .HasColumnType("INTEGER"); + + b.Property("NodeId") + .HasColumnType("INTEGER"); + + b.Property("OverrideStartupCommand") + .HasColumnType("TEXT"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("MainAllocationId"); + + b.HasIndex("NodeId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Servers"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("ServerNodeId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("ServerNodeId"); + + b.ToTable("ServerAllocations"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AutoPull") + .HasColumnType("INTEGER"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerDockerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllocationsNeeded") + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DefaultDockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("InstallDockerImage") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallScript") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallShell") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OnlineDetection") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParseConfigurations") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StartupCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StopCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdateUrl") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ServerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowUserToEdit") + .HasColumnType("INTEGER"); + + b.Property("AllowUserToView") + .HasColumnType("INTEGER"); + + b.Property("DefaultValue") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerImageVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Fqdn") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FtpPort") + .HasColumnType("INTEGER"); + + b.Property("HttpPort") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Token") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UseSsl") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ServerNodes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConfigJsonOverride") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Nickname") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("INTEGER"); + + b.Property("ProductId") + .HasColumnType("INTEGER"); + + b.Property("RenewAt") + .HasColumnType("TEXT"); + + b.Property("Suspended") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.HasIndex("ProductId"); + + b.ToTable("Services"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServiceId"); + + b.HasIndex("UserId"); + + b.ToTable("ServiceShares"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Coupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Percent") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Coupons"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CouponId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CouponId"); + + b.HasIndex("UserId"); + + b.ToTable("CouponUses"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("REAL"); + + b.HasKey("Id"); + + b.ToTable("GiftCodes"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GiftCodeId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GiftCodeId"); + + b.HasIndex("UserId"); + + b.ToTable("GiftCodeUses"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.Property("ConfigJson") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Duration") + .HasColumnType("INTEGER"); + + b.Property("MaxPerUser") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Stock") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.Property("Text") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Transaction"); + }); + + modelBuilder.Entity("Moonlight.Features.Theming.Entities.Theme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CssUrl") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("JsUrl") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Themes"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatorId") + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Open") + .HasColumnType("INTEGER"); + + b.Property("Priority") + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("Tries") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Tickets"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attachment") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsSupport") + .HasColumnType("INTEGER"); + + b.Property("SenderId") + .HasColumnType("INTEGER"); + + b.Property("TicketId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("SenderId"); + + b.HasIndex("TicketId"); + + b.ToTable("TicketMessages"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Community.Entities.Post", null) + .WithMany("Comments") + .HasForeignKey("PostId"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => + { + b.HasOne("Moonlight.Features.Community.Entities.Post", null) + .WithMany("Likes") + .HasForeignKey("PostId"); + + b.HasOne("Moonlight.Core.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerAllocation", "MainAllocation") + .WithMany() + .HasForeignKey("MainAllocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", "Node") + .WithMany() + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + + b.Navigation("MainAllocation"); + + b.Navigation("Node"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Allocations") + .HasForeignKey("ServerId"); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", null) + .WithMany("Allocations") + .HasForeignKey("ServerNodeId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("DockerImages") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("Variables") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Variables") + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.StoreSystem.Entities.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Owner"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", null) + .WithMany("Shares") + .HasForeignKey("ServiceId"); + + b.HasOne("Moonlight.Core.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Coupon", "Coupon") + .WithMany() + .HasForeignKey("CouponId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("CouponUses") + .HasForeignKey("UserId"); + + b.Navigation("Coupon"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.GiftCode", "GiftCode") + .WithMany() + .HasForeignKey("GiftCodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("GiftCodeUses") + .HasForeignKey("UserId"); + + b.Navigation("GiftCode"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("Transactions") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId"); + + b.Navigation("Creator"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Sender") + .WithMany() + .HasForeignKey("SenderId"); + + b.HasOne("Moonlight.Features.Ticketing.Entities.Ticket", null) + .WithMany("Messages") + .HasForeignKey("TicketId"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Navigation("CouponUses"); + + b.Navigation("GiftCodeUses"); + + b.Navigation("Transactions"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Navigation("Comments"); + + b.Navigation("Likes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Navigation("Allocations"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Navigation("DockerImages"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Navigation("Allocations"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Navigation("Shares"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Navigation("Messages"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Moonlight/Core/Database/Migrations/20240127164420_FixedMissingPropertyInServerImage.cs b/Moonlight/Core/Database/Migrations/20240127164420_FixedMissingPropertyInServerImage.cs new file mode 100644 index 0000000..f656bc9 --- /dev/null +++ b/Moonlight/Core/Database/Migrations/20240127164420_FixedMissingPropertyInServerImage.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Moonlight.Core.Database.Migrations +{ + /// + public partial class FixedMissingPropertyInServerImage : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ServerImageId", + table: "ServerImageVariables", + type: "INTEGER", + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_ServerImageVariables_ServerImageId", + table: "ServerImageVariables", + column: "ServerImageId"); + + migrationBuilder.AddForeignKey( + name: "FK_ServerImageVariables_ServerImages_ServerImageId", + table: "ServerImageVariables", + column: "ServerImageId", + principalTable: "ServerImages", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_ServerImageVariables_ServerImages_ServerImageId", + table: "ServerImageVariables"); + + migrationBuilder.DropIndex( + name: "IX_ServerImageVariables_ServerImageId", + table: "ServerImageVariables"); + + migrationBuilder.DropColumn( + name: "ServerImageId", + table: "ServerImageVariables"); + } + } +} diff --git a/Moonlight/Core/Database/Migrations/20240129160704_AddedAllowUserToChangeDockerImage.Designer.cs b/Moonlight/Core/Database/Migrations/20240129160704_AddedAllowUserToChangeDockerImage.Designer.cs new file mode 100644 index 0000000..d5d662a --- /dev/null +++ b/Moonlight/Core/Database/Migrations/20240129160704_AddedAllowUserToChangeDockerImage.Designer.cs @@ -0,0 +1,1043 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Moonlight.Core.Database; + +#nullable disable + +namespace Moonlight.Core.Database.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20240129160704_AddedAllowUserToChangeDockerImage")] + partial class AddedAllowUserToChangeDockerImage + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); + + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Avatar") + .HasColumnType("TEXT"); + + b.Property("Balance") + .HasColumnType("REAL"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Flags") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Permissions") + .HasColumnType("INTEGER"); + + b.Property("TokenValidTimestamp") + .HasColumnType("TEXT"); + + b.Property("TotpKey") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("PostId"); + + b.ToTable("PostComments"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostLikes"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.WordFilter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Filter") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("WordFilters"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Cpu") + .HasColumnType("INTEGER"); + + b.Property("Disk") + .HasColumnType("INTEGER"); + + b.Property("DockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MainAllocationId") + .HasColumnType("INTEGER"); + + b.Property("Memory") + .HasColumnType("INTEGER"); + + b.Property("NodeId") + .HasColumnType("INTEGER"); + + b.Property("OverrideStartupCommand") + .HasColumnType("TEXT"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("MainAllocationId"); + + b.HasIndex("NodeId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Servers"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("ServerNodeId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("ServerNodeId"); + + b.ToTable("ServerAllocations"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AutoPull") + .HasColumnType("INTEGER"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerDockerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllocationsNeeded") + .HasColumnType("INTEGER"); + + b.Property("AllowUserToChangeDockerImage") + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DefaultDockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("InstallDockerImage") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallScript") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallShell") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OnlineDetection") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParseConfigurations") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StartupCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StopCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdateUrl") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ServerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowUserToEdit") + .HasColumnType("INTEGER"); + + b.Property("AllowUserToView") + .HasColumnType("INTEGER"); + + b.Property("DefaultValue") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerImageVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Fqdn") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FtpPort") + .HasColumnType("INTEGER"); + + b.Property("HttpPort") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Token") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UseSsl") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ServerNodes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConfigJsonOverride") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Nickname") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("INTEGER"); + + b.Property("ProductId") + .HasColumnType("INTEGER"); + + b.Property("RenewAt") + .HasColumnType("TEXT"); + + b.Property("Suspended") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.HasIndex("ProductId"); + + b.ToTable("Services"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServiceId"); + + b.HasIndex("UserId"); + + b.ToTable("ServiceShares"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Coupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Percent") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Coupons"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CouponId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CouponId"); + + b.HasIndex("UserId"); + + b.ToTable("CouponUses"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("REAL"); + + b.HasKey("Id"); + + b.ToTable("GiftCodes"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GiftCodeId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GiftCodeId"); + + b.HasIndex("UserId"); + + b.ToTable("GiftCodeUses"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.Property("ConfigJson") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Duration") + .HasColumnType("INTEGER"); + + b.Property("MaxPerUser") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Stock") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.Property("Text") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Transaction"); + }); + + modelBuilder.Entity("Moonlight.Features.Theming.Entities.Theme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CssUrl") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("JsUrl") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Themes"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatorId") + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Open") + .HasColumnType("INTEGER"); + + b.Property("Priority") + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("Tries") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Tickets"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attachment") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsSupport") + .HasColumnType("INTEGER"); + + b.Property("SenderId") + .HasColumnType("INTEGER"); + + b.Property("TicketId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("SenderId"); + + b.HasIndex("TicketId"); + + b.ToTable("TicketMessages"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Community.Entities.Post", null) + .WithMany("Comments") + .HasForeignKey("PostId"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => + { + b.HasOne("Moonlight.Features.Community.Entities.Post", null) + .WithMany("Likes") + .HasForeignKey("PostId"); + + b.HasOne("Moonlight.Core.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerAllocation", "MainAllocation") + .WithMany() + .HasForeignKey("MainAllocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", "Node") + .WithMany() + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + + b.Navigation("MainAllocation"); + + b.Navigation("Node"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Allocations") + .HasForeignKey("ServerId"); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", null) + .WithMany("Allocations") + .HasForeignKey("ServerNodeId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("DockerImages") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("Variables") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Variables") + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.StoreSystem.Entities.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Owner"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", null) + .WithMany("Shares") + .HasForeignKey("ServiceId"); + + b.HasOne("Moonlight.Core.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Coupon", "Coupon") + .WithMany() + .HasForeignKey("CouponId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("CouponUses") + .HasForeignKey("UserId"); + + b.Navigation("Coupon"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.GiftCode", "GiftCode") + .WithMany() + .HasForeignKey("GiftCodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("GiftCodeUses") + .HasForeignKey("UserId"); + + b.Navigation("GiftCode"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("Transactions") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId"); + + b.Navigation("Creator"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Sender") + .WithMany() + .HasForeignKey("SenderId"); + + b.HasOne("Moonlight.Features.Ticketing.Entities.Ticket", null) + .WithMany("Messages") + .HasForeignKey("TicketId"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Navigation("CouponUses"); + + b.Navigation("GiftCodeUses"); + + b.Navigation("Transactions"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Navigation("Comments"); + + b.Navigation("Likes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Navigation("Allocations"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Navigation("DockerImages"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Navigation("Allocations"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Navigation("Shares"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Navigation("Messages"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Moonlight/Core/Database/Migrations/20240129160704_AddedAllowUserToChangeDockerImage.cs b/Moonlight/Core/Database/Migrations/20240129160704_AddedAllowUserToChangeDockerImage.cs new file mode 100644 index 0000000..c0e49c8 --- /dev/null +++ b/Moonlight/Core/Database/Migrations/20240129160704_AddedAllowUserToChangeDockerImage.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Moonlight.Core.Database.Migrations +{ + /// + public partial class AddedAllowUserToChangeDockerImage : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "AllowUserToChangeDockerImage", + table: "ServerImages", + type: "INTEGER", + nullable: false, + defaultValue: false); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "AllowUserToChangeDockerImage", + table: "ServerImages"); + } + } +} diff --git a/Moonlight/Core/Database/Migrations/20240214091019_AddedServerSchedules.Designer.cs b/Moonlight/Core/Database/Migrations/20240214091019_AddedServerSchedules.Designer.cs new file mode 100644 index 0000000..632b3cf --- /dev/null +++ b/Moonlight/Core/Database/Migrations/20240214091019_AddedServerSchedules.Designer.cs @@ -0,0 +1,1089 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Moonlight.Core.Database; + +#nullable disable + +namespace Moonlight.Core.Database.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20240214091019_AddedServerSchedules")] + partial class AddedServerSchedules + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); + + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Avatar") + .HasColumnType("TEXT"); + + b.Property("Balance") + .HasColumnType("REAL"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Flags") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Permissions") + .HasColumnType("INTEGER"); + + b.Property("TokenValidTimestamp") + .HasColumnType("TEXT"); + + b.Property("TotpKey") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Title") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.ToTable("Posts"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuthorId") + .HasColumnType("INTEGER"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("UpdatedAt") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("AuthorId"); + + b.HasIndex("PostId"); + + b.ToTable("PostComments"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("PostId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PostId"); + + b.HasIndex("UserId"); + + b.ToTable("PostLikes"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.WordFilter", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Filter") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("WordFilters"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Cpu") + .HasColumnType("INTEGER"); + + b.Property("Disk") + .HasColumnType("INTEGER"); + + b.Property("DockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MainAllocationId") + .HasColumnType("INTEGER"); + + b.Property("Memory") + .HasColumnType("INTEGER"); + + b.Property("NodeId") + .HasColumnType("INTEGER"); + + b.Property("OverrideStartupCommand") + .HasColumnType("TEXT"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("MainAllocationId"); + + b.HasIndex("NodeId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Servers"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("ServerNodeId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("ServerNodeId"); + + b.ToTable("ServerAllocations"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AutoPull") + .HasColumnType("INTEGER"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerDockerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllocationsNeeded") + .HasColumnType("INTEGER"); + + b.Property("AllowUserToChangeDockerImage") + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DefaultDockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("InstallDockerImage") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallScript") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallShell") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OnlineDetection") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParseConfigurations") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StartupCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StopCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdateUrl") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ServerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowUserToEdit") + .HasColumnType("INTEGER"); + + b.Property("AllowUserToView") + .HasColumnType("INTEGER"); + + b.Property("DefaultValue") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerImageVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Fqdn") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FtpPort") + .HasColumnType("INTEGER"); + + b.Property("HttpPort") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Token") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UseSsl") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ServerNodes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActionData") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ActionType") + .HasColumnType("INTEGER"); + + b.Property("Cron") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastRunAt") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("WasLastRunAutomatic") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerSchedules"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConfigJsonOverride") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Nickname") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("INTEGER"); + + b.Property("ProductId") + .HasColumnType("INTEGER"); + + b.Property("RenewAt") + .HasColumnType("TEXT"); + + b.Property("Suspended") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.HasIndex("ProductId"); + + b.ToTable("Services"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServiceId"); + + b.HasIndex("UserId"); + + b.ToTable("ServiceShares"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Category", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Categories"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Coupon", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Percent") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("Coupons"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CouponId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CouponId"); + + b.HasIndex("UserId"); + + b.ToTable("CouponUses"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Amount") + .HasColumnType("INTEGER"); + + b.Property("Code") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("REAL"); + + b.HasKey("Id"); + + b.ToTable("GiftCodes"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("GiftCodeId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("GiftCodeId"); + + b.HasIndex("UserId"); + + b.ToTable("GiftCodeUses"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CategoryId") + .HasColumnType("INTEGER"); + + b.Property("ConfigJson") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Duration") + .HasColumnType("INTEGER"); + + b.Property("MaxPerUser") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.Property("Slug") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Stock") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CategoryId"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Price") + .HasColumnType("REAL"); + + b.Property("Text") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Transaction"); + }); + + modelBuilder.Entity("Moonlight.Features.Theming.Entities.Theme", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CssUrl") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("JsUrl") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Themes"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("CreatorId") + .HasColumnType("INTEGER"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Open") + .HasColumnType("INTEGER"); + + b.Property("Priority") + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("Tries") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Tickets"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Attachment") + .HasColumnType("TEXT"); + + b.Property("Content") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("IsSupport") + .HasColumnType("INTEGER"); + + b.Property("SenderId") + .HasColumnType("INTEGER"); + + b.Property("TicketId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("SenderId"); + + b.HasIndex("TicketId"); + + b.ToTable("TicketMessages"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Author") + .WithMany() + .HasForeignKey("AuthorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Community.Entities.Post", null) + .WithMany("Comments") + .HasForeignKey("PostId"); + + b.Navigation("Author"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => + { + b.HasOne("Moonlight.Features.Community.Entities.Post", null) + .WithMany("Likes") + .HasForeignKey("PostId"); + + b.HasOne("Moonlight.Core.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerAllocation", "MainAllocation") + .WithMany() + .HasForeignKey("MainAllocationId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", "Node") + .WithMany() + .HasForeignKey("NodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + + b.Navigation("MainAllocation"); + + b.Navigation("Node"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Allocations") + .HasForeignKey("ServerId"); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", null) + .WithMany("Allocations") + .HasForeignKey("ServerNodeId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("DockerImages") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("Variables") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerSchedule", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Schedules") + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Variables") + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") + .WithMany() + .HasForeignKey("OwnerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.StoreSystem.Entities.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Owner"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", null) + .WithMany("Shares") + .HasForeignKey("ServiceId"); + + b.HasOne("Moonlight.Core.Database.Entities.User", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Coupon", "Coupon") + .WithMany() + .HasForeignKey("CouponId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("CouponUses") + .HasForeignKey("UserId"); + + b.Navigation("Coupon"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.GiftCode", "GiftCode") + .WithMany() + .HasForeignKey("GiftCodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("GiftCodeUses") + .HasForeignKey("UserId"); + + b.Navigation("GiftCode"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("Transactions") + .HasForeignKey("UserId"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Creator") + .WithMany() + .HasForeignKey("CreatorId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId"); + + b.Navigation("Creator"); + + b.Navigation("Service"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => + { + b.HasOne("Moonlight.Core.Database.Entities.User", "Sender") + .WithMany() + .HasForeignKey("SenderId"); + + b.HasOne("Moonlight.Features.Ticketing.Entities.Ticket", null) + .WithMany("Messages") + .HasForeignKey("TicketId"); + + b.Navigation("Sender"); + }); + + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Navigation("CouponUses"); + + b.Navigation("GiftCodeUses"); + + b.Navigation("Transactions"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Navigation("Comments"); + + b.Navigation("Likes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Navigation("Allocations"); + + b.Navigation("Schedules"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Navigation("DockerImages"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Navigation("Allocations"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Navigation("Shares"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Navigation("Messages"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Moonlight/Core/Database/Migrations/20240214091019_AddedServerSchedules.cs b/Moonlight/Core/Database/Migrations/20240214091019_AddedServerSchedules.cs new file mode 100644 index 0000000..3c39ea0 --- /dev/null +++ b/Moonlight/Core/Database/Migrations/20240214091019_AddedServerSchedules.cs @@ -0,0 +1,51 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Moonlight.Core.Database.Migrations +{ + /// + public partial class AddedServerSchedules : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ServerSchedules", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(type: "TEXT", nullable: false), + Cron = table.Column(type: "TEXT", nullable: false), + ActionType = table.Column(type: "INTEGER", nullable: false), + ActionData = table.Column(type: "TEXT", nullable: false), + LastRunAt = table.Column(type: "TEXT", nullable: false), + WasLastRunAutomatic = table.Column(type: "INTEGER", nullable: false), + ServerId = table.Column(type: "INTEGER", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_ServerSchedules", x => x.Id); + table.ForeignKey( + name: "FK_ServerSchedules_Servers_ServerId", + column: x => x.ServerId, + principalTable: "Servers", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_ServerSchedules_ServerId", + table: "ServerSchedules", + column: "ServerId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ServerSchedules"); + } + } +} diff --git a/Moonlight/Core/Database/Migrations/DataContextModelSnapshot.cs b/Moonlight/Core/Database/Migrations/DataContextModelSnapshot.cs index 0e1f2dc..df1c5be 100644 --- a/Moonlight/Core/Database/Migrations/DataContextModelSnapshot.cs +++ b/Moonlight/Core/Database/Migrations/DataContextModelSnapshot.cs @@ -4,7 +4,6 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Moonlight.Core.Database; -using Moonlight.Core.Database; #nullable disable @@ -18,7 +17,52 @@ namespace Moonlight.Core.Database.Migrations #pragma warning disable 612, 618 modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.Post", b => + modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Avatar") + .HasColumnType("TEXT"); + + b.Property("Balance") + .HasColumnType("REAL"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Email") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Flags") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Password") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Permissions") + .HasColumnType("INTEGER"); + + b.Property("TokenValidTimestamp") + .HasColumnType("TEXT"); + + b.Property("TotpKey") + .HasColumnType("TEXT"); + + b.Property("Username") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -51,7 +95,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("Posts"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b => + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -82,7 +126,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("PostComments"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostLike", b => + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -106,7 +150,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("PostLikes"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.WordFilter", b => + modelBuilder.Entity("Moonlight.Features.Community.Entities.WordFilter", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -121,7 +165,358 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("WordFilters"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Category", b => + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Cpu") + .HasColumnType("INTEGER"); + + b.Property("Disk") + .HasColumnType("INTEGER"); + + b.Property("DockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("ImageId") + .HasColumnType("INTEGER"); + + b.Property("MainAllocationId") + .HasColumnType("INTEGER"); + + b.Property("Memory") + .HasColumnType("INTEGER"); + + b.Property("NodeId") + .HasColumnType("INTEGER"); + + b.Property("OverrideStartupCommand") + .HasColumnType("TEXT"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("MainAllocationId"); + + b.HasIndex("NodeId"); + + b.HasIndex("ServiceId"); + + b.ToTable("Servers"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IpAddress") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Port") + .HasColumnType("INTEGER"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("ServerNodeId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.HasIndex("ServerNodeId"); + + b.ToTable("ServerAllocations"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AutoPull") + .HasColumnType("INTEGER"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerDockerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllocationsNeeded") + .HasColumnType("INTEGER"); + + b.Property("AllowUserToChangeDockerImage") + .HasColumnType("INTEGER"); + + b.Property("Author") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DefaultDockerImageIndex") + .HasColumnType("INTEGER"); + + b.Property("DonateUrl") + .HasColumnType("TEXT"); + + b.Property("InstallDockerImage") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallScript") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("InstallShell") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("OnlineDetection") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ParseConfigurations") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StartupCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("StopCommand") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UpdateUrl") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("ServerImages"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AllowUserToEdit") + .HasColumnType("INTEGER"); + + b.Property("AllowUserToView") + .HasColumnType("INTEGER"); + + b.Property("DefaultValue") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Description") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerImageId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerImageId"); + + b.ToTable("ServerImageVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Fqdn") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("FtpPort") + .HasColumnType("INTEGER"); + + b.Property("HttpPort") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Token") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("UseSsl") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("ServerNodes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerSchedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActionData") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ActionType") + .HasColumnType("INTEGER"); + + b.Property("Cron") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("LastRunAt") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("WasLastRunAutomatic") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerSchedules"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ServerId") + .HasColumnType("INTEGER"); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ServerId"); + + b.ToTable("ServerVariables"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ConfigJsonOverride") + .HasColumnType("TEXT"); + + b.Property("CreatedAt") + .HasColumnType("TEXT"); + + b.Property("Nickname") + .HasColumnType("TEXT"); + + b.Property("OwnerId") + .HasColumnType("INTEGER"); + + b.Property("ProductId") + .HasColumnType("INTEGER"); + + b.Property("RenewAt") + .HasColumnType("TEXT"); + + b.Property("Suspended") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("OwnerId"); + + b.HasIndex("ProductId"); + + b.ToTable("Services"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ServiceId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ServiceId"); + + b.HasIndex("UserId"); + + b.ToTable("ServiceShares"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Category", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -144,7 +539,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("Categories"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b => + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Coupon", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -165,7 +560,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("Coupons"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b => + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -186,7 +581,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("CouponUses"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCode", b => + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCode", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -207,7 +602,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("GiftCodes"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b => + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -228,7 +623,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("GiftCodeUses"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Product", b => + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -278,64 +673,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("Products"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ConfigJsonOverride") - .HasColumnType("TEXT"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("Nickname") - .HasColumnType("TEXT"); - - b.Property("OwnerId") - .HasColumnType("INTEGER"); - - b.Property("ProductId") - .HasColumnType("INTEGER"); - - b.Property("RenewAt") - .HasColumnType("TEXT"); - - b.Property("Suspended") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("OwnerId"); - - b.HasIndex("ProductId"); - - b.ToTable("Services"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("ServiceId") - .HasColumnType("INTEGER"); - - b.Property("UserId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("ServiceId"); - - b.HasIndex("UserId"); - - b.ToTable("ServiceShares"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Transaction", b => + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -361,7 +699,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("Transaction"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Theme", b => + modelBuilder.Entity("Moonlight.Features.Theming.Entities.Theme", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -393,7 +731,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("Themes"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b => + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -435,7 +773,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("Tickets"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.TicketMessage", b => + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => { b.Property("Id") .ValueGeneratedOnAdd() @@ -469,52 +807,7 @@ namespace Moonlight.Core.Database.Migrations b.ToTable("TicketMessages"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Avatar") - .HasColumnType("TEXT"); - - b.Property("Balance") - .HasColumnType("REAL"); - - b.Property("CreatedAt") - .HasColumnType("TEXT"); - - b.Property("Email") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Flags") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Password") - .IsRequired() - .HasColumnType("TEXT"); - - b.Property("Permissions") - .HasColumnType("INTEGER"); - - b.Property("TokenValidTimestamp") - .HasColumnType("TEXT"); - - b.Property("TotpKey") - .HasColumnType("TEXT"); - - b.Property("Username") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("Users"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.Post", b => + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => { b.HasOne("Moonlight.Core.Database.Entities.User", "Author") .WithMany() @@ -525,7 +818,7 @@ namespace Moonlight.Core.Database.Migrations b.Navigation("Author"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b => + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostComment", b => { b.HasOne("Moonlight.Core.Database.Entities.User", "Author") .WithMany() @@ -533,16 +826,16 @@ namespace Moonlight.Core.Database.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Moonlight.Core.Database.Entities.Community.Post", null) + b.HasOne("Moonlight.Features.Community.Entities.Post", null) .WithMany("Comments") .HasForeignKey("PostId"); b.Navigation("Author"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostLike", b => + modelBuilder.Entity("Moonlight.Features.Community.Entities.PostLike", b => { - b.HasOne("Moonlight.Core.Database.Entities.Community.Post", null) + b.HasOne("Moonlight.Features.Community.Entities.Post", null) .WithMany("Likes") .HasForeignKey("PostId"); @@ -555,48 +848,81 @@ namespace Moonlight.Core.Database.Migrations b.Navigation("User"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b => + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => { - b.HasOne("Moonlight.Core.Database.Entities.Store.Coupon", "Coupon") + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", "Image") .WithMany() - .HasForeignKey("CouponId") + .HasForeignKey("ImageId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Moonlight.Core.Database.Entities.User", null) - .WithMany("CouponUses") - .HasForeignKey("UserId"); - - b.Navigation("Coupon"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.GiftCode", "GiftCode") + b.HasOne("Moonlight.Features.Servers.Entities.ServerAllocation", "MainAllocation") .WithMany() - .HasForeignKey("GiftCodeId") + .HasForeignKey("MainAllocationId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Moonlight.Core.Database.Entities.User", null) - .WithMany("GiftCodeUses") - .HasForeignKey("UserId"); - - b.Navigation("GiftCode"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", "Node") .WithMany() - .HasForeignKey("CategoryId") + .HasForeignKey("NodeId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.Navigation("Category"); + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") + .WithMany() + .HasForeignKey("ServiceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + + b.Navigation("MainAllocation"); + + b.Navigation("Node"); + + b.Navigation("Service"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerAllocation", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Allocations") + .HasForeignKey("ServerId"); + + b.HasOne("Moonlight.Features.Servers.Entities.ServerNode", null) + .WithMany("Allocations") + .HasForeignKey("ServerNodeId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerDockerImage", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("DockerImages") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImageVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.ServerImage", null) + .WithMany("Variables") + .HasForeignKey("ServerImageId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerSchedule", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Schedules") + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerVariable", b => + { + b.HasOne("Moonlight.Features.Servers.Entities.Server", null) + .WithMany("Variables") + .HasForeignKey("ServerId"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => { b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") .WithMany() @@ -604,7 +930,7 @@ namespace Moonlight.Core.Database.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") + b.HasOne("Moonlight.Features.StoreSystem.Entities.Product", "Product") .WithMany() .HasForeignKey("ProductId") .OnDelete(DeleteBehavior.Cascade) @@ -615,9 +941,9 @@ namespace Moonlight.Core.Database.Migrations b.Navigation("Product"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.ServiceShare", b => { - b.HasOne("Moonlight.Core.Database.Entities.Store.Service", null) + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", null) .WithMany("Shares") .HasForeignKey("ServiceId"); @@ -630,14 +956,55 @@ namespace Moonlight.Core.Database.Migrations b.Navigation("User"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Transaction", b => + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.CouponUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Coupon", "Coupon") + .WithMany() + .HasForeignKey("CouponId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("CouponUses") + .HasForeignKey("UserId"); + + b.Navigation("Coupon"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.GiftCodeUse", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.GiftCode", "GiftCode") + .WithMany() + .HasForeignKey("GiftCodeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Moonlight.Core.Database.Entities.User", null) + .WithMany("GiftCodeUses") + .HasForeignKey("UserId"); + + b.Navigation("GiftCode"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Product", b => + { + b.HasOne("Moonlight.Features.StoreSystem.Entities.Category", "Category") + .WithMany() + .HasForeignKey("CategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Category"); + }); + + modelBuilder.Entity("Moonlight.Features.StoreSystem.Entities.Transaction", b => { b.HasOne("Moonlight.Core.Database.Entities.User", null) .WithMany("Transactions") .HasForeignKey("UserId"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b => + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => { b.HasOne("Moonlight.Core.Database.Entities.User", "Creator") .WithMany() @@ -645,7 +1012,7 @@ namespace Moonlight.Core.Database.Migrations .OnDelete(DeleteBehavior.Cascade) .IsRequired(); - b.HasOne("Moonlight.Core.Database.Entities.Store.Service", "Service") + b.HasOne("Moonlight.Features.ServiceManagement.Entities.Service", "Service") .WithMany() .HasForeignKey("ServiceId"); @@ -654,36 +1021,19 @@ namespace Moonlight.Core.Database.Migrations b.Navigation("Service"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.TicketMessage", b => + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.TicketMessage", b => { b.HasOne("Moonlight.Core.Database.Entities.User", "Sender") .WithMany() .HasForeignKey("SenderId"); - b.HasOne("Moonlight.Core.Database.Entities.Tickets.Ticket", null) + b.HasOne("Moonlight.Features.Ticketing.Entities.Ticket", null) .WithMany("Messages") .HasForeignKey("TicketId"); b.Navigation("Sender"); }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.Post", b => - { - b.Navigation("Comments"); - - b.Navigation("Likes"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.Navigation("Shares"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b => - { - b.Navigation("Messages"); - }); - modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => { b.Navigation("CouponUses"); @@ -692,6 +1042,44 @@ namespace Moonlight.Core.Database.Migrations b.Navigation("Transactions"); }); + + modelBuilder.Entity("Moonlight.Features.Community.Entities.Post", b => + { + b.Navigation("Comments"); + + b.Navigation("Likes"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.Server", b => + { + b.Navigation("Allocations"); + + b.Navigation("Schedules"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerImage", b => + { + b.Navigation("DockerImages"); + + b.Navigation("Variables"); + }); + + modelBuilder.Entity("Moonlight.Features.Servers.Entities.ServerNode", b => + { + b.Navigation("Allocations"); + }); + + modelBuilder.Entity("Moonlight.Features.ServiceManagement.Entities.Service", b => + { + b.Navigation("Shares"); + }); + + modelBuilder.Entity("Moonlight.Features.Ticketing.Entities.Ticket", b => + { + b.Navigation("Messages"); + }); #pragma warning restore 612, 618 } } diff --git a/Moonlight/Core/Exceptions/DisplayException.cs b/Moonlight/Core/Exceptions/DisplayException.cs deleted file mode 100644 index cc8c04a..0000000 --- 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 4caf59a..0000000 --- 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/ConfigServiceExtensions.cs b/Moonlight/Core/Extensions/ConfigServiceExtensions.cs new file mode 100644 index 0000000..481096f --- /dev/null +++ b/Moonlight/Core/Extensions/ConfigServiceExtensions.cs @@ -0,0 +1,22 @@ +using MoonCore.Services; +using Moonlight.Core.Configuration; +using Newtonsoft.Json; + +namespace Moonlight.Core.Extensions; + +public static class ConfigServiceExtensions +{ + public static string GetDiagnosticJson(this ConfigService configService) + { + var jsonUnsafe = JsonConvert.SerializeObject(configService.Get()); + var configUnsafe = JsonConvert.DeserializeObject(jsonUnsafe)!; + + // Remote sensitive data + configUnsafe.Database.Password = + string.IsNullOrEmpty(configUnsafe.Database.Password) ? "IS EMPTY" : "IS NOT EMPTY"; + configUnsafe.Security.Token = string.IsNullOrEmpty(configUnsafe.Security.Token) ? "IS EMPTY" : "IS NOT EMPTY"; + configUnsafe.MailServer.Password =string.IsNullOrEmpty(configUnsafe.MailServer.Password) ? "IS EMPTY" : "IS NOT EMPTY"; + + return JsonConvert.SerializeObject(configUnsafe, Formatting.Indented); + } +} \ 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 89c69a6..0000000 --- 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 a8296d9..0000000 --- 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 ce8c343..0000000 --- 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 9e5b46c..0000000 --- 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/LogMigrator/LogMigrateProvider.cs b/Moonlight/Core/Helpers/LogMigrator/LogMigrateProvider.cs deleted file mode 100644 index 9d7d4de..0000000 --- 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 a0de98e..0000000 --- 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 068ed3c..0000000 --- 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 5388208..0000000 --- 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 39b0c6d..0000000 --- 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/Http/Controllers/Api/AssetProxyController.cs b/Moonlight/Core/Http/Controllers/Api/AssetProxyController.cs index e38b5a4..401d72e 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 4905a55..f1a4f51 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 518fb72..f03a4b3 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 5525d4e..bc7dfe6 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/Models/Enums/Permission.cs b/Moonlight/Core/Models/Enums/Permission.cs index 11a0c4f..3ab182c 100644 --- a/Moonlight/Core/Models/Enums/Permission.cs +++ b/Moonlight/Core/Models/Enums/Permission.cs @@ -11,6 +11,7 @@ public enum Permission AdminTickets = 1004, AdminCommunity = 1030, AdminServices = 1050, + AdminServers = 1060, AdminStore = 1900, AdminViewExceptions = 1999, AdminRoot = 2000 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 874ea06..ed97af2 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 3cbff63..b4e945b 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 260d7e8..37bf0a0 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 c8d0f67..0000000 --- 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/HotKeyService.cs b/Moonlight/Core/Services/HotKeyService.cs new file mode 100644 index 0000000..ec9541d --- /dev/null +++ b/Moonlight/Core/Services/HotKeyService.cs @@ -0,0 +1,39 @@ +using Microsoft.JSInterop; +using MoonCore.Attributes; +using MoonCore.Helpers; + +namespace Moonlight.Core.Services; + +[Scoped] +public class HotKeyService : IAsyncDisposable +{ + private readonly IJSRuntime JsRuntime; + + public SmartEventHandler HotKeyPressed { get; set; } = new(); + + public HotKeyService(IJSRuntime jsRuntime) + { + JsRuntime = jsRuntime; + } + + public async Task Initialize() + { + var reference = DotNetObjectReference.Create(this); + await JsRuntime.InvokeVoidAsync("moonlight.hotkeys.registerListener", reference); + } + + [JSInvokable] + public async void OnHotkeyPressed(string hotKey) + { + await HotKeyPressed.Invoke(hotKey); + } + + public async ValueTask DisposeAsync() + { + try + { + await JsRuntime.InvokeVoidAsync("moonlight.keyListener.unregisterListener"); + } + catch (Exception) { /* ignored */} + } +} \ No newline at end of file diff --git a/Moonlight/Core/Services/IdentityService.cs b/Moonlight/Core/Services/IdentityService.cs index 7f21769..cc7ceaa 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; @@ -73,7 +75,7 @@ public class IdentityService if (string.IsNullOrEmpty(Token)) return; - if (!await JwtService.Validate(Token)) + if (!await JwtService.Validate(Token, "User")) return; var data = await JwtService.Decode(Token); @@ -150,7 +152,7 @@ public class IdentityService { data.Add("userId", user.Id.ToString()); data.Add("issuedAt", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()); - }, TimeSpan.FromDays(10)); + }, "User", TimeSpan.FromDays(10)); return token; } diff --git a/Moonlight/Core/Services/Interop/AlertService.cs b/Moonlight/Core/Services/Interop/AlertService.cs deleted file mode 100644 index c66a221..0000000 --- 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/CookieService.cs b/Moonlight/Core/Services/Interop/CookieService.cs deleted file mode 100644 index d171174..0000000 --- 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 7b9b598..0000000 --- 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 c9f8819..0000000 --- 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 3e83dac..0000000 --- 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 c025d27..0dab8c8 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; @@ -52,6 +56,9 @@ public class MailService try { + Logger.Debug($"Sending {templateName} mail to {user.Email}"); + Logger.Debug($"Body: {body.HtmlBody}"); + await smtpClient.ConnectAsync(config.Host, config.Port, config.UseSsl); await smtpClient.AuthenticateAsync(config.Email, config.Password); await smtpClient.SendAsync(message); diff --git a/Moonlight/Core/Services/MoonlightService.cs b/Moonlight/Core/Services/MoonlightService.cs index 44e6521..d064353 100644 --- a/Moonlight/Core/Services/MoonlightService.cs +++ b/Moonlight/Core/Services/MoonlightService.cs @@ -1,21 +1,28 @@ using System.IO.Compression; +using MoonCore.Abstractions; +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.Servers.Entities; using Moonlight.Features.Theming.Services; +using Newtonsoft.Json; 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; @@ -24,7 +31,7 @@ public class MoonlightService // This service can be used to perform strictly pa public async Task Restart() { Logger.Info("Restarting moonlight"); - + // Notify all users that this instance will restart await Events.OnMoonlightRestart.InvokeAsync(); await Task.Delay(TimeSpan.FromSeconds(3)); @@ -35,7 +42,7 @@ public class MoonlightService // This service can be used to perform strictly pa public async Task GenerateDiagnoseReport() { var scope = ServiceProvider.CreateScope(); - + // Prepare zip file var memoryStream = new MemoryStream(); var zip = new ZipArchive(memoryStream, ZipArchiveMode.Create, true); @@ -48,15 +55,26 @@ public class MoonlightService // This service can be used to perform strictly pa var log = await sr.ReadToEndAsync(); sr.Close(); fs.Close(); - + await zip.AddFromText("log.txt", log); - - // TODO: Add node settings here - + + // Add node config + var nodeRepo = scope.ServiceProvider.GetRequiredService>(); + var nodes = nodeRepo.Get().ToArray(); + + foreach (var node in nodes) + { + // Remove sensitive data + node.Token = string.IsNullOrEmpty(node.Token) ? "IS EMPTY" : "IS NOT EMPTY"; + } + + var nodesJson = JsonConvert.SerializeObject(nodes, Formatting.Indented); + await zip.AddFromText("nodes.json", nodesJson); + // Add config - var config = ConfigService.GetDiagnoseJson(); - await zip.AddFromText("config.json", config); - + var configJson = ConfigService.GetDiagnosticJson(); + await zip.AddFromText("config.json", configJson); + // Make a list of plugins var pluginService = scope.ServiceProvider.GetRequiredService(); var plugins = await pluginService.GetLoadedPlugins(); @@ -67,11 +85,11 @@ public class MoonlightService // This service can be used to perform strictly pa var assembly = plugin.GetType().Assembly; pluginList += $"{assembly.FullName} ({assembly.Location})\n"; } - + await zip.AddFromText("pluginList.txt", pluginList); - + // Add more information here - + // Finalize file zip.Dispose(); memoryStream.Close(); diff --git a/Moonlight/Core/Services/PluginService.cs b/Moonlight/Core/Services/PluginService.cs index 74f70a3..a4334bf 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 61c7adf..c66452d 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 78217cc..f5034e9 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; @@ -97,7 +101,10 @@ public class UserAuthService public async Task SendVerification(User user) { - var jwt = await JwtService.Create(data => { data.Add("mailToVerify", user.Email); }, TimeSpan.FromMinutes(10)); + var jwt = await JwtService.Create(data => + { + data.Add("mailToVerify", user.Email); + }, "EmailVerification", TimeSpan.FromMinutes(10)); await MailService.Send(user, "Verify your account", "verifyMail", user, new MailVerify() { @@ -114,7 +121,10 @@ public class UserAuthService if (user == null) throw new DisplayException("An account with that email was not found"); - var jwt = await JwtService.Create(data => { data.Add("accountToReset", user.Id.ToString()); }); + var jwt = await JwtService.Create(data => + { + data.Add("accountToReset", user.Id.ToString()); + }, "PasswordReset", TimeSpan.FromHours(1)); await MailService.Send(user, "Password reset for your account", "passwordReset", user, new ResetPassword() { diff --git a/Moonlight/Core/Services/Users/UserDeleteService.cs b/Moonlight/Core/Services/Users/UserDeleteService.cs index 07a31ac..502a8aa 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 96b3178..1d56c1b 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 798e849..dc54a9f 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 e79e10b..3888cd6 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 2712ea1..8298cef 100644 --- a/Moonlight/Core/Services/Utils/JwtService.cs +++ b/Moonlight/Core/Services/Utils/JwtService.cs @@ -1,25 +1,31 @@ using JWT.Algorithms; using JWT.Builder; -using Moonlight.Core.Helpers; +using JWT.Exceptions; +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; } - public Task Create(Action> data, TimeSpan? validDuration = null) + public Task Create(Action> data, string type, TimeSpan? validDuration = null) { var builder = new JwtBuilder() .WithSecret(ConfigService.Get().Security.Token) .IssuedAt(DateTime.UtcNow) + .AddHeader("Type", type) .ExpirationTime(DateTime.UtcNow.Add(validDuration ?? DefaultDuration)) .WithAlgorithm(new HMACSHA512Algorithm()); @@ -34,17 +40,53 @@ public class JwtService return Task.FromResult(jwt); } - public Task Validate(string token) + public Task Validate(string token, params string[] allowedJwtTypes) { try { + // Without the body decode call the jwt validation would not work for some weird reason. + // It would not throw an error when the signature is invalid _ = new JwtBuilder() .WithSecret(ConfigService.Get().Security.Token) .WithAlgorithm(new HMACSHA512Algorithm()) .MustVerifySignature() .Decode(token); - return Task.FromResult(true); + var headerJson = new JwtBuilder() + .WithSecret(ConfigService.Get().Security.Token) + .WithAlgorithm(new HMACSHA512Algorithm()) + .MustVerifySignature() + .DecodeHeader(token); + + if (headerJson == null) + return Task.FromResult(false); + + // Jwt type validation + if (allowedJwtTypes.Length == 0) + return Task.FromResult(true); + + var headerData = JsonConvert.DeserializeObject>(headerJson); + + if (headerData == null) // => Invalid header + return Task.FromResult(false); + + if (!headerData.ContainsKey("Type")) // => Invalid header, Type is missing + return Task.FromResult(false); + + foreach (var name in allowedJwtTypes) + { + if (headerData["Type"] == name) // => Correct type found + return Task.FromResult(true); + } + + // None found? Invalid type! + return Task.FromResult(false); + } + catch (SignatureVerificationException) + { + Logger.Warn($"A manipulated jwt has been found. Required jwt types: {string.Join(" ", allowedJwtTypes)} Jwt: {token}"); + + return Task.FromResult(false); } catch (Exception e) { @@ -64,11 +106,17 @@ public class JwtService .Decode(token); var data = JsonConvert.DeserializeObject>(json); - + return Task.FromResult(data)!; } - catch (Exception) + catch (SignatureVerificationException) { + return Task.FromResult(new Dictionary()); + } + catch (Exception e) + { + Logger.Warn("An unknown error occured while processing token"); + Logger.Warn(e); return Task.FromResult>(null!); } } diff --git a/Moonlight/Core/UI/Components/Auth/ChangePassword.razor b/Moonlight/Core/UI/Components/Auth/ChangePassword.razor index 58c8769..dbc3369 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 a4520e2..67512de 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 @@ -16,7 +16,7 @@ Sign In
- Get unlimited access & earn money + Change me
diff --git a/Moonlight/Core/UI/Components/Auth/Register.razor b/Moonlight/Core/UI/Components/Auth/Register.razor index 6999763..3a1b28a 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 @@ -19,7 +19,7 @@ Sign Up
- Get unlimited access & earn money + change me
diff --git a/Moonlight/Core/UI/Components/Forms/AutoCrud.razor b/Moonlight/Core/UI/Components/Forms/AutoCrud.razor deleted file mode 100644 index 0cdd39c..0000000 --- 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 b3d248e..0000000 --- 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/AutoProperty.razor b/Moonlight/Core/UI/Components/Forms/AutoProperty.razor deleted file mode 100644 index 71afe7e..0000000 --- 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 fc920b8..0000000 --- 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 cd91812..0000000 --- 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 0897bba..0000000 --- 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 - -