diff --git a/Moonlight/App/Database/DataContext.cs b/Moonlight/App/Database/DataContext.cs
index c8575c49..23b93734 100644
--- a/Moonlight/App/Database/DataContext.cs
+++ b/Moonlight/App/Database/DataContext.cs
@@ -2,6 +2,7 @@
using Moonlight.App.Database.Entities;
using Moonlight.App.Database.Entities.LogsEntries;
using Moonlight.App.Database.Entities.Notification;
+using Moonlight.App.Models.Misc;
using Moonlight.App.Services;
namespace Moonlight.App.Database;
diff --git a/Moonlight/App/Database/Entities/Server.cs b/Moonlight/App/Database/Entities/Server.cs
index 11388d90..cad9ced9 100644
--- a/Moonlight/App/Database/Entities/Server.cs
+++ b/Moonlight/App/Database/Entities/Server.cs
@@ -20,4 +20,5 @@ public class Server
public NodeAllocation MainAllocation { get; set; } = null!;
public Node Node { get; set; } = null!;
public User Owner { get; set; } = null!;
+ public bool IsCleanupException { get; set; } = false;
}
\ No newline at end of file
diff --git a/Moonlight/App/Database/Migrations/20230402204329_AddCleanupExceptionsTable.Designer.cs b/Moonlight/App/Database/Migrations/20230402204329_AddCleanupExceptionsTable.Designer.cs
new file mode 100644
index 00000000..7ae61058
--- /dev/null
+++ b/Moonlight/App/Database/Migrations/20230402204329_AddCleanupExceptionsTable.Designer.cs
@@ -0,0 +1,1082 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Moonlight.App.Database;
+
+#nullable disable
+
+namespace Moonlight.App.Database.Migrations
+{
+ [DbContext(typeof(DataContext))]
+ [Migration("20230402204329_AddCleanupExceptionsTable")]
+ partial class AddCleanupExceptionsTable
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.AaPanel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("BaseDomain")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Url")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("AaPanels");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Database", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("AaPanelId")
+ .HasColumnType("int");
+
+ b.Property("InternalAaPanelId")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("OwnerId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AaPanelId");
+
+ b.HasIndex("OwnerId");
+
+ b.ToTable("Databases");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.DdosAttack", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Data")
+ .HasColumnType("bigint");
+
+ b.Property("Ip")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("NodeId")
+ .HasColumnType("int");
+
+ b.Property("Ongoing")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NodeId");
+
+ b.ToTable("DdosAttacks");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Default")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("ImageId")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ImageId");
+
+ b.ToTable("DockerImages");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Domain", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("OwnerId")
+ .HasColumnType("int");
+
+ b.Property("SharedDomainId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OwnerId");
+
+ b.HasIndex("SharedDomainId");
+
+ b.ToTable("Domains");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Allocations")
+ .HasColumnType("int");
+
+ b.Property("ConfigFiles")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("InstallDockerImage")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("InstallEntrypoint")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("InstallScript")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Startup")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("StartupDetection")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("StopCommand")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("TagsJson")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Uuid")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Images");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("ImageTags");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("DefaultValue")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("ImageId")
+ .HasColumnType("int");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ImageId");
+
+ b.ToTable("ImageVariables");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.LoadingMessage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("LoadingMessages");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.LogsEntries.AuditLogEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Ip")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("JsonData")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("System")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("AuditLog");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.LogsEntries.ErrorLogEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Class")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Ip")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("JsonData")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Stacktrace")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("System")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("Id");
+
+ b.ToTable("ErrorLog");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.LogsEntries.SecurityLogEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Ip")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("JsonData")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("System")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("SecurityLog");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Fqdn")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("HttpPort")
+ .HasColumnType("int");
+
+ b.Property("MoonlightDaemonPort")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("SftpPort")
+ .HasColumnType("int");
+
+ b.Property("Ssl")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Token")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("TokenId")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("Nodes");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("NodeId")
+ .HasColumnType("int");
+
+ b.Property("Port")
+ .HasColumnType("int");
+
+ b.Property("ServerId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NodeId");
+
+ b.HasIndex("ServerId");
+
+ b.ToTable("NodeAllocations");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Notification.NotificationAction", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Action")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("NotificationClientId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NotificationClientId");
+
+ b.ToTable("NotificationActions");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Notification.NotificationClient", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("NotificationClients");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Revoke", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Identifier")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("Revokes");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Cpu")
+ .HasColumnType("int");
+
+ b.Property("Disk")
+ .HasColumnType("bigint");
+
+ b.Property("DockerImageIndex")
+ .HasColumnType("int");
+
+ b.Property("ImageId")
+ .HasColumnType("int");
+
+ b.Property("Installing")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("MainAllocationId")
+ .HasColumnType("int");
+
+ b.Property("Memory")
+ .HasColumnType("bigint");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("NodeId")
+ .HasColumnType("int");
+
+ b.Property("OverrideStartup")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("OwnerId")
+ .HasColumnType("int");
+
+ b.Property("Suspended")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Uuid")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ImageId");
+
+ b.HasIndex("MainAllocationId");
+
+ b.HasIndex("NodeId");
+
+ b.HasIndex("OwnerId");
+
+ b.ToTable("Servers");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Bytes")
+ .HasColumnType("bigint");
+
+ b.Property("Created")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("ServerId")
+ .HasColumnType("int");
+
+ b.Property("Uuid")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ServerId");
+
+ b.ToTable("ServerBackups");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("ServerId")
+ .HasColumnType("int");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ServerId");
+
+ b.ToTable("ServerVariables");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.SharedDomain", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CloudflareId")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("SharedDomains");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Subscription", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Duration")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("SellPassId")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("Subscriptions");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.SubscriptionLimit", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Amount")
+ .HasColumnType("int");
+
+ b.Property("Cpu")
+ .HasColumnType("int");
+
+ b.Property("Disk")
+ .HasColumnType("int");
+
+ b.Property("ImageId")
+ .HasColumnType("int");
+
+ b.Property("Memory")
+ .HasColumnType("int");
+
+ b.Property("SubscriptionId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ImageId");
+
+ b.HasIndex("SubscriptionId");
+
+ b.ToTable("SubscriptionLimits");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.SupportMessage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Answer")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("IsQuestion")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsSupport")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("IsSystem")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("RecipientId")
+ .HasColumnType("int");
+
+ b.Property("SenderId")
+ .HasColumnType("int");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RecipientId");
+
+ b.HasIndex("SenderId");
+
+ b.ToTable("SupportMessages");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Address")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)");
+
+ b.Property("Admin")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("City")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("varchar(128)");
+
+ b.Property("Country")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("DiscordId")
+ .HasColumnType("bigint");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("FirstName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("Password")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("State")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("varchar(64)");
+
+ b.Property("Status")
+ .HasColumnType("int");
+
+ b.Property("SubscriptionDuration")
+ .HasColumnType("int");
+
+ b.Property("SubscriptionId")
+ .HasColumnType("int");
+
+ b.Property("SubscriptionSince")
+ .HasColumnType("datetime(6)");
+
+ b.Property("SupportPending")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("TokenValidTime")
+ .HasColumnType("datetime(6)");
+
+ b.Property("TotpEnabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("TotpSecret")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("UpdatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SubscriptionId");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Website", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("AaPanelId")
+ .HasColumnType("int");
+
+ b.Property("DomainName")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("FtpPassword")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("FtpUsername")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("InternalAaPanelId")
+ .HasColumnType("int");
+
+ b.Property("OwnerId")
+ .HasColumnType("int");
+
+ b.Property("PhpVersion")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AaPanelId");
+
+ b.HasIndex("OwnerId");
+
+ b.ToTable("Websites");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Models.Misc.CleanupException", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Note")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("ServerId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("CleanupExceptions");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Database", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.AaPanel", "AaPanel")
+ .WithMany()
+ .HasForeignKey("AaPanelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
+ .WithMany()
+ .HasForeignKey("OwnerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("AaPanel");
+
+ b.Navigation("Owner");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.DdosAttack", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Node", "Node")
+ .WithMany()
+ .HasForeignKey("NodeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Node");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Image", null)
+ .WithMany("DockerImages")
+ .HasForeignKey("ImageId");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Domain", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
+ .WithMany()
+ .HasForeignKey("OwnerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Moonlight.App.Database.Entities.SharedDomain", "SharedDomain")
+ .WithMany()
+ .HasForeignKey("SharedDomainId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Owner");
+
+ b.Navigation("SharedDomain");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Image", null)
+ .WithMany("Variables")
+ .HasForeignKey("ImageId");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Node", null)
+ .WithMany("Allocations")
+ .HasForeignKey("NodeId");
+
+ b.HasOne("Moonlight.App.Database.Entities.Server", null)
+ .WithMany("Allocations")
+ .HasForeignKey("ServerId");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Notification.NotificationAction", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Notification.NotificationClient", "NotificationClient")
+ .WithMany()
+ .HasForeignKey("NotificationClientId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("NotificationClient");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Notification.NotificationClient", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.User", "User")
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Image", "Image")
+ .WithMany()
+ .HasForeignKey("ImageId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Moonlight.App.Database.Entities.NodeAllocation", "MainAllocation")
+ .WithMany()
+ .HasForeignKey("MainAllocationId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Moonlight.App.Database.Entities.Node", "Node")
+ .WithMany()
+ .HasForeignKey("NodeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
+ .WithMany()
+ .HasForeignKey("OwnerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("Image");
+
+ b.Navigation("MainAllocation");
+
+ b.Navigation("Node");
+
+ b.Navigation("Owner");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Server", null)
+ .WithMany("Backups")
+ .HasForeignKey("ServerId");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Server", null)
+ .WithMany("Variables")
+ .HasForeignKey("ServerId");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.SubscriptionLimit", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Image", "Image")
+ .WithMany()
+ .HasForeignKey("ImageId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Moonlight.App.Database.Entities.Subscription", null)
+ .WithMany("Limits")
+ .HasForeignKey("SubscriptionId");
+
+ b.Navigation("Image");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.SupportMessage", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.User", "Recipient")
+ .WithMany()
+ .HasForeignKey("RecipientId");
+
+ b.HasOne("Moonlight.App.Database.Entities.User", "Sender")
+ .WithMany()
+ .HasForeignKey("SenderId");
+
+ b.Navigation("Recipient");
+
+ b.Navigation("Sender");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.Subscription", "Subscription")
+ .WithMany()
+ .HasForeignKey("SubscriptionId");
+
+ b.Navigation("Subscription");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Website", b =>
+ {
+ b.HasOne("Moonlight.App.Database.Entities.AaPanel", "AaPanel")
+ .WithMany()
+ .HasForeignKey("AaPanelId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
+ .WithMany()
+ .HasForeignKey("OwnerId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.Navigation("AaPanel");
+
+ b.Navigation("Owner");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
+ {
+ b.Navigation("DockerImages");
+
+ b.Navigation("Variables");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
+ {
+ b.Navigation("Allocations");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
+ {
+ b.Navigation("Allocations");
+
+ b.Navigation("Backups");
+
+ b.Navigation("Variables");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Subscription", b =>
+ {
+ b.Navigation("Limits");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Moonlight/App/Database/Migrations/20230402204329_AddCleanupExceptionsTable.cs b/Moonlight/App/Database/Migrations/20230402204329_AddCleanupExceptionsTable.cs
new file mode 100644
index 00000000..3c0f8e18
--- /dev/null
+++ b/Moonlight/App/Database/Migrations/20230402204329_AddCleanupExceptionsTable.cs
@@ -0,0 +1,170 @@
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Moonlight.App.Database.Migrations
+{
+ ///
+ public partial class AddCleanupExceptionsTable : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterColumn(
+ name: "State",
+ table: "Users",
+ type: "varchar(64)",
+ maxLength: 64,
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "longtext")
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "LastName",
+ table: "Users",
+ type: "varchar(64)",
+ maxLength: 64,
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "longtext")
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "FirstName",
+ table: "Users",
+ type: "varchar(64)",
+ maxLength: 64,
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "longtext")
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "Country",
+ table: "Users",
+ type: "varchar(64)",
+ maxLength: 64,
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "longtext")
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "City",
+ table: "Users",
+ type: "varchar(128)",
+ maxLength: 128,
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "longtext")
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "Address",
+ table: "Users",
+ type: "varchar(128)",
+ maxLength: 128,
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "longtext")
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "CleanupExceptions",
+ columns: table => new
+ {
+ Id = table.Column(type: "int", nullable: false)
+ .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
+ ServerId = table.Column(type: "int", nullable: false),
+ Note = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_CleanupExceptions", x => x.Id);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "CleanupExceptions");
+
+ migrationBuilder.AlterColumn(
+ name: "State",
+ table: "Users",
+ type: "longtext",
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "varchar(64)",
+ oldMaxLength: 64)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "LastName",
+ table: "Users",
+ type: "longtext",
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "varchar(64)",
+ oldMaxLength: 64)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "FirstName",
+ table: "Users",
+ type: "longtext",
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "varchar(64)",
+ oldMaxLength: 64)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "Country",
+ table: "Users",
+ type: "longtext",
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "varchar(64)",
+ oldMaxLength: 64)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "City",
+ table: "Users",
+ type: "longtext",
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "varchar(128)",
+ oldMaxLength: 128)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.AlterColumn(
+ name: "Address",
+ table: "Users",
+ type: "longtext",
+ nullable: false,
+ oldClrType: typeof(string),
+ oldType: "varchar(128)",
+ oldMaxLength: 128)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ .OldAnnotation("MySql:CharSet", "utf8mb4");
+ }
+ }
+}
diff --git a/Moonlight/App/Database/Migrations/20230402215155_ChengedCleanupExceptionModel.Designer.cs b/Moonlight/App/Database/Migrations/20230402215155_ChengedCleanupExceptionModel.Designer.cs
new file mode 100644
index 00000000..6dd7b206
--- /dev/null
+++ b/Moonlight/App/Database/Migrations/20230402215155_ChengedCleanupExceptionModel.Designer.cs
@@ -0,0 +1,1098 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Moonlight.App.Database;
+
+#nullable disable
+
+namespace Moonlight.App.Database.Migrations
+{
+ [DbContext(typeof(DataContext))]
+ [Migration("20230402215155_ChengedCleanupExceptionModel")]
+ partial class ChengedCleanupExceptionModel
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.AaPanel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("BaseDomain")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Url")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("AaPanels");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Database", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("AaPanelId")
+ .HasColumnType("int");
+
+ b.Property("InternalAaPanelId")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("OwnerId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AaPanelId");
+
+ b.HasIndex("OwnerId");
+
+ b.ToTable("Databases");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.DdosAttack", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Data")
+ .HasColumnType("bigint");
+
+ b.Property("Ip")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("NodeId")
+ .HasColumnType("int");
+
+ b.Property("Ongoing")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("NodeId");
+
+ b.ToTable("DdosAttacks");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Default")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("ImageId")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ImageId");
+
+ b.ToTable("DockerImages");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Domain", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("OwnerId")
+ .HasColumnType("int");
+
+ b.Property("SharedDomainId")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OwnerId");
+
+ b.HasIndex("SharedDomainId");
+
+ b.ToTable("Domains");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Allocations")
+ .HasColumnType("int");
+
+ b.Property("ConfigFiles")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("InstallDockerImage")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("InstallEntrypoint")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("InstallScript")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Startup")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("StartupDetection")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("StopCommand")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("TagsJson")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Uuid")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Images");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("ImageTags");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("DefaultValue")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("ImageId")
+ .HasColumnType("int");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ImageId");
+
+ b.ToTable("ImageVariables");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.LoadingMessage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Message")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("LoadingMessages");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.LogsEntries.AuditLogEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Ip")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("JsonData")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("System")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("AuditLog");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.LogsEntries.ErrorLogEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Class")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Ip")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("JsonData")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Stacktrace")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("System")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("Id");
+
+ b.ToTable("ErrorLog");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.LogsEntries.SecurityLogEntry", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("CreatedAt")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Ip")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("JsonData")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("System")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.ToTable("SecurityLog");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("Fqdn")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("HttpPort")
+ .HasColumnType("int");
+
+ b.Property("MoonlightDaemonPort")
+ .HasColumnType("int");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("SftpPort")
+ .HasColumnType("int");
+
+ b.Property("Ssl")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Token")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("TokenId")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.ToTable("Nodes");
+ });
+
+ modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("NodeId")
+ .HasColumnType("int");
+
+ b.Property