diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index cd967fc..0000000 --- a/.dockerignore +++ /dev/null @@ -1,25 +0,0 @@ -**/.dockerignore -**/.env -**/.git -**/.gitignore -**/.project -**/.settings -**/.toolstarget -**/.vs -**/.vscode -**/.idea -**/*.*proj.user -**/*.dbmdl -**/*.jfm -**/azds.yaml -**/bin -**/charts -**/docker-compose* -**/Dockerfile* -**/node_modules -**/npm-debug.log -**/obj -**/secrets.dev.yaml -**/values.dev.yaml -LICENSE -README.md \ No newline at end of file diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index 6fb47de..0000000 --- a/.gitattributes +++ /dev/null @@ -1,10 +0,0 @@ -# Auto detect text files and perform LF normalization -* text=auto -Moonlight/wwwroot/** linguist-vendored -Moonlight/wwwroot/assets/js/scripts.bundle.js linguist-vendored -Moonlight/wwwroot/assets/js/widgets.bundle.js linguist-vendored -Moonlight/wwwroot/assets/js/theme.js linguist-vendored -Moonlight/wwwroot/assets/css/boxicons.min.css linguist-vendored -Moonlight/wwwroot/assets/css/style.bundle.css linguist-vendored -Moonlight/wwwroot/assets/plugins/** linguist-vendored -Moonlight/wwwroot/assets/fonts/** linguist-vendored diff --git a/.gitignore b/.gitignore deleted file mode 100644 index e836232..0000000 --- a/.gitignore +++ /dev/null @@ -1,44 +0,0 @@ - Common IntelliJ Platform excludes - -# User specific -**/.idea/**/workspace.xml -**/.idea/**/tasks.xml -**/.idea/shelf/* -**/.idea/dictionaries -**/.idea/httpRequests/ - -# Sensitive or high-churn files -**/.idea/**/dataSources/ -**/.idea/**/dataSources.ids -**/.idea/**/dataSources.xml -**/.idea/**/dataSources.local.xml -**/.idea/**/sqlDataSources.xml -**/.idea/**/dynamic.xml - -# Rider -# Rider auto-generates .iml files, and contentModel.xml -**/.idea/**/*.iml -**/.idea/**/contentModel.xml -**/.idea/**/modules.xml - - -Moonlight/[Bb]in/ -Moonlight/[Oo]bj/ -Moonlight/_UpgradeReport_Files/ -Moonlight/[Pp]ackages/ - -*.suo -*.user -.vs/ -[Bb]in/ -[Oo]bj/ -_UpgradeReport_Files/ -[Pp]ackages/ - -Thumbs.db -Desktop.ini -.DS_Store -.idea/.idea.Moonlight/.idea/discord.xml -Moonlight/wwwroot/css/theme.css -Moonlight/wwwroot/css/theme.css.map -storage/ diff --git a/.idea/.idea.Moonlight/.idea/efCoreCommonOptions.xml b/.idea/.idea.Moonlight/.idea/efCoreCommonOptions.xml deleted file mode 100644 index c001b75..0000000 --- a/.idea/.idea.Moonlight/.idea/efCoreCommonOptions.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/.idea.Moonlight/.idea/efCoreDialogsState.xml b/.idea/.idea.Moonlight/.idea/efCoreDialogsState.xml deleted file mode 100644 index 8f682f3..0000000 --- a/.idea/.idea.Moonlight/.idea/efCoreDialogsState.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/.idea.Moonlight/.idea/encodings.xml b/.idea/.idea.Moonlight/.idea/encodings.xml deleted file mode 100644 index df87cf9..0000000 --- a/.idea/.idea.Moonlight/.idea/encodings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/.idea.Moonlight/.idea/indexLayout.xml b/.idea/.idea.Moonlight/.idea/indexLayout.xml deleted file mode 100644 index 7b08163..0000000 --- a/.idea/.idea.Moonlight/.idea/indexLayout.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/.idea.Moonlight/.idea/projectSettingsUpdater.xml b/.idea/.idea.Moonlight/.idea/projectSettingsUpdater.xml deleted file mode 100644 index 4bb9f4d..0000000 --- a/.idea/.idea.Moonlight/.idea/projectSettingsUpdater.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/.idea.Moonlight/.idea/vcs.xml b/.idea/.idea.Moonlight/.idea/vcs.xml deleted file mode 100644 index 94a25f7..0000000 --- a/.idea/.idea.Moonlight/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Moonlight.sln b/Moonlight.sln deleted file mode 100644 index 87f7f78..0000000 --- a/Moonlight.sln +++ /dev/null @@ -1,16 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moonlight", "Moonlight\Moonlight.csproj", "{691E5EC2-4B4F-4BD1-9CBC-7D3C6EFC12DA}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {691E5EC2-4B4F-4BD1-9CBC-7D3C6EFC12DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {691E5EC2-4B4F-4BD1-9CBC-7D3C6EFC12DA}.Debug|Any CPU.Build.0 = Debug|Any CPU - {691E5EC2-4B4F-4BD1-9CBC-7D3C6EFC12DA}.Release|Any CPU.ActiveCfg = Release|Any CPU - {691E5EC2-4B4F-4BD1-9CBC-7D3C6EFC12DA}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/Moonlight/BlazorApp.razor b/Moonlight/BlazorApp.razor deleted file mode 100644 index abf100d..0000000 --- a/Moonlight/BlazorApp.razor +++ /dev/null @@ -1,15 +0,0 @@ -@using Moonlight.Core.UI.Layouts - - - - - - - - - Not found - -

Sorry, there's nothing at this address.

-
-
-
\ No newline at end of file diff --git a/Moonlight/Core/Actions/Dummy/DummyActions.cs b/Moonlight/Core/Actions/Dummy/DummyActions.cs deleted file mode 100644 index 4f11be2..0000000 --- a/Moonlight/Core/Actions/Dummy/DummyActions.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.ServiceManagement.Models.Abstractions; - -namespace Moonlight.Core.Actions.Dummy; - -public class DummyActions : ServiceActions -{ - public override Task Create(IServiceProvider provider, Service service) - { - return Task.CompletedTask; - } - - public override Task Update(IServiceProvider provider, Service service) - { - return Task.CompletedTask; - } - - public override Task Delete(IServiceProvider provider, Service service) - { - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Actions/Dummy/DummyConfig.cs b/Moonlight/Core/Actions/Dummy/DummyConfig.cs deleted file mode 100644 index f9d7bfa..0000000 --- a/Moonlight/Core/Actions/Dummy/DummyConfig.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.ComponentModel; - -namespace Moonlight.Core.Actions.Dummy; - -public class DummyConfig -{ - [Description("Some description")] - public string String { get; set; } = ""; - public bool Boolean { get; set; } - public int Integer { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs b/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs deleted file mode 100644 index 91da0bf..0000000 --- a/Moonlight/Core/Actions/Dummy/DummyServiceDefinition.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Moonlight.Core.Actions.Dummy.Layouts; -using Moonlight.Core.Actions.Dummy.Pages; -using Moonlight.Features.ServiceManagement.Models.Abstractions; - -namespace Moonlight.Core.Actions.Dummy; - -public class DummyServiceDefinition : ServiceDefinition -{ - public override ServiceActions Actions => new DummyActions(); - public override Type ConfigType => typeof(DummyConfig); - public override async Task BuildUserView(ServiceViewContext context) - { - context.Layout = typeof(DummyUser); - - await context.AddPage("Demo", "/demo"); - } - - public override Task BuildAdminView(ServiceViewContext context) - { - context.Layout = typeof(DummyAdmin); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Actions/Dummy/Layouts/DummyAdmin.razor b/Moonlight/Core/Actions/Dummy/Layouts/DummyAdmin.razor deleted file mode 100644 index 0f7abae..0000000 --- a/Moonlight/Core/Actions/Dummy/Layouts/DummyAdmin.razor +++ /dev/null @@ -1,5 +0,0 @@ -

DummyAdmin

- -@code { - -} \ No newline at end of file diff --git a/Moonlight/Core/Actions/Dummy/Layouts/DummyUser.razor b/Moonlight/Core/Actions/Dummy/Layouts/DummyUser.razor deleted file mode 100644 index fb0c0ca..0000000 --- a/Moonlight/Core/Actions/Dummy/Layouts/DummyUser.razor +++ /dev/null @@ -1,5 +0,0 @@ -

DummyUser

- -@code { - -} \ No newline at end of file diff --git a/Moonlight/Core/Actions/Dummy/Pages/DummyPage.razor b/Moonlight/Core/Actions/Dummy/Pages/DummyPage.razor deleted file mode 100644 index b465c85..0000000 --- a/Moonlight/Core/Actions/Dummy/Pages/DummyPage.razor +++ /dev/null @@ -1,5 +0,0 @@ -

DummyPage

- -@code { - -} \ No newline at end of file diff --git a/Moonlight/Core/Configuration/ConfigV1.cs b/Moonlight/Core/Configuration/ConfigV1.cs deleted file mode 100644 index 51a378f..0000000 --- a/Moonlight/Core/Configuration/ConfigV1.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System.ComponentModel; -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; - -namespace Moonlight.Core.Configuration; - -public class ConfigV1 -{ - [JsonProperty("AppUrl")] - [Description("The url with which moonlight is accessible from the internet. It must not end with a /")] - public string AppUrl { get; set; } = "http://your-moonlight-instance-without-slash.owo"; - - [JsonProperty("Security")] public SecurityData Security { get; set; } = new(); - [JsonProperty("Database")] public DatabaseData Database { get; set; } = new(); - [JsonProperty("MailServer")] public MailServerData MailServer { get; set; } = new(); - - [JsonProperty("Store")] public StoreData Store { get; set; } = new(); - - [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")] - [Description("The security token helio will use to encrypt various things like tokens")] - public string Token { get; set; } = Guid.NewGuid().ToString().Replace("-", ""); - - [JsonProperty("EnableEmailVerify")] - [Description("This will users force to verify their email address if they havent already")] - public bool EnableEmailVerify { get; set; } = false; - - [JsonProperty("EnableReverseProxyMode")] - [Description("Enable this option if you are using a reverse proxy to access moonlight. This will configure some parts of moonlight to act correctly like the ip detection")] - public bool EnableReverseProxyMode { get; set; } = false; - } - - public class DatabaseData - { - [JsonProperty("UseSqlite")] - public bool UseSqlite { get; set; } = false; - - [JsonProperty("SqlitePath")] - public string SqlitePath { get; set; } = PathBuilder.File("storage", "data.sqlite"); - - [JsonProperty("Host")] - public string Host { get; set; } = "your.db.host"; - - [JsonProperty("Port")] - public int Port { get; set; } = 3306; - - [JsonProperty("Username")] - public string Username { get; set; } = "moonlight_user"; - - [JsonProperty("Password")] - public string Password { get; set; } = "s3cr3t"; - - [JsonProperty("Database")] - public string Database { get; set; } = "moonlight_db"; - } - - public class MailServerData - { - [JsonProperty("Host")] public string Host { get; set; } = "your.email.host"; - - [JsonProperty("Port")] public int Port { get; set; } = 465; - - [JsonProperty("Email")] public string Email { get; set; } = "noreply@your.email.host"; - - [JsonProperty("Password")] public string Password { get; set; } = "s3cr3t"; - - [JsonProperty("UseSsl")] public bool UseSsl { get; set; } = true; - - [JsonProperty("SenderName")] - [Description("This will be shown as the system emails sender name in apps like gmail")] - public string SenderName { get; set; } = "Moonlight System"; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Database/DataContext.cs b/Moonlight/Core/Database/DataContext.cs deleted file mode 100644 index 53a354a..0000000 --- a/Moonlight/Core/Database/DataContext.cs +++ /dev/null @@ -1,85 +0,0 @@ -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; -using Moonlight.Features.Ticketing.Entities; - -namespace Moonlight.Core.Database; - -public class DataContext : DbContext -{ - private readonly ConfigService ConfigService; - - public DbSet Users { get; set; } - - // Store - public DbSet Categories { get; set; } - public DbSet Products { get; set; } - public DbSet Services { get; set; } - public DbSet ServiceShares { get; set; } - - public DbSet GiftCodes { get; set; } - public DbSet GiftCodeUses { get; set; } - - public DbSet Coupons { get; set; } - public DbSet CouponUses { get; set; } - - // Community - public DbSet Posts { get; set; } - public DbSet PostComments { get; set; } - public DbSet PostLikes { get; set; } - public DbSet WordFilters { get; set; } - - // Tickets - public DbSet Tickets { get; set; } - public DbSet TicketMessages { get; set; } - - // 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) - { - ConfigService = configService; - } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - if (!optionsBuilder.IsConfigured) - { - var config = ConfigService.Get().Database; - - if (config.UseSqlite) - optionsBuilder.UseSqlite($"Data Source={config.SqlitePath}"); - else - { - var connectionString = $"host={config.Host};" + - $"port={config.Port};" + - $"database={config.Database};" + - $"uid={config.Username};" + - $"pwd={config.Password}"; - - optionsBuilder.UseMySql( - connectionString, - ServerVersion.AutoDetect(connectionString), - builder => builder.EnableRetryOnFailure(5) - ); - } - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Database/Entities/User.cs b/Moonlight/Core/Database/Entities/User.cs deleted file mode 100644 index 1c83022..0000000 --- a/Moonlight/Core/Database/Entities/User.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Core.Database.Entities; - -public class User -{ - public int Id { get; set; } - public string Username { get; set; } - public string Email { get; set; } - public string Password { get; set; } - public string? Avatar { get; set; } = null; - public string? TotpKey { get; set; } = null; - - // Store - public double Balance { get; set; } - public List Transactions { get; set; } = new(); - - public List CouponUses { get; set; } = new(); - public List GiftCodeUses { get; set; } = new(); - - // Meta data - public string Flags { get; set; } = ""; - public int Permissions { get; set; } = 0; - - // Timestamps - public DateTime TokenValidTimestamp { get; set; } = DateTime.UtcNow.AddMinutes(-10); - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Core/Database/Migrations/20231013200303_AddedUser.Designer.cs b/Moonlight/Core/Database/Migrations/20231013200303_AddedUser.Designer.cs deleted file mode 100644 index 7eed2ec..0000000 --- a/Moonlight/Core/Database/Migrations/20231013200303_AddedUser.Designer.cs +++ /dev/null @@ -1,68 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20231013200303_AddedUser")] - partial class AddedUser - { - /// - 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("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"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231013200303_AddedUser.cs b/Moonlight/Core/Database/Migrations/20231013200303_AddedUser.cs deleted file mode 100644 index a187145..0000000 --- a/Moonlight/Core/Database/Migrations/20231013200303_AddedUser.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddedUser : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Users", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Username = table.Column(type: "TEXT", nullable: false), - Email = table.Column(type: "TEXT", nullable: false), - Password = table.Column(type: "TEXT", nullable: false), - Avatar = table.Column(type: "TEXT", nullable: true), - TotpKey = table.Column(type: "TEXT", nullable: true), - Flags = table.Column(type: "TEXT", nullable: false), - Permissions = table.Column(type: "INTEGER", nullable: false), - TokenValidTimestamp = table.Column(type: "TEXT", nullable: false), - CreatedAt = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Users", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Users"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231017075519_AddStoreModels.Designer.cs b/Moonlight/Core/Database/Migrations/20231017075519_AddStoreModels.Designer.cs deleted file mode 100644 index 3c90fdb..0000000 --- a/Moonlight/Core/Database/Migrations/20231017075519_AddStoreModels.Designer.cs +++ /dev/null @@ -1,342 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20231017075519_AddStoreModels")] - partial class AddStoreModels - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.CouponUse", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("CouponId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("CouponId"); - - b.ToTable("CouponUses"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("GiftCodeId") - .HasColumnType("INTEGER"); - - b.HasKey("Id"); - - b.HasIndex("GiftCodeId"); - - b.ToTable("GiftCodeUses"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.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.User", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Avatar") - .HasColumnType("TEXT"); - - 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.Store.CouponUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Coupon", "Coupon") - .WithMany() - .HasForeignKey("CouponId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Coupon"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.GiftCode", "GiftCode") - .WithMany() - .HasForeignKey("GiftCodeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("GiftCode"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId"); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Owner"); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Service", b => - { - b.Navigation("Shares"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231017075519_AddStoreModels.cs b/Moonlight/Core/Database/Migrations/20231017075519_AddStoreModels.cs deleted file mode 100644 index dcaefe9..0000000 --- a/Moonlight/Core/Database/Migrations/20231017075519_AddStoreModels.cs +++ /dev/null @@ -1,245 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddStoreModels : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Categories", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Name = table.Column(type: "TEXT", nullable: false), - Description = table.Column(type: "TEXT", nullable: false), - Slug = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Categories", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Coupons", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Code = table.Column(type: "TEXT", nullable: false), - Percent = table.Column(type: "INTEGER", nullable: false), - Amount = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Coupons", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "GiftCodes", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Code = table.Column(type: "TEXT", nullable: false), - Value = table.Column(type: "REAL", nullable: false), - Amount = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_GiftCodes", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Products", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CategoryId = table.Column(type: "INTEGER", nullable: true), - Name = table.Column(type: "TEXT", nullable: false), - Description = table.Column(type: "TEXT", nullable: false), - Slug = table.Column(type: "TEXT", nullable: false), - Price = table.Column(type: "REAL", nullable: false), - Stock = table.Column(type: "INTEGER", nullable: false), - MaxPerUser = table.Column(type: "INTEGER", nullable: false), - Duration = table.Column(type: "INTEGER", nullable: false), - Type = table.Column(type: "INTEGER", nullable: false), - ConfigJson = table.Column(type: "TEXT", nullable: false), - CreatedAt = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Products", x => x.Id); - table.ForeignKey( - name: "FK_Products_Categories_CategoryId", - column: x => x.CategoryId, - principalTable: "Categories", - principalColumn: "Id"); - }); - - migrationBuilder.CreateTable( - name: "CouponUses", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CouponId = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CouponUses", x => x.Id); - table.ForeignKey( - name: "FK_CouponUses_Coupons_CouponId", - column: x => x.CouponId, - principalTable: "Coupons", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "GiftCodeUses", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - GiftCodeId = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_GiftCodeUses", x => x.Id); - table.ForeignKey( - name: "FK_GiftCodeUses_GiftCodes_GiftCodeId", - column: x => x.GiftCodeId, - principalTable: "GiftCodes", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "Services", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Nickname = table.Column(type: "TEXT", nullable: true), - Suspended = table.Column(type: "INTEGER", nullable: false), - ProductId = table.Column(type: "INTEGER", nullable: false), - ConfigJsonOverride = table.Column(type: "TEXT", nullable: true), - OwnerId = table.Column(type: "INTEGER", nullable: false), - CreatedAt = table.Column(type: "TEXT", nullable: false), - RenewAt = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Services", x => x.Id); - table.ForeignKey( - name: "FK_Services_Products_ProductId", - column: x => x.ProductId, - principalTable: "Products", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_Services_Users_OwnerId", - column: x => x.OwnerId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "ServiceShares", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - UserId = table.Column(type: "INTEGER", nullable: false), - ServiceId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_ServiceShares", x => x.Id); - table.ForeignKey( - name: "FK_ServiceShares_Services_ServiceId", - column: x => x.ServiceId, - principalTable: "Services", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_ServiceShares_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_CouponUses_CouponId", - table: "CouponUses", - column: "CouponId"); - - migrationBuilder.CreateIndex( - name: "IX_GiftCodeUses_GiftCodeId", - table: "GiftCodeUses", - column: "GiftCodeId"); - - migrationBuilder.CreateIndex( - name: "IX_Products_CategoryId", - table: "Products", - column: "CategoryId"); - - migrationBuilder.CreateIndex( - name: "IX_Services_OwnerId", - table: "Services", - column: "OwnerId"); - - migrationBuilder.CreateIndex( - name: "IX_Services_ProductId", - table: "Services", - column: "ProductId"); - - migrationBuilder.CreateIndex( - name: "IX_ServiceShares_ServiceId", - table: "ServiceShares", - column: "ServiceId"); - - migrationBuilder.CreateIndex( - name: "IX_ServiceShares_UserId", - table: "ServiceShares", - column: "UserId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "CouponUses"); - - migrationBuilder.DropTable( - name: "GiftCodeUses"); - - migrationBuilder.DropTable( - name: "ServiceShares"); - - migrationBuilder.DropTable( - name: "Coupons"); - - migrationBuilder.DropTable( - name: "GiftCodes"); - - migrationBuilder.DropTable( - name: "Services"); - - migrationBuilder.DropTable( - name: "Products"); - - migrationBuilder.DropTable( - name: "Categories"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231018203522_AddedUserStoreData.Designer.cs b/Moonlight/Core/Database/Migrations/20231018203522_AddedUserStoreData.Designer.cs deleted file mode 100644 index 4249659..0000000 --- a/Moonlight/Core/Database/Migrations/20231018203522_AddedUserStoreData.Designer.cs +++ /dev/null @@ -1,372 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20231018203522_AddedUserStoreData")] - partial class AddedUserStoreData - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.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.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.Store.CouponUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Owner"); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Service", b => - { - b.Navigation("Shares"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => - { - b.Navigation("CouponUses"); - - b.Navigation("GiftCodeUses"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231018203522_AddedUserStoreData.cs b/Moonlight/Core/Database/Migrations/20231018203522_AddedUserStoreData.cs deleted file mode 100644 index a22bb9e..0000000 --- a/Moonlight/Core/Database/Migrations/20231018203522_AddedUserStoreData.cs +++ /dev/null @@ -1,130 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddedUserStoreData : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Products_Categories_CategoryId", - table: "Products"); - - migrationBuilder.AddColumn( - name: "Balance", - table: "Users", - type: "REAL", - nullable: false, - defaultValue: 0.0); - - migrationBuilder.AlterColumn( - name: "CategoryId", - table: "Products", - type: "INTEGER", - nullable: false, - defaultValue: 0, - oldClrType: typeof(int), - oldType: "INTEGER", - oldNullable: true); - - migrationBuilder.AddColumn( - name: "UserId", - table: "GiftCodeUses", - type: "INTEGER", - nullable: true); - - migrationBuilder.AddColumn( - name: "UserId", - table: "CouponUses", - type: "INTEGER", - nullable: true); - - migrationBuilder.CreateIndex( - name: "IX_GiftCodeUses_UserId", - table: "GiftCodeUses", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_CouponUses_UserId", - table: "CouponUses", - column: "UserId"); - - migrationBuilder.AddForeignKey( - name: "FK_CouponUses_Users_UserId", - table: "CouponUses", - column: "UserId", - principalTable: "Users", - principalColumn: "Id"); - - migrationBuilder.AddForeignKey( - name: "FK_GiftCodeUses_Users_UserId", - table: "GiftCodeUses", - column: "UserId", - principalTable: "Users", - principalColumn: "Id"); - - migrationBuilder.AddForeignKey( - name: "FK_Products_Categories_CategoryId", - table: "Products", - column: "CategoryId", - principalTable: "Categories", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_CouponUses_Users_UserId", - table: "CouponUses"); - - migrationBuilder.DropForeignKey( - name: "FK_GiftCodeUses_Users_UserId", - table: "GiftCodeUses"); - - migrationBuilder.DropForeignKey( - name: "FK_Products_Categories_CategoryId", - table: "Products"); - - migrationBuilder.DropIndex( - name: "IX_GiftCodeUses_UserId", - table: "GiftCodeUses"); - - migrationBuilder.DropIndex( - name: "IX_CouponUses_UserId", - table: "CouponUses"); - - migrationBuilder.DropColumn( - name: "Balance", - table: "Users"); - - migrationBuilder.DropColumn( - name: "UserId", - table: "GiftCodeUses"); - - migrationBuilder.DropColumn( - name: "UserId", - table: "CouponUses"); - - migrationBuilder.AlterColumn( - name: "CategoryId", - table: "Products", - type: "INTEGER", - nullable: true, - oldClrType: typeof(int), - oldType: "INTEGER"); - - migrationBuilder.AddForeignKey( - name: "FK_Products_Categories_CategoryId", - table: "Products", - column: "CategoryId", - principalTable: "Categories", - principalColumn: "Id"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231018204737_AddedTransactions.Designer.cs b/Moonlight/Core/Database/Migrations/20231018204737_AddedTransactions.Designer.cs deleted file mode 100644 index caabb9e..0000000 --- a/Moonlight/Core/Database/Migrations/20231018204737_AddedTransactions.Designer.cs +++ /dev/null @@ -1,404 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20231018204737_AddedTransactions")] - partial class AddedTransactions - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.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 => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - 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.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.Store.CouponUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Owner"); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Transaction", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", null) - .WithMany("Transactions") - .HasForeignKey("UserId"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.Navigation("Shares"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b => - { - b.Navigation("CouponUses"); - - b.Navigation("GiftCodeUses"); - - b.Navigation("Transactions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231018204737_AddedTransactions.cs b/Moonlight/Core/Database/Migrations/20231018204737_AddedTransactions.cs deleted file mode 100644 index 72a6a61..0000000 --- a/Moonlight/Core/Database/Migrations/20231018204737_AddedTransactions.cs +++ /dev/null @@ -1,46 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddedTransactions : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Transaction", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Price = table.Column(type: "REAL", nullable: false), - Text = table.Column(type: "TEXT", nullable: false), - UserId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Transaction", x => x.Id); - table.ForeignKey( - name: "FK_Transaction_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id"); - }); - - migrationBuilder.CreateIndex( - name: "IX_Transaction_UserId", - table: "Transaction", - column: "UserId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Transaction"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231027105412_AddPostsModels.Designer.cs b/Moonlight/Core/Database/Migrations/20231027105412_AddPostsModels.Designer.cs deleted file mode 100644 index 7b500b5..0000000 --- a/Moonlight/Core/Database/Migrations/20231027105412_AddPostsModels.Designer.cs +++ /dev/null @@ -1,540 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20231027105412_AddPostsModels")] - partial class AddPostsModels - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.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 => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - 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.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 => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Community.Post", null) - .WithMany("Comments") - .HasForeignKey("PostId"); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostLike", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Store.CouponUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Owner"); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Transaction", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", null) - .WithMany("Transactions") - .HasForeignKey("UserId"); - }); - - 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.User", b => - { - b.Navigation("CouponUses"); - - b.Navigation("GiftCodeUses"); - - b.Navigation("Transactions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231027105412_AddPostsModels.cs b/Moonlight/Core/Database/Migrations/20231027105412_AddPostsModels.cs deleted file mode 100644 index 9083ba8..0000000 --- a/Moonlight/Core/Database/Migrations/20231027105412_AddPostsModels.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddPostsModels : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Posts", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Title = table.Column(type: "TEXT", nullable: false), - Content = table.Column(type: "TEXT", nullable: false), - AuthorId = table.Column(type: "INTEGER", nullable: false), - Type = table.Column(type: "INTEGER", nullable: false), - CreatedAt = table.Column(type: "TEXT", nullable: false), - UpdatedAt = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Posts", x => x.Id); - table.ForeignKey( - name: "FK_Posts_Users_AuthorId", - column: x => x.AuthorId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "PostComments", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Content = table.Column(type: "TEXT", nullable: false), - AuthorId = table.Column(type: "INTEGER", nullable: false), - CreatedAt = table.Column(type: "TEXT", nullable: false), - UpdatedAt = table.Column(type: "TEXT", nullable: false), - PostId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PostComments", x => x.Id); - table.ForeignKey( - name: "FK_PostComments_Posts_PostId", - column: x => x.PostId, - principalTable: "Posts", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_PostComments_Users_AuthorId", - column: x => x.AuthorId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "PostLikes", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - UserId = table.Column(type: "INTEGER", nullable: false), - CreatedAt = table.Column(type: "TEXT", nullable: false), - PostId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_PostLikes", x => x.Id); - table.ForeignKey( - name: "FK_PostLikes_Posts_PostId", - column: x => x.PostId, - principalTable: "Posts", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_PostLikes_Users_UserId", - column: x => x.UserId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_PostComments_AuthorId", - table: "PostComments", - column: "AuthorId"); - - migrationBuilder.CreateIndex( - name: "IX_PostComments_PostId", - table: "PostComments", - column: "PostId"); - - migrationBuilder.CreateIndex( - name: "IX_PostLikes_PostId", - table: "PostLikes", - column: "PostId"); - - migrationBuilder.CreateIndex( - name: "IX_PostLikes_UserId", - table: "PostLikes", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Posts_AuthorId", - table: "Posts", - column: "AuthorId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "PostComments"); - - migrationBuilder.DropTable( - name: "PostLikes"); - - migrationBuilder.DropTable( - name: "Posts"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231028214520_AddedWordFilter.Designer.cs b/Moonlight/Core/Database/Migrations/20231028214520_AddedWordFilter.Designer.cs deleted file mode 100644 index 5492762..0000000 --- a/Moonlight/Core/Database/Migrations/20231028214520_AddedWordFilter.Designer.cs +++ /dev/null @@ -1,555 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20231028214520_AddedWordFilter")] - partial class AddedWordFilter - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.WordFilter", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Filter") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("WordFilters"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.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 => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - 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.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 => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Community.Post", null) - .WithMany("Comments") - .HasForeignKey("PostId"); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostLike", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Store.CouponUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Owner"); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Transaction", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", null) - .WithMany("Transactions") - .HasForeignKey("UserId"); - }); - - 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.User", b => - { - b.Navigation("CouponUses"); - - b.Navigation("GiftCodeUses"); - - b.Navigation("Transactions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231028214520_AddedWordFilter.cs b/Moonlight/Core/Database/Migrations/20231028214520_AddedWordFilter.cs deleted file mode 100644 index a43b859..0000000 --- a/Moonlight/Core/Database/Migrations/20231028214520_AddedWordFilter.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddedWordFilter : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "WordFilters", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Filter = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_WordFilters", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "WordFilters"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231101161843_AddedTicketModels.Designer.cs b/Moonlight/Core/Database/Migrations/20231101161843_AddedTicketModels.Designer.cs deleted file mode 100644 index 9772bff..0000000 --- a/Moonlight/Core/Database/Migrations/20231101161843_AddedTicketModels.Designer.cs +++ /dev/null @@ -1,666 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20231101161843_AddedTicketModels")] - partial class AddedTicketModels - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.WordFilter", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Filter") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("WordFilters"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.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 => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - 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.Core.Database.Entities.Tickets.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.Core.Database.Entities.Tickets.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.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 => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Community.Post", null) - .WithMany("Comments") - .HasForeignKey("PostId"); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostLike", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Store.CouponUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Owner"); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Transaction", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", null) - .WithMany("Transactions") - .HasForeignKey("UserId"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Service", "Service") - .WithMany() - .HasForeignKey("ServiceId"); - - b.Navigation("Creator"); - - b.Navigation("Service"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.TicketMessage", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Sender") - .WithMany() - .HasForeignKey("SenderId"); - - b.HasOne("Moonlight.Core.Database.Entities.Tickets.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"); - - b.Navigation("GiftCodeUses"); - - b.Navigation("Transactions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231101161843_AddedTicketModels.cs b/Moonlight/Core/Database/Migrations/20231101161843_AddedTicketModels.cs deleted file mode 100644 index ac2ad43..0000000 --- a/Moonlight/Core/Database/Migrations/20231101161843_AddedTicketModels.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddedTicketModels : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Tickets", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - CreatorId = table.Column(type: "INTEGER", nullable: false), - Name = table.Column(type: "TEXT", nullable: false), - Description = table.Column(type: "TEXT", nullable: false), - Tries = table.Column(type: "TEXT", nullable: false), - Priority = table.Column(type: "INTEGER", nullable: false), - Open = table.Column(type: "INTEGER", nullable: false), - ServiceId = table.Column(type: "INTEGER", nullable: true), - CreatedAt = table.Column(type: "TEXT", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Tickets", x => x.Id); - table.ForeignKey( - name: "FK_Tickets_Services_ServiceId", - column: x => x.ServiceId, - principalTable: "Services", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_Tickets_Users_CreatorId", - column: x => x.CreatorId, - principalTable: "Users", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "TicketMessages", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - SenderId = table.Column(type: "INTEGER", nullable: true), - IsSupport = table.Column(type: "INTEGER", nullable: false), - Content = table.Column(type: "TEXT", nullable: false), - Attachment = table.Column(type: "TEXT", nullable: true), - CreatedAt = table.Column(type: "TEXT", nullable: false), - TicketId = table.Column(type: "INTEGER", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_TicketMessages", x => x.Id); - table.ForeignKey( - name: "FK_TicketMessages_Tickets_TicketId", - column: x => x.TicketId, - principalTable: "Tickets", - principalColumn: "Id"); - table.ForeignKey( - name: "FK_TicketMessages_Users_SenderId", - column: x => x.SenderId, - principalTable: "Users", - principalColumn: "Id"); - }); - - migrationBuilder.CreateIndex( - name: "IX_TicketMessages_SenderId", - table: "TicketMessages", - column: "SenderId"); - - migrationBuilder.CreateIndex( - name: "IX_TicketMessages_TicketId", - table: "TicketMessages", - column: "TicketId"); - - migrationBuilder.CreateIndex( - name: "IX_Tickets_CreatorId", - table: "Tickets", - column: "CreatorId"); - - migrationBuilder.CreateIndex( - name: "IX_Tickets_ServiceId", - table: "Tickets", - column: "ServiceId"); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "TicketMessages"); - - migrationBuilder.DropTable( - name: "Tickets"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231222100225_AddThemeModel.Designer.cs b/Moonlight/Core/Database/Migrations/20231222100225_AddThemeModel.Designer.cs deleted file mode 100644 index 4a8c9da..0000000 --- a/Moonlight/Core/Database/Migrations/20231222100225_AddThemeModel.Designer.cs +++ /dev/null @@ -1,698 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20231222100225_AddThemeModel")] - partial class AddThemeModel - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.WordFilter", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Filter") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("WordFilters"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.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 => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - 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.Core.Database.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.Core.Database.Entities.Tickets.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.Core.Database.Entities.Tickets.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.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 => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Community.Post", null) - .WithMany("Comments") - .HasForeignKey("PostId"); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostLike", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Store.CouponUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Owner"); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Transaction", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", null) - .WithMany("Transactions") - .HasForeignKey("UserId"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Service", "Service") - .WithMany() - .HasForeignKey("ServiceId"); - - b.Navigation("Creator"); - - b.Navigation("Service"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.TicketMessage", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Sender") - .WithMany() - .HasForeignKey("SenderId"); - - b.HasOne("Moonlight.Core.Database.Entities.Tickets.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"); - - b.Navigation("GiftCodeUses"); - - b.Navigation("Transactions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20231222100225_AddThemeModel.cs b/Moonlight/Core/Database/Migrations/20231222100225_AddThemeModel.cs deleted file mode 100644 index aa5fb5d..0000000 --- a/Moonlight/Core/Database/Migrations/20231222100225_AddThemeModel.cs +++ /dev/null @@ -1,39 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddThemeModel : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Themes", - columns: table => new - { - Id = table.Column(type: "INTEGER", nullable: false) - .Annotation("Sqlite:Autoincrement", true), - Name = table.Column(type: "TEXT", nullable: false), - Author = table.Column(type: "TEXT", nullable: false), - DonateUrl = table.Column(type: "TEXT", nullable: true), - CssUrl = table.Column(type: "TEXT", nullable: false), - JsUrl = table.Column(type: "TEXT", nullable: true), - Enabled = table.Column(type: "INTEGER", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Themes", x => x.Id); - }); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Themes"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20240119090835_AddedTransactionDate.Designer.cs b/Moonlight/Core/Database/Migrations/20240119090835_AddedTransactionDate.Designer.cs deleted file mode 100644 index 40b8d57..0000000 --- a/Moonlight/Core/Database/Migrations/20240119090835_AddedTransactionDate.Designer.cs +++ /dev/null @@ -1,701 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - [Migration("20240119090835_AddedTransactionDate")] - partial class AddedTransactionDate - { - /// - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "7.0.2"); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.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.Core.Database.Entities.Community.WordFilter", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("Filter") - .IsRequired() - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.ToTable("WordFilters"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.Core.Database.Entities.Store.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.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 => - { - 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.Core.Database.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.Core.Database.Entities.Tickets.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.Core.Database.Entities.Tickets.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.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 => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Author") - .WithMany() - .HasForeignKey("AuthorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Community.Post", null) - .WithMany("Comments") - .HasForeignKey("PostId"); - - b.Navigation("Author"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostLike", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Community.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.Core.Database.Entities.Store.CouponUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.GiftCodeUse", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Product", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.Category", "Category") - .WithMany() - .HasForeignKey("CategoryId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Category"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Owner") - .WithMany() - .HasForeignKey("OwnerId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Product", "Product") - .WithMany() - .HasForeignKey("ProductId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Owner"); - - b.Navigation("Product"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.ServiceShare", b => - { - b.HasOne("Moonlight.Core.Database.Entities.Store.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.Core.Database.Entities.Store.Transaction", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", null) - .WithMany("Transactions") - .HasForeignKey("UserId"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Creator") - .WithMany() - .HasForeignKey("CreatorId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Moonlight.Core.Database.Entities.Store.Service", "Service") - .WithMany() - .HasForeignKey("ServiceId"); - - b.Navigation("Creator"); - - b.Navigation("Service"); - }); - - modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.TicketMessage", b => - { - b.HasOne("Moonlight.Core.Database.Entities.User", "Sender") - .WithMany() - .HasForeignKey("SenderId"); - - b.HasOne("Moonlight.Core.Database.Entities.Tickets.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"); - - b.Navigation("GiftCodeUses"); - - b.Navigation("Transactions"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20240119090835_AddedTransactionDate.cs b/Moonlight/Core/Database/Migrations/20240119090835_AddedTransactionDate.cs deleted file mode 100644 index 806e2ec..0000000 --- a/Moonlight/Core/Database/Migrations/20240119090835_AddedTransactionDate.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - /// - public partial class AddedTransactionDate : Migration - { - /// - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AddColumn( - name: "CreatedAt", - table: "Transaction", - type: "TEXT", - nullable: false, - defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); - } - - /// - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropColumn( - name: "CreatedAt", - table: "Transaction"); - } - } -} diff --git a/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.Designer.cs b/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.Designer.cs deleted file mode 100644 index 0fb9d13..0000000 --- a/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.Designer.cs +++ /dev/null @@ -1,1026 +0,0 @@ -// -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 deleted file mode 100644 index 7c53f5d..0000000 --- a/Moonlight/Core/Database/Migrations/20240127110558_AddedServerModels.cs +++ /dev/null @@ -1,266 +0,0 @@ -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 deleted file mode 100644 index 5be6d5e..0000000 --- a/Moonlight/Core/Database/Migrations/20240127164420_FixedMissingPropertyInServerImage.Designer.cs +++ /dev/null @@ -1,1040 +0,0 @@ -// -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 deleted file mode 100644 index f656bc9..0000000 --- a/Moonlight/Core/Database/Migrations/20240127164420_FixedMissingPropertyInServerImage.cs +++ /dev/null @@ -1,48 +0,0 @@ -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 deleted file mode 100644 index d5d662a..0000000 --- a/Moonlight/Core/Database/Migrations/20240129160704_AddedAllowUserToChangeDockerImage.Designer.cs +++ /dev/null @@ -1,1043 +0,0 @@ -// -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 deleted file mode 100644 index c0e49c8..0000000 --- a/Moonlight/Core/Database/Migrations/20240129160704_AddedAllowUserToChangeDockerImage.cs +++ /dev/null @@ -1,29 +0,0 @@ -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 deleted file mode 100644 index 632b3cf..0000000 --- a/Moonlight/Core/Database/Migrations/20240214091019_AddedServerSchedules.Designer.cs +++ /dev/null @@ -1,1089 +0,0 @@ -// -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 deleted file mode 100644 index 3c39ea0..0000000 --- a/Moonlight/Core/Database/Migrations/20240214091019_AddedServerSchedules.cs +++ /dev/null @@ -1,51 +0,0 @@ -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 deleted file mode 100644 index df1c5be..0000000 --- a/Moonlight/Core/Database/Migrations/DataContextModelSnapshot.cs +++ /dev/null @@ -1,1086 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Moonlight.Core.Database; - -#nullable disable - -namespace Moonlight.Core.Database.Migrations -{ - [DbContext(typeof(DataContext))] - partial class DataContextModelSnapshot : ModelSnapshot - { - protected override void BuildModel(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/Event/Args/MailVerificationEventArgs.cs b/Moonlight/Core/Event/Args/MailVerificationEventArgs.cs deleted file mode 100644 index 69b4450..0000000 --- a/Moonlight/Core/Event/Args/MailVerificationEventArgs.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Moonlight.Core.Database.Entities; - -namespace Moonlight.Core.Event.Args; - -public class MailVerificationEventArgs -{ - public User User { get; set; } - public string Jwt { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/Event/Args/TicketMessageEventArgs.cs b/Moonlight/Core/Event/Args/TicketMessageEventArgs.cs deleted file mode 100644 index 715d3a7..0000000 --- a/Moonlight/Core/Event/Args/TicketMessageEventArgs.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Moonlight.Features.Ticketing.Entities; - -namespace Moonlight.Core.Event.Args; - -public class TicketMessageEventArgs -{ - public Ticket Ticket { get; set; } - public TicketMessage TicketMessage { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/Event/Args/TransactionCreatedEventArgs.cs b/Moonlight/Core/Event/Args/TransactionCreatedEventArgs.cs deleted file mode 100644 index a04e258..0000000 --- a/Moonlight/Core/Event/Args/TransactionCreatedEventArgs.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Moonlight.Core.Database.Entities; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Core.Event.Args; - -public class TransactionCreatedEventArgs -{ - public Transaction Transaction { get; set; } - public User User { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/Event/Events.cs b/Moonlight/Core/Event/Events.cs deleted file mode 100644 index 9f3f38a..0000000 --- a/Moonlight/Core/Event/Events.cs +++ /dev/null @@ -1,27 +0,0 @@ -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Event.Args; -using Moonlight.Features.Community.Entities; -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.Ticketing.Entities; - -namespace Moonlight.Core.Event; - -public class Events -{ - public static EventHandler OnUserRegistered; - public static EventHandler OnUserPasswordChanged; - public static EventHandler OnUserTotpSet; - public static EventHandler OnUserMailVerify; - public static EventHandler OnServiceOrdered; - public static EventHandler OnTransactionCreated; - public static EventHandler OnPostCreated; - public static EventHandler OnPostUpdated; - public static EventHandler OnPostDeleted; - public static EventHandler OnPostLiked; - public static EventHandler OnPostCommentCreated; - public static EventHandler OnPostCommentDeleted; - public static EventHandler OnTicketCreated; - public static EventHandler OnTicketMessage; - public static EventHandler OnTicketUpdated; - public static EventHandler OnMoonlightRestart; -} \ No newline at end of file diff --git a/Moonlight/Core/Extensions/Attributes/RequirePermissionAttribute.cs b/Moonlight/Core/Extensions/Attributes/RequirePermissionAttribute.cs deleted file mode 100644 index e409c43..0000000 --- a/Moonlight/Core/Extensions/Attributes/RequirePermissionAttribute.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Moonlight.Core.Models.Enums; - -namespace Moonlight.Core.Extensions.Attributes; - -public class RequirePermissionAttribute : Attribute -{ - public int PermissionInteger = 0; - - public RequirePermissionAttribute(){} - - public RequirePermissionAttribute(int perms) - { - PermissionInteger = perms; - } - - public RequirePermissionAttribute(Permission permission) - { - PermissionInteger = (int)permission; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Extensions/ConfigServiceExtensions.cs b/Moonlight/Core/Extensions/ConfigServiceExtensions.cs deleted file mode 100644 index 481096f..0000000 --- a/Moonlight/Core/Extensions/ConfigServiceExtensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -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/EventHandlerExtensions.cs b/Moonlight/Core/Extensions/EventHandlerExtensions.cs deleted file mode 100644 index a070432..0000000 --- a/Moonlight/Core/Extensions/EventHandlerExtensions.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Moonlight.Core.Extensions; - -public static class EventHandlerExtensions -{ - public static async Task InvokeAsync(this EventHandler handler) - { - var tasks = handler - .GetInvocationList() - .Select(x => new Task(() => x.DynamicInvoke(null, null))) - .ToArray(); - - foreach (var task in tasks) - { - task.Start(); - } - - await Task.WhenAll(tasks); - } - - public static async Task InvokeAsync(this EventHandler? handler, T? data = default(T)) - { - if(handler == null) - return; - - var tasks = handler - .GetInvocationList() - .Select(x => new Task(() => x.DynamicInvoke(null, data))) - .ToArray(); - - foreach (var task in tasks) - { - task.Start(); - } - - await Task.WhenAll(tasks); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Extensions/ZipArchiveExtension.cs b/Moonlight/Core/Extensions/ZipArchiveExtension.cs deleted file mode 100644 index 14be580..0000000 --- a/Moonlight/Core/Extensions/ZipArchiveExtension.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.IO.Compression; -using System.Text; - -namespace Moonlight.Core.Extensions; - -public static class ZipArchiveExtension -{ - public static async Task AddFromText(this ZipArchive archive, string entryName, string content) - { - using var memoryStream = new MemoryStream(); - await memoryStream.WriteAsync(Encoding.UTF8.GetBytes(content)); - await memoryStream.FlushAsync(); - - await archive.AddFromStream(entryName, memoryStream); - } - - public static async Task AddFromStream(this ZipArchive archive, string entryName, Stream dataStream) - { - var entry = archive.CreateEntry(entryName, CompressionLevel.Fastest); - await using var stream = entry.Open(); - - dataStream.Position = 0; - await dataStream.CopyToAsync(stream); - await stream.FlushAsync(); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Http/Controllers/Api/AssetProxyController.cs b/Moonlight/Core/Http/Controllers/Api/AssetProxyController.cs deleted file mode 100644 index 401d72e..0000000 --- a/Moonlight/Core/Http/Controllers/Api/AssetProxyController.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using MoonCore.Helpers; -using Moonlight.Features.Theming.Services; - -namespace Moonlight.Core.Http.Controllers.Api; - -[ApiController] -[Route("api/assetproxy")] -public class AssetProxyController : Controller -{ - private readonly ThemeService ThemeService; - - public AssetProxyController(ThemeService themeService) - { - ThemeService = themeService; - } - - [HttpGet("theme/{id}/js")] - public async Task GetThemeJs(int id) - { - var enabledThemes = await ThemeService.GetEnabled(); - var selectedTheme = enabledThemes.FirstOrDefault(x => x.Id == id); - - if (selectedTheme == null) - return NotFound(); - - try - { - using var httpClient = new HttpClient(); - var content = await httpClient.GetByteArrayAsync(selectedTheme.JsUrl); - - return File(content, "text/javascript"); - } - catch (Exception e) - { - Logger.Warn($"Error proxying js for theme {id}"); - Logger.Warn(e); - return Problem(); - } - } - - [HttpGet("theme/{id}/css")] - public async Task GetThemeCss(int id) - { - var enabledThemes = await ThemeService.GetEnabled(); - var selectedTheme = enabledThemes.FirstOrDefault(x => x.Id == id); - - if (selectedTheme == null) - return NotFound(); - - try - { - using var httpClient = new HttpClient(); - var content = await httpClient.GetByteArrayAsync(selectedTheme.CssUrl); - - return File(content, "text/css"); - } - catch (Exception e) - { - Logger.Warn($"Error proxying css for theme {id}"); - Logger.Warn(e); - return Problem(); - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Http/Controllers/Api/Auth/ResetController.cs b/Moonlight/Core/Http/Controllers/Api/Auth/ResetController.cs deleted file mode 100644 index f1a4f51..0000000 --- a/Moonlight/Core/Http/Controllers/Api/Auth/ResetController.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using MoonCore.Abstractions; -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Models.Enums; - -using Moonlight.Core.Services; -using Moonlight.Core.Services.Utils; - -namespace Moonlight.Core.Http.Controllers.Api.Auth; - -[ApiController] -[Route("api/auth/reset")] -public class ResetController : Controller -{ - private readonly Repository UserRepository; - private readonly IdentityService IdentityService; - private readonly JwtService JwtService; - - public ResetController(Repository userRepository, IdentityService identityService, JwtService jwtService) - { - UserRepository = userRepository; - IdentityService = identityService; - JwtService = jwtService; - } - - [HttpGet] - public async Task Get([FromQuery] string token) - { - // Validate token - - if (!await JwtService.Validate(token)) - return Redirect("/password-reset"); - - var data = await JwtService.Decode(token); - - if (!data.ContainsKey("accountToReset")) - return Redirect("/password-reset"); - - var userId = int.Parse(data["accountToReset"]); - var user = UserRepository - .Get() - .FirstOrDefault(x => x.Id == userId); - - // User may have been deleted, so we check here - - if (user == null) - return Redirect("/password-reset"); - - // In order to allow the user to get access to the change password screen - // we need to authenticate him so we can read his flags. - // That's why we are creating a session here - - var sessionToken = await IdentityService.GenerateToken(user); - - // Authenticate the current identity service instance in order to - // get access to the flags field. - await IdentityService.Authenticate(sessionToken); - IdentityService.Flags[UserFlag.PasswordPending] = true; - await IdentityService.SaveFlags(); - - // Make the user login so he can reach the change password screen - Response.Cookies.Append("token", sessionToken); - return Redirect("/"); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Http/Controllers/Api/Auth/VerifyController.cs b/Moonlight/Core/Http/Controllers/Api/Auth/VerifyController.cs deleted file mode 100644 index f03a4b3..0000000 --- a/Moonlight/Core/Http/Controllers/Api/Auth/VerifyController.cs +++ /dev/null @@ -1,51 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using MoonCore.Helpers; -using Moonlight.Core.Models.Enums; -using Moonlight.Core.Services; -using Moonlight.Core.Services.Utils; - -namespace Moonlight.Core.Http.Controllers.Api.Auth; - -[ApiController] -[Route("api/auth/verify")] -public class VerifyController : Controller -{ - private readonly IdentityService IdentityService; - private readonly JwtService JwtService; - - public VerifyController(IdentityService identityService, JwtService jwtService) - { - IdentityService = identityService; - JwtService = jwtService; - } - - [HttpGet] - public async Task Get([FromQuery] string token) - { - await IdentityService.Authenticate(Request); - - if (!IdentityService.IsSignedIn) - return Redirect("/login"); - - if (!await JwtService.Validate(token)) - return Redirect("/login"); - - var data = await JwtService.Decode(token); - - if (!data.ContainsKey("mailToVerify")) - return Redirect("/login"); - - var mailToVerify = data["mailToVerify"]; - - if (mailToVerify != IdentityService.CurrentUser.Email) - { - Logger.Warn($"User {IdentityService.CurrentUser.Email} tried to mail verify {mailToVerify} via verify api endpoint", "security"); - return Redirect("/login"); - } - - IdentityService.Flags[UserFlag.MailVerified] = true; - await IdentityService.SaveFlags(); - - return Redirect("/"); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Http/Controllers/Api/BucketController.cs b/Moonlight/Core/Http/Controllers/Api/BucketController.cs deleted file mode 100644 index bc7dfe6..0000000 --- a/Moonlight/Core/Http/Controllers/Api/BucketController.cs +++ /dev/null @@ -1,37 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using MoonCore.Helpers; -using Moonlight.Core.Services; - -namespace Moonlight.Core.Http.Controllers.Api; - -[ApiController] -[Route("api/bucket")] -public class BucketController : Controller -{ - private readonly BucketService BucketService; - - public BucketController(BucketService bucketService) - { - BucketService = bucketService; - } - - [HttpGet("{bucket}/{file}")] - public async Task Get([FromRoute] string bucket, [FromRoute] string file) // TODO: Implement auth - { - if (bucket.Contains("..") || file.Contains("..")) - { - Logger.Warn($"Detected path transversal attack ({Request.HttpContext.Connection.RemoteIpAddress}).", "security"); - return NotFound(); - } - - try - { - var stream = await BucketService.Pull(bucket, file); - return File(stream, MimeTypes.GetMimeType(file)); - } - catch (FileNotFoundException) - { - return NotFound(); - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Abstractions/FlagStorage.cs b/Moonlight/Core/Models/Abstractions/FlagStorage.cs deleted file mode 100644 index 829dedf..0000000 --- a/Moonlight/Core/Models/Abstractions/FlagStorage.cs +++ /dev/null @@ -1,50 +0,0 @@ -using Moonlight.Core.Models.Enums; - -namespace Moonlight.Core.Models.Abstractions; - -public class FlagStorage -{ - private readonly List FlagList; - - public UserFlag[] Flags => FlagList - .Select(x => Enum.Parse(typeof(UserFlag), x)) - .Select(x => (UserFlag)x) - .ToArray(); - - public string[] RawFlags => FlagList.ToArray(); - public string RawFlagString => string.Join(";", FlagList); - - public bool this[UserFlag flag] - { - get => Flags.Contains(flag); - set => Set(flag.ToString(), value); - } - - public bool this[string flagName] - { - get => FlagList.Contains(flagName); - set => Set(flagName, value); - } - - public FlagStorage(string flagString) - { - FlagList = flagString - .Split(";") - .Where(x => !string.IsNullOrEmpty(x)) - .ToList(); - } - - public void Set(string flagName, bool shouldAdd) - { - if (shouldAdd) - { - if(!FlagList.Contains(flagName)) - FlagList.Add(flagName); - } - else - { - if (FlagList.Contains(flagName)) - FlagList.Remove(flagName); - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Abstractions/PermissionStorage.cs b/Moonlight/Core/Models/Abstractions/PermissionStorage.cs deleted file mode 100644 index 78cf17f..0000000 --- a/Moonlight/Core/Models/Abstractions/PermissionStorage.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Moonlight.Core.Models.Enums; - -namespace Moonlight.Core.Models.Abstractions; - -public class PermissionStorage -{ - public readonly int PermissionInteger; - - public PermissionStorage(int permissionInteger) - { - PermissionInteger = permissionInteger; - } - - public Permission[] Permissions => GetPermissions(); - - public Permission[] GetPermissions() - { - return GetAllPermissions() - .Where(x => (int)x <= PermissionInteger) - .ToArray(); - } - - public static Permission[] GetAllPermissions() - { - return Enum.GetValues(); - } - - public static Permission GetFromInteger(int id) - { - return GetAllPermissions().First(x => (int)x == id); - } - - public bool this[Permission permission] => Permissions.Contains(permission); -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Abstractions/Session.cs b/Moonlight/Core/Models/Abstractions/Session.cs deleted file mode 100644 index d4b6d93..0000000 --- a/Moonlight/Core/Models/Abstractions/Session.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Moonlight.Core.Database.Entities; - -namespace Moonlight.Core.Models.Abstractions; - -public class Session -{ - public string Ip { get; set; } = "N/A"; - public string Url { get; set; } = "N/A"; - public User? User { get; set; } - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; // To remove inactive sessions -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Abstractions/Subscriber.cs b/Moonlight/Core/Models/Abstractions/Subscriber.cs deleted file mode 100644 index f752f33..0000000 --- a/Moonlight/Core/Models/Abstractions/Subscriber.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Core.Models.Abstractions; - -public class Subscriber -{ - public string Id { get; set; } - public object Action { get; set; } - public object Handle { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Enums/Permission.cs b/Moonlight/Core/Models/Enums/Permission.cs deleted file mode 100644 index 3ab182c..0000000 --- a/Moonlight/Core/Models/Enums/Permission.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Moonlight.Core.Models.Enums; - -public enum Permission -{ - Default = 0, - AdminMenu = 999, - AdminOverview = 1000, - AdminUsers = 1001, - AdminSessions = 1002, - AdminUsersEdit = 1003, - AdminTickets = 1004, - AdminCommunity = 1030, - AdminServices = 1050, - AdminServers = 1060, - AdminStore = 1900, - AdminViewExceptions = 1999, - AdminRoot = 2000 -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Enums/UserFlag.cs b/Moonlight/Core/Models/Enums/UserFlag.cs deleted file mode 100644 index ef613a6..0000000 --- a/Moonlight/Core/Models/Enums/UserFlag.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Core.Models.Enums; - -public enum UserFlag -{ - MailVerified, - PasswordPending, - TotpEnabled -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/Admin/Users/UpdateUserForm.cs b/Moonlight/Core/Models/Forms/Admin/Users/UpdateUserForm.cs deleted file mode 100644 index 8682efe..0000000 --- a/Moonlight/Core/Models/Forms/Admin/Users/UpdateUserForm.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Core.Models.Forms.Admin.Users; - -public class UpdateUserForm -{ - [Required(ErrorMessage = "You need to enter a username")] - [MinLength(7, ErrorMessage = "The username is too short")] - [MaxLength(20, ErrorMessage = "The username cannot be longer than 20 characters")] - [RegularExpression("^[a-z][a-z0-9]*$", ErrorMessage = "Usernames can only contain lowercase characters and numbers")] - public string Username { get; set; } = ""; - - [Required(ErrorMessage = "You need to enter a email address")] - [EmailAddress(ErrorMessage = "You need to enter a valid email address")] - public string Email { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/Admin/Users/UpdateUserPasswordForm.cs b/Moonlight/Core/Models/Forms/Admin/Users/UpdateUserPasswordForm.cs deleted file mode 100644 index 9136579..0000000 --- a/Moonlight/Core/Models/Forms/Admin/Users/UpdateUserPasswordForm.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Core.Models.Forms.Admin.Users; - -public class UpdateUserPasswordForm -{ - [Required(ErrorMessage = "You need to specify a password")] - [MinLength(8, ErrorMessage = "The password must be at least 8 characters long")] - [MaxLength(256, ErrorMessage = "The password must not be longer than 256 characters")] - public string Password { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/Auth/LoginForm.cs b/Moonlight/Core/Models/Forms/Auth/LoginForm.cs deleted file mode 100644 index 7b414a4..0000000 --- a/Moonlight/Core/Models/Forms/Auth/LoginForm.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Core.Models.Forms.Auth; - -public class LoginForm -{ - [Required(ErrorMessage = "You need to provide an email address")] - [EmailAddress(ErrorMessage = "You need to enter a valid email address")] - public string Email { get; set; } - - [Required(ErrorMessage = "You need to provide a password")] - public string Password { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/Auth/RegisterForm.cs b/Moonlight/Core/Models/Forms/Auth/RegisterForm.cs deleted file mode 100644 index 6ebbde4..0000000 --- a/Moonlight/Core/Models/Forms/Auth/RegisterForm.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Core.Models.Forms.Auth; - -public class RegisterForm -{ - [Required(ErrorMessage = "You need to provide an username")] - [MinLength(7, ErrorMessage = "The username is too short")] - [MaxLength(20, ErrorMessage = "The username cannot be longer than 20 characters")] - [RegularExpression("^[a-z][a-z0-9]*$", ErrorMessage = "Usernames can only contain lowercase characters and numbers and should not start with a number")] - public string Username { get; set; } - - [Required(ErrorMessage = "You need to provide an email address")] - [EmailAddress(ErrorMessage = "You need to enter a valid email address")] - public string Email { get; set; } - - [Required(ErrorMessage = "You need to provide a password")] - [MinLength(8, ErrorMessage = "The password must be at least 8 characters long")] - [MaxLength(256, ErrorMessage = "The password must not be longer than 256 characters")] - public string Password { get; set; } - - [Required(ErrorMessage = "You need to provide a password")] - [MinLength(8, ErrorMessage = "The password must be at least 8 characters long")] - [MaxLength(256, ErrorMessage = "The password must not be longer than 256 characters")] - public string RepeatedPassword { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/Auth/ResetPasswordForm.cs b/Moonlight/Core/Models/Forms/Auth/ResetPasswordForm.cs deleted file mode 100644 index 6816728..0000000 --- a/Moonlight/Core/Models/Forms/Auth/ResetPasswordForm.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Core.Models.Forms.Auth; - -public class ResetPasswordForm -{ - [Required(ErrorMessage = "You need to specify an email address")] - [EmailAddress(ErrorMessage = "You need to enter a valid email address")] - public string Email { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/Auth/TwoFactorCodeForm.cs b/Moonlight/Core/Models/Forms/Auth/TwoFactorCodeForm.cs deleted file mode 100644 index 88c7521..0000000 --- a/Moonlight/Core/Models/Forms/Auth/TwoFactorCodeForm.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Core.Models.Forms.Auth; - -public class TwoFactorCodeForm -{ - [Required(ErrorMessage = "You need to enter a two factor code")] - public string Code { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/Auth/UpdateAccountForm.cs b/Moonlight/Core/Models/Forms/Auth/UpdateAccountForm.cs deleted file mode 100644 index 9796e02..0000000 --- a/Moonlight/Core/Models/Forms/Auth/UpdateAccountForm.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Core.Models.Forms.Auth; - -public class UpdateAccountForm -{ - [Required(ErrorMessage = "You need to provide an username")] - [MinLength(7, ErrorMessage = "The username is too short")] - [MaxLength(20, ErrorMessage = "The username cannot be longer than 20 characters")] - [RegularExpression("^[a-z][a-z0-9]*$", ErrorMessage = "Usernames can only contain lowercase characters and numbers")] - public string Username { get; set; } - - [Required(ErrorMessage = "You need to provide an email address")] - [EmailAddress(ErrorMessage = "You need to enter a valid email address")] - public string Email { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Forms/Auth/UpdateAccountPasswordForm.cs b/Moonlight/Core/Models/Forms/Auth/UpdateAccountPasswordForm.cs deleted file mode 100644 index f8f6120..0000000 --- a/Moonlight/Core/Models/Forms/Auth/UpdateAccountPasswordForm.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Core.Models.Forms.Auth; - -public class UpdateAccountPasswordForm -{ - [Required(ErrorMessage = "You need to specify a password")] - [MinLength(8, ErrorMessage = "The password must be at least 8 characters long")] - [MaxLength(256, ErrorMessage = "The password must not be longer than 256 characters")] - public string Password { get; set; } = ""; - - [Required(ErrorMessage = "You need to repeat your new password")] - [MinLength(8, ErrorMessage = "The password must be at least 8 characters long")] - [MaxLength(256, ErrorMessage = "The password must not be longer than 256 characters")] - public string RepeatedPassword { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Templates/MailVerify.cs b/Moonlight/Core/Models/Templates/MailVerify.cs deleted file mode 100644 index 7d90436..0000000 --- a/Moonlight/Core/Models/Templates/MailVerify.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Moonlight.Core.Models.Templates; - -public class MailVerify -{ - public string Url { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Core/Models/Templates/ResetPassword.cs b/Moonlight/Core/Models/Templates/ResetPassword.cs deleted file mode 100644 index d06356b..0000000 --- a/Moonlight/Core/Models/Templates/ResetPassword.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Moonlight.Core.Models.Templates; - -public class ResetPassword -{ - public string Url { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Core/Plugins/Contexts/PluginContext.cs b/Moonlight/Core/Plugins/Contexts/PluginContext.cs deleted file mode 100644 index f16b8d1..0000000 --- a/Moonlight/Core/Plugins/Contexts/PluginContext.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Moonlight.Features.ServiceManagement.Models.Abstractions; - -namespace Moonlight.Core.Plugins.Contexts; - -public class PluginContext -{ - public IServiceCollection Services { get; set; } - public IServiceProvider Provider { get; set; } - public IServiceScope Scope { get; set; } - public WebApplicationBuilder WebApplicationBuilder { get; set; } - public WebApplication WebApplication { get; set; } - public List PreInitTasks = new(); - public List PostInitTasks = new(); - public Action? BuildUserServiceView { get; set; } = null; - public Action? BuildAdminServiceView { get; set; } = null; -} \ No newline at end of file diff --git a/Moonlight/Core/Plugins/MoonlightPlugin.cs b/Moonlight/Core/Plugins/MoonlightPlugin.cs deleted file mode 100644 index b6f71c1..0000000 --- a/Moonlight/Core/Plugins/MoonlightPlugin.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Moonlight.Core.Plugins.Contexts; - -namespace Moonlight.Core.Plugins; - -public abstract class MoonlightPlugin -{ - public PluginContext Context { get; set; } - public abstract Task Enable(); - public abstract Task Disable(); -} \ No newline at end of file diff --git a/Moonlight/Core/Repositories/GenericRepository.cs b/Moonlight/Core/Repositories/GenericRepository.cs deleted file mode 100644 index ed97af2..0000000 --- a/Moonlight/Core/Repositories/GenericRepository.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using Moonlight.Core.Database; - -namespace Moonlight.Core.Repositories; - -[Scoped] -public class GenericRepository : Repository where TEntity : class -{ - private readonly DataContext DataContext; - private readonly DbSet DbSet; - - public GenericRepository(DataContext dbContext) - { - DataContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); - DbSet = DataContext.Set(); - } - - public override DbSet Get() - { - return DbSet; - } - - public override TEntity Add(TEntity entity) - { - var x = DbSet.Add(entity); - DataContext.SaveChanges(); - return x.Entity; - } - - public override void Update(TEntity entity) - { - DbSet.Update(entity); - DataContext.SaveChanges(); - } - - public override void Delete(TEntity entity) - { - DbSet.Remove(entity); - DataContext.SaveChanges(); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Background/AutoMailSendService.cs b/Moonlight/Core/Services/Background/AutoMailSendService.cs deleted file mode 100644 index b4e945b..0000000 --- a/Moonlight/Core/Services/Background/AutoMailSendService.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Moonlight.Core.Database.Entities; -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 : 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) - { - await MailService.Send( - eventArgs.User, - "New transaction", - "transactionCreated", - eventArgs.Transaction, - eventArgs.User - ); - } - - private async void OnServiceOrdered(object? _, Service service) - { - await MailService.Send( - service.Owner, - "New product ordered", - "serviceOrdered", - service, - service.Product, - service.Owner - ); - } - - private async void OnUserRegistered(object? _, User user) - { - await MailService.Send( - user, - $"Welcome {user.Username}", - "welcome", - user - ); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/BucketService.cs b/Moonlight/Core/Services/BucketService.cs deleted file mode 100644 index 37bf0a0..0000000 --- a/Moonlight/Core/Services/BucketService.cs +++ /dev/null @@ -1,86 +0,0 @@ -using MoonCore.Attributes; -using MoonCore.Helpers; - -namespace Moonlight.Core.Services; - -[Singleton] -public class BucketService -{ - private readonly string BasePath; - public string[] Buckets => GetBuckets(); - - - public BucketService() - { - // This is used to create the buckets folder in the persistent storage of helio - BasePath = PathBuilder.Dir("storage", "buckets"); - Directory.CreateDirectory(BasePath); - } - - public string[] GetBuckets() - { - return Directory - .GetDirectories(BasePath) - .Select(x => - x.Replace(BasePath, "").TrimEnd('/') - ) - .ToArray(); - } - - public Task EnsureBucket(string name) // To ensure a specific bucket has been created, call this function - { - Directory.CreateDirectory(PathBuilder.Dir(BasePath, name)); - return Task.CompletedTask; - } - - public async Task Store(string bucket, Stream dataStream, string fileName) - { - await EnsureBucket(bucket); // Ensure the bucket actually exists - - // Create a safe to file name to store the file - var extension = Path.GetExtension(fileName); - var finalFileName = Path.GetRandomFileName() + extension; - var finalFilePath = PathBuilder.File(BasePath, bucket, finalFileName); - - // Copy the file from the remote stream to the bucket - var fs = File.Create(finalFilePath); - await dataStream.CopyToAsync(fs); - await fs.FlushAsync(); - fs.Close(); - - // Return the generated file name to save it in the db or smth - return finalFileName; - } - - public Task Pull(string bucket, string file) - { - var filePath = PathBuilder.File(BasePath, bucket, file); - - if (File.Exists(filePath)) - { - var stream = File.Open(filePath, FileMode.Open); - - return Task.FromResult(stream); - } - else - throw new FileNotFoundException(); - } - - public Task Delete(string bucket, string file, bool ignoreNotFound = false) - { - var filePath = PathBuilder.File(BasePath, bucket, file); - - if (File.Exists(filePath)) - { - File.Delete(filePath); - return Task.CompletedTask; - } - - // This section will only be reached if the file does not exist - - if (!ignoreNotFound) - throw new FileNotFoundException(); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/HotKeyService.cs b/Moonlight/Core/Services/HotKeyService.cs deleted file mode 100644 index ec9541d..0000000 --- a/Moonlight/Core/Services/HotKeyService.cs +++ /dev/null @@ -1,39 +0,0 @@ -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 deleted file mode 100644 index cc7ceaa..0000000 --- a/Moonlight/Core/Services/IdentityService.cs +++ /dev/null @@ -1,189 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Exceptions; -using MoonCore.Helpers; -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Models.Abstractions; -using Moonlight.Core.Models.Enums; -using Moonlight.Core.Services.Utils; -using Moonlight.Features.StoreSystem.Entities; -using OtpNet; - -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; - private readonly JwtService JwtService; - - private string Token; - - public User? CurrentUserNullable { get; private set; } - public User CurrentUser => CurrentUserNullable!; - public bool IsSignedIn => CurrentUserNullable != null; - public FlagStorage Flags { get; private set; } = new(""); - public PermissionStorage Permissions { get; private set; } = new(-1); - public Transaction[] Transactions => GetTransactions().Result; // TODO: make more efficient - public EventHandler OnAuthenticationStateChanged { get; set; } - - public IdentityService(Repository userRepository, - JwtService jwtService) - { - UserRepository = userRepository; - JwtService = jwtService; - } - - // Transactions - public Task GetTransactions() - { - if (CurrentUserNullable == null) - return Task.FromResult(Array.Empty()); - - var user = UserRepository - .Get() - .Include(x => x.Transactions) - .First(x => x.Id == CurrentUserNullable.Id); - - return Task.FromResult(user.Transactions.ToArray()); - } - - // Authentication - - public async Task Authenticate() // Reauthenticate - { - // Save the last id (or -1 if not set) so we can track a change - var lastUserId = CurrentUserNullable == null ? -1 : CurrentUserNullable.Id; - - // Reset - CurrentUserNullable = null; - - await ValidateToken(); - - // Get current user id to compare against the last one - var currentUserId = CurrentUserNullable == null ? -1 : CurrentUserNullable.Id; - - if (lastUserId != currentUserId) // State changed, lets notify all event listeners - OnAuthenticationStateChanged?.Invoke(this, null!); - } - - private async Task ValidateToken() // Read and validate token - { - if (string.IsNullOrEmpty(Token)) - return; - - if (!await JwtService.Validate(Token, "User")) - return; - - var data = await JwtService.Decode(Token); - - if (!data.ContainsKey("userId")) - return; - - var userId = int.Parse(data["userId"]); - - var user = UserRepository - .Get() - .FirstOrDefault(x => x.Id == userId); - - if (user == null) - return; - - if (!data.ContainsKey("issuedAt")) - return; - - var issuedAt = long.Parse(data["issuedAt"]); - var issuedAtDateTime = DateTimeOffset.FromUnixTimeSeconds(issuedAt).DateTime; - - // If the valid time is newer then when the token was issued, the token is not longer valid - if (user.TokenValidTimestamp > issuedAtDateTime) - return; - - CurrentUserNullable = user; - - if (CurrentUserNullable == null) // If the current user is null, stop loading additional data - return; - - Flags = new(CurrentUser.Flags); - Permissions = new(CurrentUser.Permissions); - } - - public async Task Login(string email, string password, string? code = null) - { - var user = UserRepository - .Get() - .FirstOrDefault(x => x.Email == email); - - if (user == null) - throw new DisplayException("A user with these credential combination was not found"); - - if (!HashHelper.Verify(password, user.Password)) - throw new DisplayException("A user with these credential combination was not found"); - - var flags = new FlagStorage(user.Flags); // Construct FlagStorage to check for 2fa - - if (!flags[UserFlag.TotpEnabled]) // No 2fa found on this user so were done here - return await GenerateToken(user); - - // If we reach this point, 2fa is enabled so we need to continue validating - - if (string.IsNullOrEmpty(code)) // This will show an additional 2fa login field - throw new ArgumentNullException(nameof(code), "2FA code missing"); - - if (user.TotpKey == null) // Hopefully we will never fulfill this check ;) - throw new DisplayException("2FA key is missing. Please contact the support to fix your account"); - - // Calculate server side code - var totp = new Totp(Base32Encoding.ToBytes(user.TotpKey)); - var codeServerSide = totp.ComputeTotp(); - - if (codeServerSide == code) - return await GenerateToken(user); - - throw new DisplayException("Invalid 2fa code entered"); - } - - public async Task GenerateToken(User user) - { - var token = await JwtService.Create(data => - { - data.Add("userId", user.Id.ToString()); - data.Add("issuedAt", DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString()); - }, "User", TimeSpan.FromDays(10)); - - return token; - } - - public Task SaveFlags() - { - // Prevent saving flags for an empty user - if (!IsSignedIn) - return Task.CompletedTask; - - // Save the new flag string - CurrentUser.Flags = Flags.RawFlagString; - UserRepository.Update(CurrentUser); - - return Task.CompletedTask; - } - - // Helpers and overloads - public async Task - Authenticate(HttpRequest request) // Overload for api controllers to authenticate a user like the normal panel - { - if (request.Cookies.ContainsKey("token")) - { - var token = request.Cookies["token"]; - await Authenticate(token!); - } - } - - public async Task Authenticate(string token) // Overload to set token and reauth - { - Token = token; - await Authenticate(); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/MailService.cs b/Moonlight/Core/Services/MailService.cs deleted file mode 100644 index 0dab8c8..0000000 --- a/Moonlight/Core/Services/MailService.cs +++ /dev/null @@ -1,110 +0,0 @@ -using MailKit.Net.Smtp; -using MimeKit; -using MoonCore.Attributes; -using MoonCore.Helpers; -using MoonCore.Services; -using Moonlight.Core.Configuration; -using Moonlight.Core.Database.Entities; - -namespace Moonlight.Core.Services; - -[Singleton] -public class MailService -{ - private readonly ConfigService ConfigService; - private readonly string BasePath; - - public MailService(ConfigService configService) - { - ConfigService = configService; - - BasePath = PathBuilder.Dir("storage", "mail"); - Directory.CreateDirectory(BasePath); - } - - public async Task Send(User user, string title, string templateName, params object[] models) - { - var config = ConfigService.Get().MailServer; - - try - { - // Build mail message - var message = new MimeMessage(); - - message.From.Add(new MailboxAddress( - config.SenderName, - config.Email - )); - - message.To.Add(new MailboxAddress( - $"{user.Username}", - user.Email - )); - - message.Subject = Formatter.ProcessTemplating(title, models); - - var body = new BodyBuilder() - { - HtmlBody = await ParseTemplate(templateName, models) - }; - message.Body = body.ToMessageBody(); - - // The actual sending will not be done in the mail thread to prevent long loading times - Task.Run(async () => - { - using var smtpClient = new SmtpClient(); - - 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); - await smtpClient.DisconnectAsync(true); - } - catch (Exception e) - { - Logger.Warn("An unexpected error occured while connecting and transferring mail to mailserver"); - Logger.Warn(e); - } - }); - } - catch (FileNotFoundException) - { - // ignored as we log it anyways in the parse template function - } - catch (Exception e) - { - Logger.Warn("Unhandled error occured during sending mail:"); - Logger.Warn(e); - } - } - - private async Task ParseTemplate(string templateName, params object[] models) - { - if (!File.Exists(PathBuilder.File(BasePath, templateName + ".html"))) - { - Logger.Warn($"Mail template '{templateName}' is missing. Skipping sending mail"); - throw new FileNotFoundException(); - } - - var text = await File.ReadAllTextAsync( - PathBuilder.File(BasePath, templateName + ".html") - ); - - // For details how the templating works, check out the explanation of the ProcessTemplating in the Formatter class - text = Formatter.ProcessTemplating(text, models); - - return text; - } - - // Helpers - - public async Task Send(IEnumerable users, string title, string templateName, params object[] models) - { - foreach (var user in users) - await Send(user, title, templateName, models); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/MoonlightService.cs b/Moonlight/Core/Services/MoonlightService.cs deleted file mode 100644 index d064353..0000000 --- a/Moonlight/Core/Services/MoonlightService.cs +++ /dev/null @@ -1,100 +0,0 @@ -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.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 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) - { - ConfigService = configService; - ServiceProvider = serviceProvider; - } - - 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)); - - await Application.StopAsync(); - } - - public async Task GenerateDiagnoseReport() - { - var scope = ServiceProvider.CreateScope(); - - // Prepare zip file - var memoryStream = new MemoryStream(); - var zip = new ZipArchive(memoryStream, ZipArchiveMode.Create, true); - - // Add current log - // We need to open the file this way because we need to specify the access and share mode directly - // in order to read from a file which is currently written to - var fs = File.Open(LogPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - var sr = new StreamReader(fs); - var log = await sr.ReadToEndAsync(); - sr.Close(); - fs.Close(); - - await zip.AddFromText("log.txt", log); - - // 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 configJson = ConfigService.GetDiagnosticJson(); - await zip.AddFromText("config.json", configJson); - - // Make a list of plugins - var pluginService = scope.ServiceProvider.GetRequiredService(); - var plugins = await pluginService.GetLoadedPlugins(); - var pluginList = "Installed plugins:\n"; - - foreach (var plugin in plugins) - { - 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(); - var data = memoryStream.ToArray(); - - return data; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/PluginService.cs b/Moonlight/Core/Services/PluginService.cs deleted file mode 100644 index a4334bf..0000000 --- a/Moonlight/Core/Services/PluginService.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System.Reflection; -using MoonCore.Helpers; -using Moonlight.Core.Plugins; -using Moonlight.Core.Plugins.Contexts; -using Moonlight.Features.ServiceManagement.Models.Abstractions; - -namespace Moonlight.Core.Services; - -public class PluginService -{ - private readonly List Plugins = new(); - - public async Task Load(WebApplicationBuilder webApplicationBuilder) - { - var path = PathBuilder.Dir("storage", "plugins"); - Directory.CreateDirectory(path); - - var files = FindFiles(path) - .Where(x => x.EndsWith(".dll")) - .ToArray(); - - foreach (var file in files) - { - try - { - var assembly = Assembly.LoadFile(PathBuilder.File(Directory.GetCurrentDirectory(), file)); - - int plugins = 0; - foreach (var type in assembly.GetTypes()) - { - if (type.IsSubclassOf(typeof(MoonlightPlugin))) - { - try - { - var plugin = (Activator.CreateInstance(type) as MoonlightPlugin)!; - - // Create environment - plugin.Context = new PluginContext() - { - Services = webApplicationBuilder.Services, - WebApplicationBuilder = webApplicationBuilder - }; - - try - { - await plugin.Enable(); - - // After here we can treat the plugin as successfully loaded - plugins++; - Plugins.Add(plugin); - } - catch (Exception e) - { - Logger.Fatal($"Unhandled exception while enabling plugin '{type.Name}'"); - Logger.Fatal(e); - } - } - catch (Exception e) - { - Logger.Fatal($"Failed to create plugin environment for '{type.Name}'"); - Logger.Fatal(e); - } - } - } - - if(plugins == 0) // If 0, we can assume that it was a library dll - Logger.Info($"Loaded {file} as a library"); - else - Logger.Info($"Loaded {plugins} plugin(s) from {file}"); - } - catch (Exception e) - { - Logger.Fatal($"Unable to load assembly from file '{file}'"); - Logger.Fatal(e); - } - } - - Logger.Info($"Loaded {Plugins.Count} plugin(s)"); - } - - public Task GetLoadedPlugins() => Task.FromResult(Plugins.ToArray()); - - public async Task RunPreInit() - { - foreach (var plugin in Plugins) - { - Logger.Info($"Running pre init tasks for {plugin.GetType().Name}"); - - foreach (var preInitTask in plugin.Context.PreInitTasks) - await Task.Run(preInitTask); - } - } - - public async Task RunPrePost(WebApplication webApplication) - { - foreach (var plugin in Plugins) - { - // Pass through the dependency injection - var scope = webApplication.Services.CreateScope(); - plugin.Context.Provider = scope.ServiceProvider; - plugin.Context.Scope = scope; - plugin.Context.WebApplication = webApplication; - - Logger.Info($"Running post init tasks for {plugin.GetType().Name}"); - - foreach (var postInitTask in plugin.Context.PostInitTasks) - await Task.Run(postInitTask); - } - } - - public Task BuildUserServiceView(ServiceViewContext context) - { - foreach (var plugin in Plugins) - { - plugin.Context.BuildUserServiceView?.Invoke(context); - } - - return Task.CompletedTask; - } - - public Task BuildAdminServiceView(ServiceViewContext context) - { - foreach (var plugin in Plugins) - { - plugin.Context.BuildAdminServiceView?.Invoke(context); - } - - return Task.CompletedTask; - } - - private string[] FindFiles(string dir) - { - var result = new List(); - - foreach (var file in Directory.GetFiles(dir)) - result.Add(file); - - foreach (var directory in Directory.GetDirectories(dir)) - { - result.AddRange(FindFiles(directory)); - } - - return result.ToArray(); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/SessionService.cs b/Moonlight/Core/Services/SessionService.cs deleted file mode 100644 index c66452d..0000000 --- a/Moonlight/Core/Services/SessionService.cs +++ /dev/null @@ -1,40 +0,0 @@ -using MoonCore.Attributes; -using Moonlight.Core.Models.Abstractions; - -namespace Moonlight.Core.Services; - -[Singleton] -public class SessionService -{ - private readonly List AllSessions = new(); - - public Session[] Sessions => GetSessions(); - - public Task Register(Session session) - { - lock (AllSessions) - { - AllSessions.Add(session); - } - - return Task.CompletedTask; - } - - public Task Unregister(Session session) - { - lock (AllSessions) - { - AllSessions.Remove(session); - } - - return Task.CompletedTask; - } - - public Session[] GetSessions() - { - lock (AllSessions) - { - return AllSessions.ToArray(); - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Users/UserAuthService.cs b/Moonlight/Core/Services/Users/UserAuthService.cs deleted file mode 100644 index f5034e9..0000000 --- a/Moonlight/Core/Services/Users/UserAuthService.cs +++ /dev/null @@ -1,134 +0,0 @@ -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.Extensions; -using Moonlight.Core.Models.Abstractions; -using Moonlight.Core.Models.Enums; -using Moonlight.Core.Models.Templates; -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 MailService MailService; - - public UserAuthService( - Repository userRepository, - JwtService jwtService, - ConfigService configService, - MailService mailService) - { - UserRepository = userRepository; - JwtService = jwtService; - ConfigService = configService; - MailService = mailService; - } - - public async Task Register(string username, string email, string password) - { - // Event though we have form validation i want to - // ensure that at least these basic formatting things are done - email = email.ToLower().Trim(); - username = username.ToLower().Trim(); - - // Prevent duplication or username and/or email - if (UserRepository.Get().Any(x => x.Email == email)) - throw new DisplayException("A user with that email does already exist"); - - if (UserRepository.Get().Any(x => x.Username == username)) - throw new DisplayException("A user with that username does already exist"); - - var user = new User() - { - Username = username, - Email = email, - Password = HashHelper.HashToString(password) - }; - - var result = UserRepository.Add(user); - - await Events.OnUserRegistered.InvokeAsync(result); - - return result; - } - - public async Task ChangePassword(User user, string newPassword) - { - user.Password = HashHelper.HashToString(newPassword); - user.TokenValidTimestamp = DateTime.UtcNow; - UserRepository.Update(user); - - await Events.OnUserPasswordChanged.InvokeAsync(user); - } - - public Task SeedTotp(User user) - { - var key = Base32Encoding.ToString(KeyGeneration.GenerateRandomKey(20)); - - user.TotpKey = key; - UserRepository.Update(user); - - return Task.CompletedTask; - } - - public async Task SetTotp(User user, bool state) - { - // Access to flags without identity service - var flags = new FlagStorage(user.Flags); - flags[UserFlag.TotpEnabled] = state; - user.Flags = flags.RawFlagString; - - if (!state) - user.TotpKey = null; - - UserRepository.Update(user); - - await Events.OnUserTotpSet.InvokeAsync(user); - } - - // Mails - - public async Task SendVerification(User user) - { - 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() - { - Url = ConfigService.Get().AppUrl + "/api/auth/verify?token=" + jwt - }); - } - - public async Task SendResetPassword(string email) - { - var user = UserRepository - .Get() - .FirstOrDefault(x => x.Email == email); - - 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()); - }, "PasswordReset", TimeSpan.FromHours(1)); - - await MailService.Send(user, "Password reset for your account", "passwordReset", user, new ResetPassword() - { - Url = ConfigService.Get().AppUrl + "/api/auth/reset?token=" + jwt - }); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Users/UserDeleteService.cs b/Moonlight/Core/Services/Users/UserDeleteService.cs deleted file mode 100644 index 502a8aa..0000000 --- a/Moonlight/Core/Services/Users/UserDeleteService.cs +++ /dev/null @@ -1,173 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using Moonlight.Core.Database.Entities; - -using Moonlight.Features.Community.Entities; -using Moonlight.Features.Community.Services; -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.ServiceManagement.Services; -using Moonlight.Features.StoreSystem.Entities; -using Moonlight.Features.Ticketing.Entities; - -namespace Moonlight.Core.Services.Users; - -[Scoped] -public class UserDeleteService -{ - private readonly Repository ServiceRepository; - private readonly Repository ServiceShareRepository; - private readonly Repository PostRepository; - private readonly Repository UserRepository; - private readonly Repository TransactionRepository; - private readonly Repository CouponUseRepository; - private readonly Repository GiftCodeUseRepository; - private readonly Repository TicketRepository; - private readonly Repository TicketMessageRepository; - private readonly ServiceService ServiceService; - private readonly PostService PostService; - - public UserDeleteService( - Repository serviceRepository, - ServiceService serviceService, - PostService postService, - Repository postRepository, - Repository userRepository, - Repository giftCodeUseRepository, - Repository couponUseRepository, - Repository transactionRepository, - Repository ticketRepository, - Repository ticketMessageRepository, - Repository serviceShareRepository) - { - ServiceRepository = serviceRepository; - ServiceService = serviceService; - PostService = postService; - PostRepository = postRepository; - UserRepository = userRepository; - GiftCodeUseRepository = giftCodeUseRepository; - CouponUseRepository = couponUseRepository; - TransactionRepository = transactionRepository; - TicketRepository = ticketRepository; - TicketMessageRepository = ticketMessageRepository; - ServiceShareRepository = serviceShareRepository; - } - - public async Task Perform(User user) - { - // Community - - // - Posts - foreach (var post in PostRepository.Get().ToArray()) - { - await PostService.Delete(post); - } - - // - Comments - var posts = PostRepository - .Get() - .Where(x => x.Comments.Any(y => y.Author.Id == user.Id)) - .ToArray(); - - foreach (var post in posts) - { - var comments = PostRepository - .Get() - .Include(x => x.Comments) - .ThenInclude(x => x.Author) - .First(x => x.Id == post.Id) - .Comments - .Where(x => x.Author.Id == user.Id) - .ToArray(); - - foreach (var comment in comments) - await PostService.DeleteComment(post, comment); - } - - // Services - foreach (var service in ServiceRepository.Get().Where(x => x.Owner.Id == user.Id).ToArray()) - { - await ServiceService.Admin.Delete(service); - } - - // Service shares - var shares = ServiceShareRepository - .Get() - .Where(x => x.User.Id == user.Id) - .ToArray(); - - foreach (var share in shares) - { - ServiceShareRepository.Delete(share); - } - - // Transactions - Coupons - Gift codes - var userWithDetails = UserRepository - .Get() - .Include(x => x.Transactions) - .Include(x => x.CouponUses) - .Include(x => x.GiftCodeUses) - .First(x => x.Id == user.Id); - - var giftCodeUses = userWithDetails.GiftCodeUses.ToArray(); - var couponUses = userWithDetails.CouponUses.ToArray(); - var transactions = userWithDetails.Transactions.ToArray(); - - userWithDetails.GiftCodeUses.Clear(); - userWithDetails.CouponUses.Clear(); - userWithDetails.Transactions.Clear(); - - UserRepository.Update(userWithDetails); - - foreach (var giftCodeUse in giftCodeUses) - GiftCodeUseRepository.Delete(giftCodeUse); - - foreach (var couponUse in couponUses) - CouponUseRepository.Delete(couponUse); - - foreach (var transaction in transactions) - TransactionRepository.Delete(transaction); - - // Tickets and ticket messages - - // First we need to fetch every message this user has sent and delete it as admin accounts can have messages - // in tickets they dont own - var messagesFromUser = TicketMessageRepository - .Get() - .Where(x => x.Sender.Id == user.Id) - .ToArray(); - - foreach (var message in messagesFromUser) - { - TicketMessageRepository.Delete(message); - } - - // Now we can only delete the tickets the user actually owns - var tickets = TicketRepository - .Get() - .Include(x => x.Messages) - .Where(x => x.Creator.Id == user.Id) - .ToArray(); - - foreach (var ticket in tickets) - { - var messages = ticket.Messages.ToArray(); // Cache message models - - ticket.Messages.Clear(); - TicketRepository.Update(ticket); - - foreach (var ticketMessage in messages) - { - TicketMessageRepository.Delete(ticketMessage); - } - - TicketRepository.Delete(ticket); - } - - // User - - // We need to use this in order to entity framework not crashing because of the previous deleted data - var userToDelete = UserRepository.Get().First(x => x.Id == user.Id); - UserRepository.Delete(userToDelete); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Users/UserDetailsService.cs b/Moonlight/Core/Services/Users/UserDetailsService.cs deleted file mode 100644 index 1d56c1b..0000000 --- a/Moonlight/Core/Services/Users/UserDetailsService.cs +++ /dev/null @@ -1,43 +0,0 @@ -using MoonCore.Abstractions; -using MoonCore.Attributes; -using Moonlight.Core.Database.Entities; - - -namespace Moonlight.Core.Services.Users; - -[Scoped] -public class UserDetailsService -{ - private readonly BucketService BucketService; - private readonly Repository UserRepository; - - public UserDetailsService(BucketService bucketService, Repository userRepository) - { - BucketService = bucketService; - UserRepository = userRepository; - } - - public async Task UpdateAvatar(User user, Stream stream, string fileName) - { - if (user.Avatar != null) - { - await BucketService.Delete("avatars", user.Avatar, true); - } - - var file = await BucketService.Store("avatars", stream, fileName); - - user.Avatar = file; - UserRepository.Update(user); - } - - public async Task UpdateAvatar(User user) // Overload to reset avatar - { - if (user.Avatar != null) - { - await BucketService.Delete("avatars", user.Avatar, true); - } - - user.Avatar = null; - UserRepository.Update(user); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Users/UserService.cs b/Moonlight/Core/Services/Users/UserService.cs deleted file mode 100644 index dc54a9f..0000000 --- a/Moonlight/Core/Services/Users/UserService.cs +++ /dev/null @@ -1,47 +0,0 @@ -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; - private readonly IServiceProvider ServiceProvider; - - public UserAuthService Auth => ServiceProvider.GetRequiredService(); - public UserDetailsService Details => ServiceProvider.GetRequiredService(); - public UserDeleteService Delete => ServiceProvider.GetRequiredService(); - - public UserService( - Repository userRepository, - IServiceProvider serviceProvider) - { - UserRepository = userRepository; - ServiceProvider = serviceProvider; - } - - public Task Update(User user, string username, string email) - { - // Event though we have form validation i want to - // ensure that at least these basic formatting things are done - email = email.ToLower().Trim(); - username = username.ToLower().Trim(); - - // Prevent duplication or username and/or email - if (UserRepository.Get().Any(x => x.Email == email && x.Id != user.Id)) - throw new DisplayException("A user with that email does already exist"); - - if (UserRepository.Get().Any(x => x.Username == username && x.Id != user.Id)) - throw new DisplayException("A user with that username does already exist"); - - user.Username = username; - user.Email = email; - - UserRepository.Update(user); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Utils/ConnectionService.cs b/Moonlight/Core/Services/Utils/ConnectionService.cs deleted file mode 100644 index 3888cd6..0000000 --- a/Moonlight/Core/Services/Utils/ConnectionService.cs +++ /dev/null @@ -1,38 +0,0 @@ -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; - - public ConnectionService(IHttpContextAccessor contextAccessor, ConfigService configService) - { - ContextAccessor = contextAccessor; - ConfigService = configService; - } - - public Task GetIpAddress() - { - if (ContextAccessor.HttpContext == null) - return Task.FromResult("N/A (Missing http context)"); - - var request = ContextAccessor.HttpContext.Request; - - if (request.Headers.ContainsKey("X-Real-IP")) - { - if(ConfigService.Get().Security.EnableReverseProxyMode) - return Task.FromResult(request.Headers["X-Real-IP"].ToString()); - - Logger.Warn($"Detected an ip mask attempt by using a fake X-Real-IP header. Fake IP: {request.Headers["X-Real-IP"]}. Real IP: {ContextAccessor.HttpContext.Connection.RemoteIpAddress}"); - return Task.FromResult(ContextAccessor.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "N/A (Remote IP missing)"); - } - - return Task.FromResult(ContextAccessor.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "N/A (Remote IP missing)"); - } -} \ No newline at end of file diff --git a/Moonlight/Core/Services/Utils/JwtService.cs b/Moonlight/Core/Services/Utils/JwtService.cs deleted file mode 100644 index 8298cef..0000000 --- a/Moonlight/Core/Services/Utils/JwtService.cs +++ /dev/null @@ -1,123 +0,0 @@ -using JWT.Algorithms; -using JWT.Builder; -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 TimeSpan DefaultDuration = TimeSpan.FromDays(365 * 10); - - public JwtService(ConfigService configService) - { - ConfigService = configService; - } - - 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()); - - var dataDic = new Dictionary(); - data.Invoke(dataDic); - - foreach (var entry in dataDic) - builder = builder.AddClaim(entry.Key, entry.Value); - - var jwt = builder.Encode(); - - return Task.FromResult(jwt); - } - - 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); - - 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) - { - Logger.Warn(e.Message); - return Task.FromResult(false); - } - } - - public Task> Decode(string token) - { - try - { - var json = new JwtBuilder() - .WithSecret(ConfigService.Get().Security.Token) - .WithAlgorithm(new HMACSHA512Algorithm()) - .MustVerifySignature() - .Decode(token); - - var data = JsonConvert.DeserializeObject>(json); - - return Task.FromResult(data)!; - } - 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!); - } - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Alerts/NotFoundAlert.razor b/Moonlight/Core/UI/Components/Alerts/NotFoundAlert.razor deleted file mode 100644 index 9f34dc1..0000000 --- a/Moonlight/Core/UI/Components/Alerts/NotFoundAlert.razor +++ /dev/null @@ -1,33 +0,0 @@ -
-
-
-
- Not found illustration -
-

- The requested resource was not found -

-
- We were not able to find the requested resource. This can have following reasons - -
-
  • - The resource was deleted -
  • -
  • - You have no permission to access this resource -
  • -
  • - You may have entered invalid data -
  • -
  • - A unknown bug occured -
  • -
  • - An api was offline and not proper handled -
  • -
    -
    -
    -
    -
    \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Alerts/RestartAlert.razor b/Moonlight/Core/UI/Components/Alerts/RestartAlert.razor deleted file mode 100644 index 5db8a7f..0000000 --- a/Moonlight/Core/UI/Components/Alerts/RestartAlert.razor +++ /dev/null @@ -1,16 +0,0 @@ -
    -
    -
    -

    - Restarting -

    -
    - The panel is restarting. This may take a moment -
    -
    - -
    - Reconnect -
    -
    -
    \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Auth/ChangePassword.razor b/Moonlight/Core/UI/Components/Auth/ChangePassword.razor deleted file mode 100644 index dbc3369..0000000 --- a/Moonlight/Core/UI/Components/Auth/ChangePassword.razor +++ /dev/null @@ -1,67 +0,0 @@ -@using Moonlight.Core.Models.Forms -@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 - -
    -
    -
    -

    - Change your password -

    -
    - You need to change your password in order to continue -
    -
    - - -
    - -
    - -
    - -
    - -
    - -
    -
    -
    -
    - -@code -{ - private UpdateAccountPasswordForm Form = new(); - - private async Task OnValidSubmit() - { - if (Form.Password != Form.RepeatedPassword) - throw new DisplayException("The password do not match"); - - // Because of UserService.Auth.ChangePassword may logout the user before we can reset the flag - // we reset the flag before changing the password and if any error occurs we simple set it again - - try - { - IdentityService.Flags[UserFlag.PasswordPending] = false; - await IdentityService.SaveFlags(); - - await UserService.Auth.ChangePassword(IdentityService.CurrentUser, Form.Password); - } - catch (Exception) - { - IdentityService.Flags[UserFlag.PasswordPending] = true; - await IdentityService.SaveFlags(); - - throw; - } - - await IdentityService.Authenticate(); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Auth/Login.razor b/Moonlight/Core/UI/Components/Auth/Login.razor deleted file mode 100644 index 67512de..0000000 --- a/Moonlight/Core/UI/Components/Auth/Login.razor +++ /dev/null @@ -1,81 +0,0 @@ -@page "/login" -@* Virtual route to trick blazor *@ -@using Moonlight.Core.Models.Forms -@using Moonlight.Core.Models.Forms.Auth -@using Moonlight.Core.Services -@using MoonCoreUI.Services - -@inject IdentityService IdentityService -@inject CookieService CookieService -@inject NavigationManager Navigation - -
    -
    -
    -

    - Sign In -

    -
    - Change me -
    -
    - - -
    - -
    - -
    - -
    - - - -
    - -
    -
    Or
    - @* OAuth2 Providers here *@ -
    -
    -
    -
    -
    - -@code -{ - private LoginForm Form = new(); - - // 2FA - private bool Require2FA = false; - private string TwoFactorCode = ""; - - private async Task OnValidSubmit() - { - string token; - - try - { - token = await IdentityService.Login(Form.Email, Form.Password, TwoFactorCode); - } - catch (ArgumentNullException) // IdentityService requires two factor code => show field - { - Require2FA = true; - await InvokeAsync(StateHasChanged); - return; - } - - await CookieService.SetValue("token", token); - await IdentityService.Authenticate(token); - - if (Navigation.Uri.EndsWith("/login")) - Navigation.NavigateTo("/"); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Auth/MailVerify.razor b/Moonlight/Core/UI/Components/Auth/MailVerify.razor deleted file mode 100644 index cf5ddf6..0000000 --- a/Moonlight/Core/UI/Components/Auth/MailVerify.razor +++ /dev/null @@ -1,45 +0,0 @@ -@using Moonlight.Core.Services.Users -@using Moonlight.Core.Services -@inject UserService UserService -@inject IdentityService IdentityService - -
    -
    - @if (HasBeenSend) - { -
    -

    - Email verification sent -

    -
    - You should receive an email shortly. If you see no email in your inbox, look inside your spam folder -
    -
    - } - else - { -
    -

    - Verify your email address -

    -
    - We will sent you an email to verify your account -
    -
    - - - } -
    -
    - -@code -{ - private bool HasBeenSend = false; - - private async Task Send() - { - await UserService.Auth.SendVerification(IdentityService.CurrentUser); - HasBeenSend = true; - await InvokeAsync(StateHasChanged); - } -} diff --git a/Moonlight/Core/UI/Components/Auth/PasswordReset.razor b/Moonlight/Core/UI/Components/Auth/PasswordReset.razor deleted file mode 100644 index f842c47..0000000 --- a/Moonlight/Core/UI/Components/Auth/PasswordReset.razor +++ /dev/null @@ -1,56 +0,0 @@ -@page "/password-reset" -@using Moonlight.Core.Models.Forms -@using Moonlight.Core.Models.Forms.Auth -@using Moonlight.Core.Services.Users - -@inject UserService UserService - -
    -
    - @if (HasBeenSend) - { -
    -

    - Password reset email sent -

    -
    - You should receive the email shortly. If you see no email in your inbox, look inside your spam folder -
    -
    - } - else - { -
    -

    - Reset your password -

    -
    - We will sent you an email to reset your account password -
    -
    - - -
    - -
    - -
    - -
    -
    - } -
    -
    - -@code -{ - private bool HasBeenSend = false; - private ResetPasswordForm Form = new(); - - private async Task OnValidSubmit() - { - await UserService.Auth.SendResetPassword(Form.Email); - HasBeenSend = true; - await InvokeAsync(StateHasChanged); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Auth/Register.razor b/Moonlight/Core/UI/Components/Auth/Register.razor deleted file mode 100644 index 3a1b28a..0000000 --- a/Moonlight/Core/UI/Components/Auth/Register.razor +++ /dev/null @@ -1,79 +0,0 @@ -@page "/register" -@* Virtual route to trick blazor *@ -@using Moonlight.Core.Models.Forms -@using Moonlight.Core.Models.Forms.Auth -@using Moonlight.Core.Services -@using Moonlight.Core.Services.Users -@using MoonCore.Exceptions -@using MoonCoreUI.Services - -@inject IdentityService IdentityService -@inject UserService UserService -@inject CookieService CookieService -@inject NavigationManager Navigation - -
    -
    -
    -

    - Sign Up -

    -
    - change me -
    -
    - - -
    - -
    - -
    - -
    - -
    - -
    - -
    - -
    - - - -
    - -
    -
    Or
    - @* OAuth2 Providers here *@ -
    -
    -
    -
    -
    - -@code -{ - private RegisterForm Form = new(); - - private async Task OnValidSubmit() - { - if (Form.Password != Form.RepeatedPassword) - throw new DisplayException("The passwords do not match"); - - var user = await UserService.Auth.Register(Form.Username, Form.Email, Form.Password); - var token = await IdentityService.GenerateToken(user); - - await CookieService.SetValue("token", token); - await IdentityService.Authenticate(token); - - if (Navigation.Uri.EndsWith("/register")) - Navigation.NavigateTo("/"); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Forms/TextEditor.razor b/Moonlight/Core/UI/Components/Forms/TextEditor.razor deleted file mode 100644 index c5fa92a..0000000 --- a/Moonlight/Core/UI/Components/Forms/TextEditor.razor +++ /dev/null @@ -1,176 +0,0 @@ -@inject IJSRuntime JsRuntime -@using Microsoft.AspNetCore.Components.Forms -@using Ganss.Xss -@using MoonCore.Helpers -@using Moonlight.Core.Services -@inherits InputBase - -@inject IdentityService IdentityService - - - -
    - -@code -{ - [Parameter] - public string InitialContent { get; set; } - - [Parameter] - public string CssClasses { get; set; } = ""; - - [Parameter] - public string Styles { get; set; } = ""; // We added this parameter to allow custom heights to be set - - private string Id; - private bool IsInitialized = false; - - protected override void OnInitialized() - { - Id = "editor" + GetHashCode(); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await JsRuntime.InvokeVoidAsync("moonlight.textEditor.create", Id); - await JsRuntime.InvokeVoidAsync("moonlight.textEditor.set", Id, InitialContent); - CurrentValue = InitialContent; - IsInitialized = true; - } - } - - private async Task Callback() - { - if(!IsInitialized) - return; - - var html = await JsRuntime.InvokeAsync("moonlight.textEditor.get", Id); - - var sanitizer = new HtmlSanitizer(); - var sanitized = sanitizer.Sanitize(html); - - if(sanitized != html) - Logger.Warn($"XSS attempt by {IdentityService.CurrentUserNullable?.Username ?? "Guest"}: {html}", "security"); - - CurrentValue = sanitized; - } - - protected override bool TryParseValueFromString(string? value, out string result, out string? validationErrorMessage) - { - result = value; - validationErrorMessage = ""; - return true; - } -} diff --git a/Moonlight/Core/UI/Components/Navigations/AccountNavigation.razor b/Moonlight/Core/UI/Components/Navigations/AccountNavigation.razor deleted file mode 100644 index d3ed097..0000000 --- a/Moonlight/Core/UI/Components/Navigations/AccountNavigation.razor +++ /dev/null @@ -1,27 +0,0 @@ - - -@code -{ - [Parameter] - public int Index { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Navigations/AdminSysNavigation.razor b/Moonlight/Core/UI/Components/Navigations/AdminSysNavigation.razor deleted file mode 100644 index 9913f81..0000000 --- a/Moonlight/Core/UI/Components/Navigations/AdminSysNavigation.razor +++ /dev/null @@ -1,31 +0,0 @@ - - -@code -{ - [Parameter] public int Index { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Navigations/AdminUsersNavigation.razor b/Moonlight/Core/UI/Components/Navigations/AdminUsersNavigation.razor deleted file mode 100644 index 7fe0445..0000000 --- a/Moonlight/Core/UI/Components/Navigations/AdminUsersNavigation.razor +++ /dev/null @@ -1,22 +0,0 @@ -
    - -
    - -@code -{ - [Parameter] - public int Index { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Partials/ConnectionIndicator.razor b/Moonlight/Core/UI/Components/Partials/ConnectionIndicator.razor deleted file mode 100644 index 12f6f1c..0000000 --- a/Moonlight/Core/UI/Components/Partials/ConnectionIndicator.razor +++ /dev/null @@ -1,24 +0,0 @@ -
    -
    - -
    -
    - -
    - - -
    \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Partials/PageHeader.razor b/Moonlight/Core/UI/Components/Partials/PageHeader.razor deleted file mode 100644 index 21af2b7..0000000 --- a/Moonlight/Core/UI/Components/Partials/PageHeader.razor +++ /dev/null @@ -1,104 +0,0 @@ -@using Moonlight.Core.Services -@using Moonlight.Core.UI.Layouts -@using Moonlight.Core.Configuration -@using MoonCore.Services -@using MoonCoreUI.Services - -@inject IdentityService IdentityService -@inject ConfigService ConfigService -@inject CookieService CookieService - -
    -
    - -
    -
    -
    - -
    - -
    - -
    - - -
    -
    -
    - - -
    - -@code -{ - [CascadingParameter] - public DefaultLayout Layout { get; set; } - - private async Task Logout() - { - await IdentityService.Authenticate(""); - await CookieService.SetValue("token", ""); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Partials/PermissionChecker.razor b/Moonlight/Core/UI/Components/Partials/PermissionChecker.razor deleted file mode 100644 index 7b366f6..0000000 --- a/Moonlight/Core/UI/Components/Partials/PermissionChecker.razor +++ /dev/null @@ -1,63 +0,0 @@ -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Abstractions -@using Moonlight.Core.Services -@inject IdentityService IdentityService - -@if (Allowed) -{ - @ChildContent -} -else -{ -

    Ha, nein ;)

    -} - -@code -{ - [CascadingParameter(Name = "TargetPageType")] - public Type? TargetPageType { get; set; } - - [Parameter] - public RenderFragment ChildContent { get; set; } - - private bool Allowed = false; - - protected override Task OnParametersSetAsync() - { - if(TargetPageType == null) - return Task.CompletedTask; - - var attributes = TargetPageType.GetCustomAttributes(true); - var permAttrs = attributes - .Where(x => x.GetType() == typeof(RequirePermissionAttribute)) - .Select(x => x as RequirePermissionAttribute) - .ToArray(); - - Allowed = true; - - if (permAttrs.Any()) - { - Allowed = false; - - foreach (var permissionRequired in permAttrs) - { - if(permissionRequired == null) - continue; - - var permission = PermissionStorage.GetFromInteger(permissionRequired.PermissionInteger); - - if (IdentityService.Permissions[permission]) - { - Allowed = true; - } - } - } - - if (!Allowed) - { - //Logger.Warn($"{IdentityService.Ip} has tried to access {NavigationManager.Uri} without permission", "security"); - } - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Partials/Route.razor b/Moonlight/Core/UI/Components/Partials/Route.razor deleted file mode 100644 index d5a05e8..0000000 --- a/Moonlight/Core/UI/Components/Partials/Route.razor +++ /dev/null @@ -1,20 +0,0 @@ -@{ - var route = "/" + (Router.Route ?? ""); -} - -@if (route == Path) -{ - @ChildContent -} - -@code -{ - [CascadingParameter] - public SmartRouter Router { get; set; } - - [Parameter] - public RenderFragment ChildContent { get; set; } - - [Parameter] - public string Path { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Partials/Sidebar.razor b/Moonlight/Core/UI/Components/Partials/Sidebar.razor deleted file mode 100644 index 0de0e34..0000000 --- a/Moonlight/Core/UI/Components/Partials/Sidebar.razor +++ /dev/null @@ -1,162 +0,0 @@ -@using Moonlight.Core.Services -@using Moonlight.Core.Models.Enums -@using Moonlight.Core.UI.Layouts - -@inject IdentityService IdentityService - - - -@code -{ - [CascadingParameter] - public DefaultLayout Layout { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Partials/SmartRouter.razor b/Moonlight/Core/UI/Components/Partials/SmartRouter.razor deleted file mode 100644 index 2b151d6..0000000 --- a/Moonlight/Core/UI/Components/Partials/SmartRouter.razor +++ /dev/null @@ -1,12 +0,0 @@ - - @ChildContent - - -@code -{ - [Parameter] - public string? Route { get; set; } - - [Parameter] - public RenderFragment ChildContent { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor b/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor deleted file mode 100644 index 4e6f328..0000000 --- a/Moonlight/Core/UI/Components/Partials/SoftErrorHandler.razor +++ /dev/null @@ -1,79 +0,0 @@ -@using System.Diagnostics -@using MoonCore.Exceptions -@using MoonCore.Helpers -@using Moonlight.Core.Models.Enums -@using Moonlight.Core.Services - -@inherits ErrorBoundaryBase -@inject IdentityService IdentityService - -@if (Crashed) -{ - if (Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Development" || IdentityService.Permissions[Permission.AdminViewExceptions]) - { - if (Exception != null) - { -
    -
    - An unhandled exception occured -
    -
    - @(Formatter.FormatLineBreaks(Exception.ToStringDemystified())) -
    -
    - } - } - else - { -

    Crashed lol :c

    - } -} -else -{ - if (ErrorMessages.Any()) - { - foreach (var errorMessage in ErrorMessages) - { -
    - @errorMessage -
    - } - } - - @ChildContent -} - -@code -{ - private bool Crashed = false; - private List ErrorMessages = new(); - private Exception? Exception; - - protected override Task OnErrorAsync(Exception exception) - { - if (exception is DisplayException displayException) - { - ErrorMessages.Add(displayException.Message); - - Task.Run(async () => - { - await Task.Delay(TimeSpan.FromSeconds(5)); - ErrorMessages.Remove(displayException.Message); - await InvokeAsync(StateHasChanged); - }); - } - else - { - Exception = exception; - Crashed = true; - - var username = IdentityService.IsSignedIn ? IdentityService.CurrentUser.Username : "Guest"; - Logger.Warn($"A crash occured in the view of the user '{username}'"); - Logger.Warn(exception); - } - - Recover(); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Components/Partials/Tooltip.razor b/Moonlight/Core/UI/Components/Partials/Tooltip.razor deleted file mode 100644 index f73df5c..0000000 --- a/Moonlight/Core/UI/Components/Partials/Tooltip.razor +++ /dev/null @@ -1,11 +0,0 @@ -
    - @ChildContent -
    - -@code -{ - [Parameter] - public RenderFragment ChildContent { get; set; } - - [Parameter] public string Color { get; set; } = "primary"; -} diff --git a/Moonlight/Core/UI/Layouts/DefaultLayout.razor b/Moonlight/Core/UI/Layouts/DefaultLayout.razor deleted file mode 100644 index 5dd77c0..0000000 --- a/Moonlight/Core/UI/Layouts/DefaultLayout.razor +++ /dev/null @@ -1,39 +0,0 @@ -@using Moonlight.Features.Ticketing.UI.Components - -
    -
    - - -
    - -
    -
    -
    - @ChildContent - - -
    -
    -
    -
    -
    -
    -
    - -@if (ShowMobileSidebar) -{ -
    -} - -@code -{ - [Parameter] - public RenderFragment ChildContent { get; set; } - public bool ShowMobileSidebar { get; set; } - - public async Task ToggleMobileSidebar() - { - ShowMobileSidebar = !ShowMobileSidebar; - await InvokeAsync(StateHasChanged); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Layouts/MainLayout.razor b/Moonlight/Core/UI/Layouts/MainLayout.razor deleted file mode 100644 index 0f8b830..0000000 --- a/Moonlight/Core/UI/Layouts/MainLayout.razor +++ /dev/null @@ -1,181 +0,0 @@ -@using Moonlight.Core.Models.Abstractions -@using Moonlight.Core.Models.Enums -@using Moonlight.Core.Services -@using Moonlight.Core.Services.Utils -@using Moonlight.Core.Event -@using Moonlight.Core.UI.Components.Auth -@using Moonlight.Features.Advertisement.Services -@using Moonlight.Features.Advertisement.UI.Components -@using MoonCoreUI.Services -@using MoonCore.Services -@using Moonlight.Core.Configuration - -@inherits LayoutComponentBase -@implements IDisposable - -@inject CookieService CookieService -@inject ConfigService ConfigService -@inject IdentityService IdentityService -@inject SessionService SessionService -@inject NavigationManager Navigation -@inject ConnectionService ConnectionService -@inject AdBlockService AdBlockService -@inject HotKeyService HotKeyService - -@{ - var url = new Uri(Navigation.Uri); -} - -@if (Initialized) -{ - if (IdentityService.IsSignedIn) - { - if (!IdentityService.Flags[UserFlag.MailVerified] && ConfigService.Get().Security.EnableEmailVerify) - { - - - - } - else if (IdentityService.Flags[UserFlag.PasswordPending]) - { - - - - } - else if (RestartLock) - { - - - - } - else if (ConfigService.Get().Advertisement.PreventAdBlockers && AdBlockerDetected) - { - - - - } - else - { - - - - @Body - - - - } - } - else - { - if (url.LocalPath == "/register") - { - - - - } - else if (url.LocalPath == "/password-reset") - { - - - - } - else - { - - - - } - } -} -else -{ - -
    -
    -
    -

    - Connecting to the remote server -

    -
    -
    -
    - Loading... -
    -
    -
    -
    -
    -
    -
    -} - -@code -{ - private bool Initialized = false; - private bool RestartLock = false; - private bool AdBlockerDetected = false; - - private Session? MySession; - - protected override void OnInitialized() - { - IdentityService.OnAuthenticationStateChanged += async (_, _) => - { - if (MySession != null) - { - MySession.User = IdentityService.CurrentUserNullable; - MySession.UpdatedAt = DateTime.UtcNow; - } - - await InvokeAsync(StateHasChanged); - }; - - Navigation.LocationChanged += (_, _) => - { - if (MySession != null) - { - MySession.Url = Navigation.Uri; - MySession.UpdatedAt = DateTime.UtcNow; - } - }; - - Events.OnMoonlightRestart += async (_, _) => - { - RestartLock = true; - await InvokeAsync(StateHasChanged); - }; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - var token = await CookieService.GetValue("token"); - await IdentityService.Authenticate(token); - - MySession = new() - { - Ip = await ConnectionService.GetIpAddress(), - Url = Navigation.Uri, - User = IdentityService.CurrentUserNullable - }; - - await SessionService.Register(MySession); - - if(ConfigService.Get().Advertisement.PreventAdBlockers) - AdBlockerDetected = await AdBlockService.Detect(); - - await HotKeyService.Initialize(); - - Initialized = true; - - await InvokeAsync(StateHasChanged); - } - } - - public async void Dispose() // This method will be called if the user closes his tab - { - if (MySession != null) - await SessionService.Unregister(MySession); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Layouts/OverlayLayout.razor b/Moonlight/Core/UI/Layouts/OverlayLayout.razor deleted file mode 100644 index bd7670f..0000000 --- a/Moonlight/Core/UI/Layouts/OverlayLayout.razor +++ /dev/null @@ -1,36 +0,0 @@ -@* disable any reconnect screens *@ - - - -
    -
    - - Logo - -
    -
    -
    -
    -
    - @ChildContent -
    -
    -
    -
    -
    -
    @* style="background-image: url()" add bg image here *@ -
    -
    -
    - -@code -{ - [Parameter] - public RenderFragment ChildContent { get; set; } -} diff --git a/Moonlight/Core/UI/Views/Account/Index.razor b/Moonlight/Core/UI/Views/Account/Index.razor deleted file mode 100644 index c105971..0000000 --- a/Moonlight/Core/UI/Views/Account/Index.razor +++ /dev/null @@ -1,136 +0,0 @@ -@page "/account" -@using Moonlight.Core.Models.Forms.Auth -@using Moonlight.Core.Services -@using Moonlight.Core.Services.Users -@using MoonCoreUI.Services -@using MoonCore.Helpers - -@inject IdentityService IdentityService -@inject UserService UserService -@inject ToastService ToastService - - - -
    -
    -
    -
    -
    -
    -
    - @if (IdentityService.CurrentUser.Avatar == null) - { - Avatar - } - else - { - Avatar - } -
    -
    -
    -
    - Your avatar -
    -
    - PNG or JPG no bigger than 1000px wide and tall -
    -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    - -
    -
    -
    - - -
    -
    - - -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - - - -@code -{ - private UpdateAccountForm Form = new(); - private SmartFileSelect SmartFileSelect; - - protected override void OnInitialized() - { - Form.Username = IdentityService.CurrentUser.Username; - Form.Email = IdentityService.CurrentUser.Email; - } - - private async Task OnSubmit() - { - await UserService.Update( - IdentityService.CurrentUser, - Form.Username, - Form.Email - ); - - await ToastService.Success("Successfully saved changes"); - } - - private async Task OnUpload() - { - // Validation - if (SmartFileSelect.SelectedFile == null) - return; - - if (!Formatter.EndsInOneOf(SmartFileSelect.SelectedFile.Name, new[] - { - ".jpg", - ".png" - })) - { - await ToastService.Danger("You are only allowed to upload JPG and PNG files"); - return; - } - - // Now, we are actually working - await UserService.Details.UpdateAvatar( - IdentityService.CurrentUser, - SmartFileSelect.SelectedFile.OpenReadStream(SmartFileSelect.MaxFileSize), - SmartFileSelect.SelectedFile.Name - ); - - // Reset - await SmartFileSelect.RemoveSelection(); - await InvokeAsync(StateHasChanged); - - await ToastService.Success("Successfully uploaded avatar"); - } - - private async Task OnDelete() - { - await UserService.Delete.Perform(IdentityService.CurrentUser); - await IdentityService.Authenticate(); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Account/Payments.razor b/Moonlight/Core/UI/Views/Account/Payments.razor deleted file mode 100644 index 13cfb2e..0000000 --- a/Moonlight/Core/UI/Views/Account/Payments.razor +++ /dev/null @@ -1,151 +0,0 @@ -@page "/account/payments" -@using BlazorTable -@using MoonCore.Exceptions -@using MoonCore.Helpers -@using MoonCore.Services -@using MoonCoreUI.Services -@using Moonlight.Core.Configuration -@using Moonlight.Core.Services -@using Moonlight.Features.StoreSystem.Entities -@using Moonlight.Features.StoreSystem.Models.Abstractions -@using Moonlight.Features.StoreSystem.Services - -@inject IdentityService IdentityService -@inject ConfigService ConfigService -@inject StoreService StoreService -@inject ToastService ToastService -@inject NavigationManager Navigation - - - -
    -
    -
    -
    -

    Redeem gift code

    -
    -
    -
    - - -
    -
    -
    -
    -
    -
    -
    - -
    -
    - @foreach (var gateway in StoreService.Payment.Gateways) - { - - } -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    -

    Transactions

    -
    -
    - - - - - - - - - - - - - -
    -
    -
    -
    - -@code -{ - private LazyLoader LazyLoader; - - private Transaction[] Transactions; - private string GiftCode = ""; - private double Amount = 0; - private PaymentGateway? SelectedGateway; - - private async Task Load(LazyLoader _) - { - Transactions = await IdentityService.GetTransactions(); - - Transactions = Transactions - .OrderByDescending(x => x.Id) - .ToArray(); - } - - private async Task RedeemGiftCode() - { - if (string.IsNullOrEmpty(GiftCode)) - return; - - await StoreService.Gift.Redeem(IdentityService.CurrentUser, GiftCode); - - // Reset - GiftCode = ""; - await InvokeAsync(StateHasChanged); - - await ToastService.Success("Successfully applied gift code"); - await LazyLoader.Reload(); - } - - private async Task SelectGateway(PaymentGateway gateway) - { - SelectedGateway = gateway; - await InvokeAsync(StateHasChanged); - } - - private async Task LaunchPayment() - { - if (SelectedGateway == null) - throw new DisplayException("You need to select a payment method"); - - var url = await SelectedGateway.Start(Amount); - Navigation.NavigateTo(url, true); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Account/Security.razor b/Moonlight/Core/UI/Views/Account/Security.razor deleted file mode 100644 index 7324b54..0000000 --- a/Moonlight/Core/UI/Views/Account/Security.razor +++ /dev/null @@ -1,173 +0,0 @@ -@page "/account/security" -@using OtpNet -@using QRCoder -@using Moonlight.Core.Models.Forms.Auth -@using Moonlight.Core.Services -@using Moonlight.Core.Services.Users -@using Moonlight.Core.Models.Enums -@using MoonCore.Exceptions -@using MoonCoreUI.Services - -@inject IdentityService IdentityService -@inject UserService UserService -@inject ToastService ToastService - - - -
    -
    -
    -
    - Change password -
    - -
    -
    -
    -
    - - -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    -
    -
    - @if (IdentityService.Flags[UserFlag.TotpEnabled]) - { -
    -
    - Your account is secured with 2fa -
    -
    - -
    - } - else if (!IdentityService.Flags[UserFlag.TotpEnabled] && IdentityService.CurrentUser.TotpKey != null) - { -
    -
    - Scan the qr code and enter the code generated by the app you have scanned it in -
    -
    - @{ - QRCodeGenerator qrGenerator = new QRCodeGenerator(); - - var qrCodeData = qrGenerator.CreateQrCode - ( - $"otpauth://totp/{Uri.EscapeDataString(IdentityService.CurrentUser.Email)}?secret={IdentityService.CurrentUser.TotpKey}&issuer={Uri.EscapeDataString("Moonlight")}", - QRCodeGenerator.ECCLevel.Q - ); - - PngByteQRCode qrCode = new PngByteQRCode(qrCodeData); - byte[] qrCodeAsPngByteArr = qrCode.GetGraphic(5); - var base64 = Convert.ToBase64String(qrCodeAsPngByteArr); - } -
    - QR Code -
    -
    - @(IdentityService.CurrentUser.TotpKey) -
    -
    - -
    - } - else - { -
    -
    - Secure your account using 2fa -
    -
    -

    - Make sure you have installed one of the following apps on your smartphone and continue -

    - - Google Authenticator -
    - Microsoft Authenticator -
    - Authy -
    - 1Password -
    -
    - -
    - } -
    -
    - -@code -{ - private UpdateAccountPasswordForm PasswordForm = new(); - private TwoFactorCodeForm CodeForm = new(); - - private async Task OnPasswordSubmit() - { - if (PasswordForm.Password != PasswordForm.RepeatedPassword) - throw new DisplayException("The passwords do not match"); - - await UserService.Auth.ChangePassword(IdentityService.CurrentUser, PasswordForm.Password); - await ToastService.Success("Successfully updated your password"); - await IdentityService.Authenticate(); - } - - private async Task OnDisable2FA() - { - await UserService.Auth.SetTotp(IdentityService.CurrentUser, false); - await IdentityService.Authenticate(); - await InvokeAsync(StateHasChanged); - } - - private async Task OnSeed2FA() - { - await UserService.Auth.SeedTotp(IdentityService.CurrentUser); - await IdentityService.Authenticate(); - await InvokeAsync(StateHasChanged); - } - - private async Task On2FASubmit() - { - var totp = new Totp(Base32Encoding.ToBytes(IdentityService.CurrentUser.TotpKey)); - var code = totp.ComputeTotp(); - - if (code != CodeForm.Code) - throw new DisplayException("The 2fa code you entered is invalid"); - - CodeForm = new(); - - await UserService.Auth.SetTotp(IdentityService.CurrentUser, true); - await IdentityService.Authenticate(); - await InvokeAsync(StateHasChanged); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Admin/Index.razor b/Moonlight/Core/UI/Views/Admin/Index.razor deleted file mode 100644 index 2000df3..0000000 --- a/Moonlight/Core/UI/Views/Admin/Index.razor +++ /dev/null @@ -1,5 +0,0 @@ -@page "/admin" -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - -@attribute [RequirePermission(Permission.AdminOverview)] \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Admin/Sys/Diagnose.razor b/Moonlight/Core/UI/Views/Admin/Sys/Diagnose.razor deleted file mode 100644 index d5b0da6..0000000 --- a/Moonlight/Core/UI/Views/Admin/Sys/Diagnose.razor +++ /dev/null @@ -1,35 +0,0 @@ -@page "/admin/sys/diagnose" -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums -@using Moonlight.Core.Services -@using MoonCoreUI.Services - -@attribute [RequirePermission(Permission.AdminRoot)] - -@inject MoonlightService MoonlightService -@inject FileDownloadService DownloadService - - - -
    -
    - - Dont share this file with random people. - We do our best to clear this file from sensitive information but it can still contain some. - Its safe to share with official moonlight panel developers - - -
    - -
    -
    -
    - -@code -{ - private async Task GenerateDiagnose() - { - var data = await MoonlightService.GenerateDiagnoseReport(); - await DownloadService.DownloadBytes("moonlight-diagnose.zip", data); - } -} diff --git a/Moonlight/Core/UI/Views/Admin/Sys/Index.razor b/Moonlight/Core/UI/Views/Admin/Sys/Index.razor deleted file mode 100644 index 37bfa4f..0000000 --- a/Moonlight/Core/UI/Views/Admin/Sys/Index.razor +++ /dev/null @@ -1,18 +0,0 @@ -@page "/admin/sys" -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums -@using Moonlight.Core.Services - -@attribute [RequirePermission(Permission.AdminRoot)] - -@inject MoonlightService MoonlightService - - - -
    -
    -
    - -
    -
    -
    \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Admin/Sys/Settings.razor b/Moonlight/Core/UI/Views/Admin/Sys/Settings.razor deleted file mode 100644 index 19159dc..0000000 --- a/Moonlight/Core/UI/Views/Admin/Sys/Settings.razor +++ /dev/null @@ -1,194 +0,0 @@ -@page "/admin/sys/settings" -@using System.Reflection -@using MoonCore.Services -@using MoonCoreUI.Helpers -@using MoonCoreUI.Services -@using Moonlight.Core.Configuration -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - -@attribute [RequirePermission(Permission.AdminRoot)] - -@inject ConfigService ConfigService -@inject ToastService ToastService - - - -@if (ModelToShow == null) -{ - -} -else -{ -
    -
    - @{ - string title; - - if (Path.Length == 0) - title = "Configuration"; - else - { - title = "Configuration - " + string.Join(" - ", Path); - } - } - -

    @(title)

    -
    - - - - - - -
    -
    -
    - - - Changes to these settings are live applied. The save button only make the changes persistently saved to disk - - -
    -
    -
    - @{ - var props = ModelToShow - .GetType() - .GetProperties() - .Where(x => x.PropertyType.Assembly.FullName!.Contains("Moonlight") && x.PropertyType.IsClass) - .ToArray(); - } - - @foreach (var prop in props) - { -
    - -
    - } - - @if (Path.Length != 0) - { -
    -
    - Back -
    -
    - } -
    -
    -
    -
    -
    - - @foreach (var prop in Properties) - { -
    - @{ - var typeToCreate = typeof(AutoProperty<>).MakeGenericType(prop.PropertyType); - var rf = ComponentHelper.FromType(typeToCreate, parameters => - { - parameters.Add("Data", ModelToShow); - parameters.Add("Property", prop); - }); - } - - @rf -
    - } -
    -
    -
    -
    -
    -} - -@code -{ - [Parameter] - [SupplyParameterFromQuery] - public string? Section { get; set; } = ""; - - private object? ModelToShow; - private PropertyInfo[] Properties = Array.Empty(); - private string[] Path = Array.Empty(); - - private LazyLoader? LazyLoader; - - protected override async Task OnParametersSetAsync() - { - if (Section != null && Section.StartsWith("/")) - Section = Section.TrimStart('/'); - - Path = Section != null ? Section.Split("/") : Array.Empty(); - - ModelToShow = Resolve(ConfigService.Get(), Path, 0); - - if (ModelToShow != null) - { - Properties = ModelToShow - .GetType() - .GetProperties() - .Where(x => !x.PropertyType.Assembly.FullName!.Contains("Moonlight")) - .ToArray(); - } - else - { - Properties = Array.Empty(); - } - - await InvokeAsync(StateHasChanged); - - if (LazyLoader != null) - await LazyLoader.Reload(); - } - - private string GetBackPath() - { - if (Path.Length == 1) - return "settings"; - else - { - var path = string.Join('/', Path.Take(Path.Length - 1)).TrimEnd('/'); - return $"settings?section={path}"; - } - } - - private object? Resolve(object model, string[] path, int index) - { - if (path.Length == 0) - return model; - - if (path.Length == index) - return model; - - var prop = model - .GetType() - .GetProperties() - .FirstOrDefault(x => x.PropertyType.Assembly.FullName!.Contains("Moonlight") && x.Name == path[index]); - - if (prop == null) - return null; - - return Resolve(prop.GetValue(model)!, path, index + 1); - } - - private Task Load(LazyLoader arg) - { - return Task.CompletedTask; - } - - private async Task Save() - { - ConfigService.Save(); - await ToastService.Success("Successfully saved config to disk"); - } - - private async Task Reload() - { - ConfigService.Reload(); - await ToastService.Info("Reloaded configuration from disk"); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Admin/Users/Index.razor b/Moonlight/Core/UI/Views/Admin/Users/Index.razor deleted file mode 100644 index f13cb70..0000000 --- a/Moonlight/Core/UI/Views/Admin/Users/Index.razor +++ /dev/null @@ -1,53 +0,0 @@ -@page "/admin/users" -@using BlazorTable -@using MoonCore.Abstractions -@using MoonCore.Helpers -@using Moonlight.Core.Database.Entities -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - -@attribute [RequirePermission(Permission.AdminUsers)] - -@inject Repository UserRepository - - - -
    -
    - - - - - - - - - - - -
    -
    -
    -
    - -@code -{ - private User[] AllUsers; - - private Task Load(LazyLoader _) - { - AllUsers = UserRepository - .Get() - .ToArray(); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Admin/Users/Sessions.razor b/Moonlight/Core/UI/Views/Admin/Users/Sessions.razor deleted file mode 100644 index 8faa2dd..0000000 --- a/Moonlight/Core/UI/Views/Admin/Users/Sessions.razor +++ /dev/null @@ -1,76 +0,0 @@ -@page "/admin/users/sessions" -@using BlazorTable -@using MoonCore.Helpers -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Abstractions -@using Moonlight.Core.Models.Enums -@using Moonlight.Core.Services - -@attribute [RequirePermission(Permission.AdminSessions)] - -@inject SessionService SessionService - - - - - This list shows you every user connected to this moonlight instance. Its updated in realtime - - -
    -
    - - - - - - - - - - - - - - - - -
    -
    -
    -
    - -@code -{ - private Task Load(LazyLoader _) - { - Task.Run(async () => - { - while (true) - { - await InvokeAsync(StateHasChanged); - await Task.Delay(TimeSpan.FromSeconds(1)); - } - }); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Admin/Users/View.razor b/Moonlight/Core/UI/Views/Admin/Users/View.razor deleted file mode 100644 index 23bb9f3..0000000 --- a/Moonlight/Core/UI/Views/Admin/Users/View.razor +++ /dev/null @@ -1,242 +0,0 @@ -@page "/admin/users/view/{Id:int}" -@using Microsoft.EntityFrameworkCore -@using Mappy.Net -@using BlazorTable -@using MoonCore.Abstractions -@using MoonCore.Helpers -@using MoonCore.Services -@using MoonCoreUI.Services -@using Moonlight.Core.Configuration -@using Moonlight.Core.Database.Entities -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums -@using Moonlight.Core.Models.Forms.Admin.Users -@using Moonlight.Core.Services -@using Moonlight.Core.Services.Users -@using Moonlight.Features.ServiceManagement.Entities -@using Moonlight.Features.StoreSystem.Entities - -@attribute [RequirePermission(Permission.AdminUsers)] - -@inject Repository UserRepository -@inject Repository ServiceRepository -@inject SessionService SessionService -@inject UserService UserService -@inject ToastService ToastService -@inject ConfigService ConfigService -@inject NavigationManager Navigation - - - @if (User == null) - { - - } - else - { -
    -
    -
    -
    -

    User details

    -
    - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    -
    - -
    -
    - - -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    Online status
    - @if (Online) - { -
    Online
    - } - else - { -
    Offline
    - } -
    -
    -
    Registered at
    -
    - @Formatter.FormatDate(User.CreatedAt) -
    -
    -
    -
    -
    -
    -

    Transactions

    -
    -
    - - - - - - - - - -
    -
    -
    -
    -
    -
    -
    -

    Services

    -
    -
    - - - - - - - - - -
    -
    -
    -
    -
    - } -
    - -@code -{ - [Parameter] - public int Id { get; set; } - - private User? User; - private bool Online; - private Service[] Services; - private Transaction[] Transactions; - - private UpdateUserForm UserForm; - private UpdateUserPasswordForm PasswordForm = new(); - - private async Task Load(LazyLoader lazyLoader) // We use the text feature here because users have a lot of data related to them - { - await lazyLoader.SetText("Loading user"); - User = UserRepository - .Get() - .Include(x => x.Transactions) - .Include(x => x.CouponUses) - .Include(x => x.GiftCodeUses) - .FirstOrDefault(x => x.Id == Id); - - if (User != null) - { - UserForm = Mapper.Map(User); - - await lazyLoader.SetText("Checking online status"); - Online = SessionService - .GetSessions() - .Where(x => x.User != null) - .Any(x => x.User!.Id == User.Id); - - await lazyLoader.SetText("Loading user services"); - Services = ServiceRepository - .Get() - .Include(x => x.Product) - .Where(x => x.Owner.Id == User.Id) - .ToArray(); - - await lazyLoader.SetText("Sorting transactions"); - Transactions = User.Transactions - .OrderByDescending(x => x.Id) - .ToArray(); - } - } - - private async Task UpdateUser() - { - await UserService.Update(User!, UserForm.Username, UserForm.Email); - await ToastService.Success("Successfully updated user"); - } - - private async Task UpdatePassword() - { - await UserService.Auth.ChangePassword(User!, PasswordForm.Password); - await ToastService.Success("Successfully updated user password"); - } - - private async Task Delete() - { - await UserService.Delete.Perform(User!); - await ToastService.Success("Successfully deleted user"); - Navigation.NavigateTo("/admin/users"); - } -} \ No newline at end of file diff --git a/Moonlight/Core/UI/Views/Index.razor b/Moonlight/Core/UI/Views/Index.razor deleted file mode 100644 index 82b9cd6..0000000 --- a/Moonlight/Core/UI/Views/Index.razor +++ /dev/null @@ -1,54 +0,0 @@ -@page "/" - -@using Moonlight.Core.Services - -@inject IdentityService IdentityService - -
    -
    - Welcome back, @(IdentityService.CurrentUser.Username) -
    -
    - - \ No newline at end of file diff --git a/Moonlight/Dockerfile b/Moonlight/Dockerfile deleted file mode 100644 index 64bd6cd..0000000 --- a/Moonlight/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base -WORKDIR /app -EXPOSE 80 -EXPOSE 443 - -FROM mcr.microsoft.com/dotnet/sdk:7.0.100-preview.3 AS build -WORKDIR /src -COPY ["Moonlight/Moonlight.csproj", "Moonlight/"] -RUN dotnet restore "Moonlight/Moonlight.csproj" -COPY . . -WORKDIR "/src/Moonlight" -RUN dotnet build "Moonlight.csproj" -c Release -o /app/build - -FROM build AS publish -RUN dotnet publish "Moonlight.csproj" -c Release -o /app/publish /p:UseAppHost=false - -FROM base AS final -WORKDIR /app -COPY --from=publish /app/publish . -RUN mkdir -p /app/storage -RUN rm -r /app/storage/* -ENTRYPOINT ["dotnet", "Moonlight.dll"] diff --git a/Moonlight/Features/Advertisement/Configuration/AdvertisementData.cs b/Moonlight/Features/Advertisement/Configuration/AdvertisementData.cs deleted file mode 100644 index 8904687..0000000 --- a/Moonlight/Features/Advertisement/Configuration/AdvertisementData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.ComponentModel; -using Newtonsoft.Json; - -namespace Moonlight.Features.Advertisement.Configuration; - -public class AdvertisementData -{ - [JsonProperty("PreventAdBlockers")] - [Description("This prevents users from using ad blockers while using moonlight. (Note: The detection might not always work)")] - public bool PreventAdBlockers { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Advertisement/Services/AdBlockService.cs b/Moonlight/Features/Advertisement/Services/AdBlockService.cs deleted file mode 100644 index 02b6120..0000000 --- a/Moonlight/Features/Advertisement/Services/AdBlockService.cs +++ /dev/null @@ -1,31 +0,0 @@ -using Microsoft.JSInterop; -using MoonCore.Attributes; -using MoonCore.Helpers; - -namespace Moonlight.Features.Advertisement.Services; - -[Scoped] -public class AdBlockService -{ - private readonly IJSRuntime JsRuntime; - - public AdBlockService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - } - - public async Task Detect() - { - try - { - return await JsRuntime.InvokeAsync("moonlight.utils.vendo"); // lat. vendo = advertisement xd - } - catch (Exception e) - { - Logger.Warn("An unexpected error occured while trying to detect possible ad blockers"); - Logger.Warn(e); - - return false; - } - } -} \ No newline at end of file diff --git a/Moonlight/Features/Advertisement/UI/Components/AdBlockAlert.razor b/Moonlight/Features/Advertisement/UI/Components/AdBlockAlert.razor deleted file mode 100644 index 0032bca..0000000 --- a/Moonlight/Features/Advertisement/UI/Components/AdBlockAlert.razor +++ /dev/null @@ -1,16 +0,0 @@ -
    -
    -
    -

    - AdBlocker detected -

    -
    - We have detected that you are using an adblocker. Disable your adblocker or add this site as an exception and reload the page to proceed -
    -
    - - -
    -
    \ No newline at end of file diff --git a/Moonlight/Features/Community/Entities/Enums/PostType.cs b/Moonlight/Features/Community/Entities/Enums/PostType.cs deleted file mode 100644 index 4899855..0000000 --- a/Moonlight/Features/Community/Entities/Enums/PostType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.Community.Entities.Enums; - -public enum PostType -{ - Project = 0, - Announcement = 1, - Event = 2 -} \ No newline at end of file diff --git a/Moonlight/Features/Community/Entities/Post.cs b/Moonlight/Features/Community/Entities/Post.cs deleted file mode 100644 index 09b92be..0000000 --- a/Moonlight/Features/Community/Entities/Post.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Moonlight.Core.Database.Entities; -using Moonlight.Features.Community.Entities.Enums; - -namespace Moonlight.Features.Community.Entities; - -public class Post -{ - public int Id { get; set; } - public string Title { get; set; } = ""; - public string Content { get; set; } = ""; - public User Author { get; set; } - public PostType Type { get; set; } - public List Comments { get; set; } = new(); - public List Likes { get; set; } = new(); - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Features/Community/Entities/PostComment.cs b/Moonlight/Features/Community/Entities/PostComment.cs deleted file mode 100644 index 545f81d..0000000 --- a/Moonlight/Features/Community/Entities/PostComment.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Moonlight.Core.Database.Entities; - -namespace Moonlight.Features.Community.Entities; - -public class PostComment -{ - public int Id { get; set; } - public string Content { get; set; } = ""; - public User Author { get; set; } - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime UpdatedAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Features/Community/Entities/PostLike.cs b/Moonlight/Features/Community/Entities/PostLike.cs deleted file mode 100644 index 4cb0cad..0000000 --- a/Moonlight/Features/Community/Entities/PostLike.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Moonlight.Core.Database.Entities; - -namespace Moonlight.Features.Community.Entities; - -public class PostLike -{ - public int Id { get; set; } - public User User { get; set; } - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Features/Community/Entities/WordFilter.cs b/Moonlight/Features/Community/Entities/WordFilter.cs deleted file mode 100644 index e0ab97e..0000000 --- a/Moonlight/Features/Community/Entities/WordFilter.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Moonlight.Features.Community.Entities; - -public class WordFilter -{ - public int Id { get; set; } - public string Filter { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/Community/Models/Forms/AddPostForm.cs b/Moonlight/Features/Community/Models/Forms/AddPostForm.cs deleted file mode 100644 index 5f8c5bf..0000000 --- a/Moonlight/Features/Community/Models/Forms/AddPostForm.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Community.Models.Forms; - -public class AddPostForm -{ - [Required(ErrorMessage = "You need to enter a title")] - [MaxLength(40, ErrorMessage = "The title can only be 40 characters long")] - [MinLength(8, ErrorMessage = "The title must at least have 8 characters")] - public string Title { get; set; } = ""; - - [Required(ErrorMessage = "You need to enter post content")] - [MaxLength(2048, ErrorMessage = "The post content can only be 2048 characters long")] - [MinLength(8, ErrorMessage = "The post content must at least have 8 characters")] - public string Content { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/Community/Models/Forms/Admin/AddWordFilter.cs b/Moonlight/Features/Community/Models/Forms/Admin/AddWordFilter.cs deleted file mode 100644 index ac434ec..0000000 --- a/Moonlight/Features/Community/Models/Forms/Admin/AddWordFilter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Community.Models.Forms.Admin; - -public class AddWordFilter -{ - [Required(ErrorMessage = "You need to specify a filter")] - [Description( - "This filters all posts and comments created using this regex. If any match is found it will block the action")] - public string Filter { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/Community/Models/Forms/Admin/EditWordFilter.cs b/Moonlight/Features/Community/Models/Forms/Admin/EditWordFilter.cs deleted file mode 100644 index 97f421b..0000000 --- a/Moonlight/Features/Community/Models/Forms/Admin/EditWordFilter.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Community.Models.Forms.Admin; - -public class EditWordFilter -{ - [Required(ErrorMessage = "You need to specify a filter")] - [Description( - "This filters all posts and comments created using this regex. If any match is found it will block the action")] - public string Filter { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/Community/Services/PostService.cs b/Moonlight/Features/Community/Services/PostService.cs deleted file mode 100644 index 39ee20b..0000000 --- a/Moonlight/Features/Community/Services/PostService.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System.Text.RegularExpressions; -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Exceptions; -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Event; -using Moonlight.Core.Extensions; -using Moonlight.Features.Community.Entities; -using Moonlight.Features.Community.Entities.Enums; - -namespace Moonlight.Features.Community.Services; - -[Scoped] -public class PostService -{ - private readonly Repository PostRepository; - private readonly Repository PostLikeRepository; - private readonly Repository PostCommentRepository; - private readonly Repository WordFilterRepository; - - public PostService( - Repository postRepository, - Repository postLikeRepository, - Repository postCommentRepository, - Repository wordFilterRepository) - { - PostRepository = postRepository; - PostLikeRepository = postLikeRepository; - PostCommentRepository = postCommentRepository; - WordFilterRepository = wordFilterRepository; - } - - // Posts - public async Task Create(User user, string title, string content, PostType type) - { - if(await CheckTextForBadWords(title)) - throw new DisplayException("Bad word detected. Please follow the community rules"); - - if(await CheckTextForBadWords(content)) - throw new DisplayException("Bad word detected. Please follow the community rules"); - - var post = new Post() - { - Author = user, - Title = title, - Content = content, - Type = type - }; - - var finishedPost = PostRepository.Add(post); - - await Events.OnPostCreated.InvokeAsync(finishedPost); - - return finishedPost; - } - - public async Task Update(Post post, string title, string content) - { - if(await CheckTextForBadWords(title)) - throw new DisplayException("Bad word detected. Please follow the community rules"); - - if(await CheckTextForBadWords(content)) - throw new DisplayException("Bad word detected. Please follow the community rules"); - - post.Title = title; - post.Content = content; - post.UpdatedAt = DateTime.UtcNow; - - PostRepository.Update(post); - - await Events.OnPostUpdated.InvokeAsync(post); - } - - public async Task Delete(Post post) - { - var postWithData = PostRepository - .Get() - .Include(x => x.Comments) - .Include(x => x.Likes) - .First(x => x.Id == post.Id); - - // Cache relational data to delete later on - var likes = postWithData.Likes.ToArray(); - var comments = postWithData.Comments.ToArray(); - - // Clear relations - postWithData.Comments.Clear(); - postWithData.Likes.Clear(); - - PostRepository.Update(postWithData); - - // Delete relational data - foreach (var like in likes) - PostLikeRepository.Delete(like); - - foreach (var comment in comments) - PostCommentRepository.Delete(comment); - - // Now delete the post itself - PostRepository.Delete(post); - await Events.OnPostDeleted.InvokeAsync(post); - } - - // Comments - public async Task CreateComment(Post post, User user, string content) - { - // As the comment feature has no edit form or model to validate we do the validation here - if (string.IsNullOrEmpty(content)) - throw new DisplayException("Comment content cannot be empty"); - - if (content.Length > 1024) - throw new DisplayException("Comment content cannot be longer than 1024 characters"); - - if (!Regex.IsMatch(content, "^[ a-zA-Z0-9äöüßÄÖÜẞ,.;_\\n\\t-]+$")) - throw new DisplayException("Illegal characters in comment content"); - - if(await CheckTextForBadWords(content)) - throw new DisplayException("Bad word detected. Please follow the community rules"); - - var comment = new PostComment() - { - Author = user, - Content = content - }; - - post.Comments.Add(comment); - PostRepository.Update(post); - - await Events.OnPostCommentCreated.InvokeAsync(comment); - - return comment; - } - - public async Task DeleteComment(Post post, PostComment comment) - { - var postWithComments = PostRepository - .Get() - .Include(x => x.Comments) - .First(x => x.Id == post.Id); - - var commentToRemove = postWithComments.Comments.First(x => x.Id == comment.Id); - postWithComments.Comments.Remove(commentToRemove); - - PostRepository.Update(postWithComments); - PostCommentRepository.Delete(commentToRemove); - - await Events.OnPostCommentCreated.InvokeAsync(commentToRemove); - } - - // Other - public async Task ToggleLike(Post post, User user) - { - var postWithLikes = PostRepository - .Get() - .Include(x => x.Likes) - .ThenInclude(x => x.User) - .First(x => x.Id == post.Id); - - var userLike = postWithLikes.Likes.FirstOrDefault(x => x.User.Id == user.Id); - - if (userLike != null) // Check if person already liked - { - postWithLikes.Likes.Remove(userLike); - - PostRepository.Update(postWithLikes); - PostLikeRepository.Delete(userLike); - } - else - { - postWithLikes.Likes.Add(new() - { - User = user - }); - - PostRepository.Update(postWithLikes); - - await Events.OnPostLiked.InvokeAsync(postWithLikes); - } - } - - // Utils - private Task CheckTextForBadWords(string input) // This method checks for bad words using the filters added by an admin - { - var filters = WordFilterRepository - .Get() - .Select(x => x.Filter) - .ToArray(); - - //TODO: Add timer for regex matching to create warnings - - foreach (var filter in filters) - { - if (Regex.IsMatch(input, filter)) - return Task.FromResult(true); - } - - return Task.FromResult(false); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Components/AdminCommunityNavigation.razor b/Moonlight/Features/Community/UI/Components/AdminCommunityNavigation.razor deleted file mode 100644 index cff1d7f..0000000 --- a/Moonlight/Features/Community/UI/Components/AdminCommunityNavigation.razor +++ /dev/null @@ -1,22 +0,0 @@ -
    - -
    - -@code -{ - [Parameter] - public int Index { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Components/CommunityNavigation.razor b/Moonlight/Features/Community/UI/Components/CommunityNavigation.razor deleted file mode 100644 index 8a42838..0000000 --- a/Moonlight/Features/Community/UI/Components/CommunityNavigation.razor +++ /dev/null @@ -1,41 +0,0 @@ -
    -
    -

    - Post channels -

    -
    -
    -
    -
    - -
    -
    - News -
    -
    -
    -
    -
    - -
    -
    - Events -
    -
    -
    -
    -
    - -
    -
    - Projects -
    -
    -
    -
    - -@code -{ - [Parameter] - public int Index { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Components/CreatePostModal.razor b/Moonlight/Features/Community/UI/Components/CreatePostModal.razor deleted file mode 100644 index 7cdadb3..0000000 --- a/Moonlight/Features/Community/UI/Components/CreatePostModal.razor +++ /dev/null @@ -1,68 +0,0 @@ -@using Moonlight.Core.Services -@using Moonlight.Features.Community.Entities.Enums -@using Moonlight.Features.Community.Models.Forms -@using Moonlight.Features.Community.Services -@using MoonCoreUI.Services - -@inject PostService PostService -@inject IdentityService IdentityService -@inject ToastService ToastService - - - - - - - - - -@code -{ - [Parameter] - public Func? OnUpdate { get; set; } - - [Parameter] - public PostType PostType { get; set; } - - private AddPostForm Form = new(); - private SmartModal Modal; - - public async Task Show() - { - Form = new(); - await Modal.Show(false); - } - - private async Task Submit() - { - await PostService.Create( - IdentityService.CurrentUser, - Form.Title, - Form.Content, - PostType - ); - - await Modal.Hide(); - await ToastService.Success("Successfully created post"); - - if (OnUpdate != null) - await OnUpdate.Invoke(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Components/PostView.razor b/Moonlight/Features/Community/UI/Components/PostView.razor deleted file mode 100644 index 5493a09..0000000 --- a/Moonlight/Features/Community/UI/Components/PostView.razor +++ /dev/null @@ -1,275 +0,0 @@ -@using Ganss.Xss -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions -@using MoonCore.Helpers -@using MoonCoreUI.Services -@using Moonlight.Core.Models.Enums - -@using Moonlight.Core.Services -@using Moonlight.Features.Community.Entities -@using Moonlight.Features.Community.Services - -@inject Repository PostRepository -@inject IdentityService IdentityService -@inject PostService PostService -@inject ToastService ToastService - -
    -
    -
    -
    - -
    -
    - @(Post.Author.Username) - @(Formatter.FormatAgoFromDateTime(Post.CreatedAt)) -
    -
    - - @if (Post.Author.Id == IdentityService.CurrentUser.Id || IdentityService.Permissions[Permission.AdminCommunity]) - { - - } -
    -
    -
    - @if (IsEditing) - { - - } - else - { - var sanitizer = new HtmlSanitizer(); - var content = sanitizer.Sanitize(Post.Content); - - @((MarkupString)content) - } -
    -
    - -
    - -@code -{ - [Parameter] - public Post Post { get; set; } - - [Parameter] - public Func? OnUpdate { get; set; } - - private int CommentsCount = -1; - private int LikesCount = -1; - private bool HasLiked = false; - - private bool ShowComments = false; - private PostComment[] Comments = Array.Empty(); - private string Comment = ""; - - private bool IsEditing = false; - private string EditTitle = ""; - private string EditContent = ""; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await UpdateCounts(); - } - } - - private Task LoadComments(LazyLoader _) - { - Comments = PostRepository - .Get() - .Include(x => x.Comments) - .ThenInclude(x => x.Author) - .First(x => x.Id == Post.Id) - .Comments - .OrderBy(x => x.CreatedAt) - .ToArray(); - - return Task.CompletedTask; - } - - private async Task UpdateCounts() - { - CommentsCount = PostRepository - .Get() - .Where(x => x.Id == Post.Id) - .SelectMany(x => x.Comments) - .Count(); - - LikesCount = PostRepository - .Get() - .Where(x => x.Id == Post.Id) - .SelectMany(x => x.Likes) - .Count(); - - HasLiked = PostRepository - .Get() - .Where(x => x.Id == Post.Id) - .SelectMany(x => x.Likes) - .Any(x => x.User.Id == IdentityService.CurrentUser.Id); - - await InvokeAsync(StateHasChanged); - } - - private async Task CreateComment() - { - await PostService.CreateComment(Post, IdentityService.CurrentUser, Comment); - - Comment = ""; - ShowComments = true; - await LoadComments(null!); - await InvokeAsync(StateHasChanged); - await UpdateCounts(); - } - - private async Task DeleteComment(PostComment comment) - { - await PostService.DeleteComment(Post, comment); - - await LoadComments(null!); - await InvokeAsync(StateHasChanged); - await UpdateCounts(); - - await ToastService.Success("Successfully deleted comment"); - } - - private async Task ToggleComments() - { - ShowComments = !ShowComments; - await InvokeAsync(StateHasChanged); - - if (!ShowComments) - Comments = Array.Empty(); // Clear unused data - } - - private async Task ToggleLike() - { - await PostService.ToggleLike(Post, IdentityService.CurrentUser); - await UpdateCounts(); - } - - private async Task ToggleEdit(bool preventSaving = false) - { - IsEditing = !IsEditing; - - if (IsEditing) - { - EditTitle = Post.Title; - EditContent = Post.Content; - } - else if (!preventSaving) - { - await PostService.Update(Post, EditTitle, EditContent); - await ToastService.Success("Successfully saved post"); - } - - await InvokeAsync(StateHasChanged); - } - - private async Task DeletePost() - { - await PostService.Delete(Post); - await ToastService.Success("Successfully deleted post"); - - if (OnUpdate != null) - await OnUpdate.Invoke(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Views/Admin/Filter.razor b/Moonlight/Features/Community/UI/Views/Admin/Filter.razor deleted file mode 100644 index 8c59585..0000000 --- a/Moonlight/Features/Community/UI/Views/Admin/Filter.razor +++ /dev/null @@ -1,42 +0,0 @@ -@page "/admin/community/filter" - -@using BlazorTable -@using MoonCore.Abstractions -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - -@using Moonlight.Features.Community.Entities -@using Moonlight.Features.Community.Models.Forms.Admin -@using Moonlight.Features.Community.UI.Components - -@attribute [RequirePermission(Permission.AdminCommunity)] - - - - - To protect from trollers and toxic people you can configure words using - regex expressions to block automatically to ensure no one can write bad things in the community tab. - - -
    - - - - - - -
    - -@code -{ - private WordFilter[] LoadData(Repository repository) - { - return repository - .Get() - .ToArray(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Views/Admin/Index.razor b/Moonlight/Features/Community/UI/Views/Admin/Index.razor deleted file mode 100644 index d1dda89..0000000 --- a/Moonlight/Features/Community/UI/Views/Admin/Index.razor +++ /dev/null @@ -1,9 +0,0 @@ -@page "/admin/community" - -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums -@using Moonlight.Features.Community.UI.Components - -@attribute [RequirePermission(Permission.AdminCommunity)] - - \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Views/Events.razor b/Moonlight/Features/Community/UI/Views/Events.razor deleted file mode 100644 index b3ebc94..0000000 --- a/Moonlight/Features/Community/UI/Views/Events.razor +++ /dev/null @@ -1,66 +0,0 @@ -@page "/community/events" - -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions -@using Moonlight.Core.Models.Enums - -@using Moonlight.Core.Services -@using Moonlight.Features.Community.Entities -@using Moonlight.Features.Community.Entities.Enums -@using Moonlight.Features.Community.UI.Components - -@inject IdentityService IdentityService -@inject Repository PostRepository - -
    -
    - - - @if (IdentityService.Permissions[Permission.AdminCommunity]) - { -
    - -
    - } -
    -
    -
    -
    - Planned events and current happenings can be found here. - If you want to know what will happen in the future or is going on now have a look at the posts below -
    -
    - - - @foreach (var post in Posts) - { - -
    - } -
    -
    -
    - -@if (IdentityService.Permissions[Permission.AdminCommunity]) -{ - -} - -@code -{ - private LazyLoader LazyLoader; - private CreatePostModal CreateModal; - private Post[] Posts; - - private Task Load(LazyLoader _) - { - Posts = PostRepository - .Get() - .Include(x => x.Author) - .Where(x => x.Type == PostType.Event) - .OrderByDescending(x => x.CreatedAt) - .ToArray(); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Views/Index.razor b/Moonlight/Features/Community/UI/Views/Index.razor deleted file mode 100644 index bbf7765..0000000 --- a/Moonlight/Features/Community/UI/Views/Index.razor +++ /dev/null @@ -1,67 +0,0 @@ -@page "/community" - -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions -@using Moonlight.Core.Models.Enums - -@using Moonlight.Core.Services -@using Moonlight.Features.Community.Entities -@using Moonlight.Features.Community.Entities.Enums -@using Moonlight.Features.Community.UI.Components - -@inject Repository PostRepository -@inject IdentityService IdentityService - -
    -
    - - - @if (IdentityService.Permissions[Permission.AdminCommunity]) - { -
    - -
    - } -
    -
    -
    -
    - These announcements provide you with the latest news and information. - The posts here have been created by an admin and can contain valuable information - so consider reading it from time to time -
    -
    - - - @foreach (var post in Posts) - { - -
    - } -
    -
    -
    - -@if (IdentityService.Permissions[Permission.AdminCommunity]) -{ - -} - -@code -{ - private LazyLoader LazyLoader; - private CreatePostModal CreateModal; - private Post[] Posts; - - private Task Load(LazyLoader _) - { - Posts = PostRepository - .Get() - .Include(x => x.Author) - .Where(x => x.Type == PostType.Announcement) - .OrderByDescending(x => x.CreatedAt) - .ToArray(); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Community/UI/Views/Projects.razor b/Moonlight/Features/Community/UI/Views/Projects.razor deleted file mode 100644 index 0ae17d0..0000000 --- a/Moonlight/Features/Community/UI/Views/Projects.razor +++ /dev/null @@ -1,58 +0,0 @@ -@page "/community/projects" - -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions - -@using Moonlight.Features.Community.Entities -@using Moonlight.Features.Community.Entities.Enums -@using Moonlight.Features.Community.UI.Components - -@inject Repository PostRepository - -
    -
    - - -
    - -
    -
    -
    -
    -
    - You have a interesting project or a fun game server you want to share with the community? - You can share it here. Please keep in mind to follow basic rules and dont offend anyone. - Be nice and respectful -
    -
    - - - @foreach (var post in Posts) - { - -
    - } -
    -
    -
    - - - -@code -{ - private LazyLoader LazyLoader; - private CreatePostModal CreateModal; - private Post[] Posts; - - private Task Load(LazyLoader _) - { - Posts = PostRepository - .Get() - .Include(x => x.Author) - .Where(x => x.Type == PostType.Project) - .OrderByDescending(x => x.CreatedAt) - .ToArray(); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Configuration/FileManagerData.cs b/Moonlight/Features/FileManager/Configuration/FileManagerData.cs deleted file mode 100644 index 69f5fa7..0000000 --- a/Moonlight/Features/FileManager/Configuration/FileManagerData.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel; -using Newtonsoft.Json; - -namespace Moonlight.Features.FileManager.Configuration; - -public class FileManagerData -{ - [JsonProperty("MaxFileOpenSize")] - [Description( - "This specifies the maximum file size a user will be able to open in the file editor in kilobytes")] - public int MaxFileOpenSize { get; set; } = 1024 * 5; // 5 MB - - [JsonProperty("OperationTimeout")] - [Description("This specifies the general timeout for file manager operations. This can but has not to be used by file accesses")] - public int OperationTimeout { get; set; } = 5; -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Helpers/EditorModeDetector.cs b/Moonlight/Features/FileManager/Helpers/EditorModeDetector.cs deleted file mode 100644 index 3a4280d..0000000 --- a/Moonlight/Features/FileManager/Helpers/EditorModeDetector.cs +++ /dev/null @@ -1,210 +0,0 @@ -namespace Moonlight.Features.FileManager.Helpers; - -public static class EditorModeDetector -{ - // We probably will never need every of this modes ;) - private static readonly Dictionary ExtensionIndex = new() - { - { "abap", new[] { "abap" } }, - { "abc", new[] { "abc" } }, - { "actionscript", new[] { "as" } }, - { "ada", new[] { "ada", "adb" } }, - { "alda", new[] { "alda" } }, - { "apache_conf", new[] { "htaccess", "htgroups", "htpasswd", "conf", "htaccess", "htgroups", "htpasswd" } }, - { "apex", new[] { "apex", "cls", "trigger", "tgr" } }, - { "aql", new[] { "aql" } }, - { "asciidoc", new[] { "asciidoc", "adoc" } }, - { "asl", new[] { "dsl", "asl", "asl.json" } }, - { "assembly_x86", new[] { "asm", "a" } }, - { "astro", new[] { "astro" } }, - { "autohotkey", new[] { "ahk" } }, - { "batchfile", new[] { "bat", "cmd" } }, - { "bibtex", new[] { "bib" } }, - { "c_cpp", new[] { "cpp", "c", "cc", "cxx", "h", "hh", "hpp", "ino" } }, - { "c9search", new[] { "c9search_results" } }, - { "cirru", new[] { "cirru", "cr" } }, - { "clojure", new[] { "clj", "cljs" } }, - { "cobol", new[] { "cbl", "cob" } }, - { "coffee", new[] { "coffee", "cf", "cson", "cakefile" } }, - { "coldfusion", new[] { "cfm", "cfc" } }, - { "crystal", new[] { "cr" } }, - { "csharp", new[] { "cs" } }, - { "csound_document", new[] { "csd" } }, - { "csound_orchestra", new[] { "orc" } }, - { "csound_score", new[] { "sco" } }, - { "css", new[] { "css" } }, - { "curly", new[] { "curly" } }, - { "cuttlefish", new[] { "conf" } }, - { "d", new[] { "d", "di" } }, - { "dart", new[] { "dart" } }, - { "diff", new[] { "diff", "patch" } }, - { "django", new[] { "djt", "html.djt", "dj.html", "djhtml" } }, - { "dockerfile", new[] { "dockerfile" } }, - { "dot", new[] { "dot" } }, - { "drools", new[] { "drl" } }, - { "edifact", new[] { "edi" } }, - { "eiffel", new[] { "e", "ge" } }, - { "ejs", new[] { "ejs" } }, - { "elixir", new[] { "ex", "exs" } }, - { "elm", new[] { "elm" } }, - { "erlang", new[] { "erl", "hrl" } }, - { "flix", new[] { "flix" } }, - { "forth", new[] { "frt", "fs", "ldr", "fth", "4th" } }, - { "fortran", new[] { "f", "f90" } }, - { "fsharp", new[] { "fsi", "fs", "ml", "mli", "fsx", "fsscript" } }, - { "fsl", new[] { "fsl" } }, - { "ftl", new[] { "ftl" } }, - { "gcode", new[] { "gcode" } }, - { "gherkin", new[] { "feature" } }, - { "gitignore", new[] { ".gitignore" } }, - { "glsl", new[] { "glsl", "frag", "vert" } }, - { "gobstones", new[] { "gbs" } }, - { "golang", new[] { "go" } }, - { "graphqlschema", new[] { "gql" } }, - { "groovy", new[] { "groovy" } }, - { "haml", new[] { "haml" } }, - { "handlebars", new[] { "hbs", "handlebars", "tpl", "mustache" } }, - { "haskell", new[] { "hs" } }, - { "haskell_cabal", new[] { "cabal" } }, - { "haxe", new[] { "hx" } }, - { "hjson", new[] { "hjson" } }, - { "html", new[] { "html", "htm", "xhtml", "vue", "we", "wpy" } }, - { "html_elixir", new[] { "eex", "html.eex" } }, - { "html_ruby", new[] { "erb", "rhtml", "html.erb" } }, - { "ini", new[] { "ini", "conf", "cfg", "prefs" } }, - { "io", new[] { "io" } }, - { "ion", new[] { "ion" } }, - { "jack", new[] { "jack" } }, - { "jade", new[] { "jade", "pug" } }, - { "java", new[] { "java" } }, - { "javascript", new[] { "js", "jsm", "jsx", "cjs", "mjs" } }, - { "jexl", new[] { "jexl" } }, - { "json", new[] { "json" } }, - { "json5", new[] { "json5" } }, - { "jsoniq", new[] { "jq" } }, - { "jsp", new[] { "jsp" } }, - { "jssm", new[] { "jssm", "jssm_state" } }, - { "jsx", new[] { "jsx" } }, - { "julia", new[] { "jl" } }, - { "kotlin", new[] { "kt", "kts" } }, - { "latex", new[] { "tex", "latex", "ltx", "bib" } }, - { "latte", new[] { "latte" } }, - { "less", new[] { "less" } }, - { "liquid", new[] { "liquid" } }, - { "lisp", new[] { "lisp" } }, - { "livescript", new[] { "ls" } }, - { "log", new[] { "log" } }, - { "logiql", new[] { "logic", "lql" } }, - { "logtalk", new[] { "lgt" } }, - { "lsl", new[] { "lsl" } }, - { "lua", new[] { "lua" } }, - { "luapage", new[] { "lp" } }, - { "lucene", new[] { "lucene" } }, - { "makefile", new[] { "makefile", "gnumakefile", "makefile", "ocamlmakefile", "make" } }, - { "markdown", new[] { "md", "markdown" } }, - { "mask", new[] { "mask" } }, - { "matlab", new[] { "matlab" } }, - { "maze", new[] { "mz" } }, - { "mediawiki", new[] { "wiki", "mediawiki" } }, - { "mel", new[] { "mel" } }, - { "mips", new[] { "s", "asm" } }, - { "mixal", new[] { "mixal" } }, - { "mushcode", new[] { "mc", "mush" } }, - { "mysql", new[] { "mysql" } }, - { "nasal", new[] { "nas" } }, - { "nginx", new[] { "nginx", "conf" } }, - { "nim", new[] { "nim" } }, - { "nix", new[] { "nix" } }, - { "nsis", new[] { "nsi", "nsh" } }, - { "nunjucks", new[] { "nunjucks", "nunjs", "nj", "njk" } }, - { "objectivec", new[] { "m", "mm" } }, - { "ocaml", new[] { "ml", "mli" } }, - { "odin", new[] { "odin" } }, - { "partiql", new[] { "partiql", "pql" } }, - { "pascal", new[] { "pas", "p" } }, - { "perl", new[] { "pl", "pm" } }, - { "pgsql", new[] { "pgsql" } }, - { "php", new[] { "php", "inc", "phtml", "shtml", "php3", "php4", "php5", "phps", "phpt", "aw", "ctp", "module" } }, - { "php_laravel_blade", new[] { "blade.php" } }, - { "pig", new[] { "pig" } }, - { "plsql", new[] { "plsql" } }, - { "powershell", new[] { "ps1" } }, - { "praat", new[] { "praat", "praatscript", "psc", "proc" } }, - { "prisma", new[] { "prisma" } }, - { "prolog", new[] { "plg", "prolog" } }, - { "properties", new[] { "properties" } }, - { "protobuf", new[] { "proto" } }, - { "prql", new[] { "prql" } }, - { "puppet", new[] { "epp", "pp" } }, - { "python", new[] { "py" } }, - { "qml", new[] { "qml" } }, - { "r", new[] { "r" } }, - { "raku", new[] { "raku", "rakumod", "rakutest", "p6", "pl6", "pm6" } }, - { "razor", new[] { "cshtml", "asp" } }, - { "rdoc", new[] { "rd" } }, - { "red", new[] { "red", "reds" } }, - { "rhtml", new[] { "rhtml" } }, - { "robot", new[] { "robot", "resource" } }, - { "rst", new[] { "rst" } }, - { "ruby", new[] { "rb", "ru", "gemspec", "rake", "guardfile", "rakefile", "gemfile" } }, - { "rust", new[] { "rs" } }, - { "sac", new[] { "sac" } }, - { "sass", new[] { "sass" } }, - { "scad", new[] { "scad" } }, - { "scala", new[] { "scala", "sbt" } }, - { "scheme", new[] { "scm", "sm", "rkt", "oak", "scheme" } }, - { "scrypt", new[] { "scrypt" } }, - { "scss", new[] { "scss" } }, - { "sh", new[] { "sh", "bash", ".bashrc" } }, - { "sjs", new[] { "sjs" } }, - { "slim", new[] { "slim", "skim" } }, - { "smarty", new[] { "smarty", "tpl" } }, - { "smithy", new[] { "smithy" } }, - { "snippets", new[] { "snippets" } }, - { "soy_template", new[] { "soy" } }, - { "space", new[] { "space" } }, - { "sparql", new[] { "rq" } }, - { "sql", new[] { "sql" } }, - { "sqlserver", new[] { "sqlserver" } }, - { "stylus", new[] { "styl", "stylus" } }, - { "svg", new[] { "svg" } }, - { "swift", new[] { "swift" } }, - { "tcl", new[] { "tcl" } }, - { "terraform", new[] { "tf", "tfvars", "terragrunt" } }, - { "tex", new[] { "tex" } }, - { "text", new[] { "txt" } }, - { "textile", new[] { "textile" } }, - { "toml", new[] { "toml" } }, - { "tsx", new[] { "tsx" } }, - { "turtle", new[] { "ttl" } }, - { "twig", new[] { "twig", "swig" } }, - { "typescript", new[] { "ts", "mts", "cts", "typescript", "str" } }, - { "vala", new[] { "vala" } }, - { "vbscript", new[] { "vbs", "vb" } }, - { "velocity", new[] { "vm" } }, - { "verilog", new[] { "v", "vh", "sv", "svh" } }, - { "vhdl", new[] { "vhd", "vhdl" } }, - { "visualforce", new[] { "vfp", "component", "page" } }, - { "wollok", new[] { "wlk", "wpgm", "wtest" } }, - { "xml", new[] { "xml", "rdf", "rss", "wsdl", "xslt", "atom", "mathml", "mml", "xul", "xbl", "xaml" } }, - { "xquery", new[] { "xq" } }, - { "yaml", new[] { "yaml", "yml" } }, - { "zeek", new[] { "zeek", "bro" } } - }; - - public static string GetModeFromFile(string fileName) - { - var extension = Path.GetExtension(fileName).Replace(".", ""); - - if (string.IsNullOrEmpty(extension)) - return "text"; - - foreach (var entry in ExtensionIndex) - { - if (entry.Value.Any(x => string.Equals(x, extension, StringComparison.InvariantCultureIgnoreCase))) - return entry.Key; - } - - return "text"; - } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Http/Controllers/DownloadController.cs b/Moonlight/Features/FileManager/Http/Controllers/DownloadController.cs deleted file mode 100644 index 4c0afd4..0000000 --- a/Moonlight/Features/FileManager/Http/Controllers/DownloadController.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using MoonCore.Helpers; -using Moonlight.Core.Services.Utils; -using Moonlight.Features.FileManager.Services; - -namespace Moonlight.Features.FileManager.Http.Controllers; - -[ApiController] -[Route("api/download")] -public class DownloadController : Controller -{ - private readonly JwtService JwtService; - private readonly SharedFileAccessService SharedFileAccessService; - - public DownloadController(JwtService jwtService, SharedFileAccessService sharedFileAccessService) - { - JwtService = jwtService; - SharedFileAccessService = sharedFileAccessService; - } - - [HttpGet] - public async Task Upload([FromQuery(Name = "token")] string downloadToken, [FromQuery(Name = "name")] string name) - { - if (name.Contains("..")) - { - Logger.Warn($"A user tried to access a file via path transversal. Name: {name}"); - return NotFound(); - } - - // Validate request - if (!await JwtService.Validate(downloadToken, "FileAccess")) - return StatusCode(403); - - var downloadContext = await JwtService.Decode(downloadToken); - - if (!downloadContext.ContainsKey("FileAccessId")) - return BadRequest(); - - if (!int.TryParse(downloadContext["FileAccessId"], out int fileAccessId)) - return BadRequest(); - - // Load file access for this file - var fileAccess = await SharedFileAccessService.Get(fileAccessId); - - if (fileAccess == null) - return BadRequest("Invalid file access id"); - - var files = await fileAccess.List(); - - if (files.All(x => !x.IsFile && x.Name != name)) - return NotFound(); - - var stream = await fileAccess.ReadFileStream(name); - - return File(stream, "application/octet-stream", name); - } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Http/Controllers/UploadController.cs b/Moonlight/Features/FileManager/Http/Controllers/UploadController.cs deleted file mode 100644 index a7dacec..0000000 --- a/Moonlight/Features/FileManager/Http/Controllers/UploadController.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Moonlight.Core.Services.Utils; -using Moonlight.Features.FileManager.Services; - -namespace Moonlight.Features.FileManager.Http.Controllers; - -[ApiController] -[Route("api/upload")] -public class UploadController : Controller -{ - private readonly JwtService JwtService; - private readonly SharedFileAccessService SharedFileAccessService; - - public UploadController( - JwtService jwtService, - SharedFileAccessService sharedFileAccessService) - { - JwtService = jwtService; - SharedFileAccessService = sharedFileAccessService; - } - - // The following method/api endpoint needs some explanation: - // Because of blazor and dropzone.js, we need an api endpoint - // to upload files via the built in file manager. - // As we learned from user experiences in v1b - // a large data transfer via the signal r connection might lead to - // failing uploads for some users with a unstable connection. That's - // why we implement this api endpoint. It can potentially prevent - // upload from malicious scripts as well. To verify the user is - // authenticated we use a jwt. - // The jwt specifies what - // connection we want to upload the file. This jwt - // will be generated every 5 minutes in the file upload service - // and only last 6 minutes. - - - [HttpPost] - public async Task Upload([FromQuery(Name = "token")] string uploadToken) - { - // Check if a file exist and if it is not too big - if (!Request.Form.Files.Any()) - return BadRequest("File is missing in request"); - - if (Request.Form.Files.Count > 1) - return BadRequest("Too many files sent"); - - // Validate request - if (!await JwtService.Validate(uploadToken, "FileAccess")) - return StatusCode(403); - - var uploadContext = await JwtService.Decode(uploadToken); - - if (!uploadContext.ContainsKey("FileAccessId")) - return BadRequest(); - - if (!int.TryParse(uploadContext["FileAccessId"], out int fileAccessId)) - return BadRequest(); - - // Load file access for this file - var fileAccess = await SharedFileAccessService.Get(fileAccessId); - - if (fileAccess == null) - return BadRequest("Invalid file access id"); - - // Actually upload the file - var file = Request.Form.Files.First(); - await fileAccess.WriteFileStream(file.FileName, file.OpenReadStream()); - - // Cleanup - fileAccess.Dispose(); - - return Ok(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/FileEntry.cs b/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/FileEntry.cs deleted file mode 100644 index 30f12c0..0000000 --- a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/FileEntry.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess; - -public class FileEntry -{ - public string Name { get; set; } - public long Size { get; set; } - public bool IsFile { get; set; } - public bool IsDirectory { get; set; } - public DateTime LastModifiedAt { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileAccess.cs b/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileAccess.cs deleted file mode 100644 index 9d8cbdc..0000000 --- a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileAccess.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess; - -public interface IFileAccess : IDisposable -{ - public Task List(); - public Task ChangeDirectory(string relativePath); - public Task SetDirectory(string path); - public Task GetCurrentDirectory(); - public Task Delete(string path); - public Task Move(string from, string to); - public Task CreateDirectory(string name); - public Task CreateFile(string name); - public Task ReadFile(string name); - public Task WriteFile(string name, string content); - public Task ReadFileStream(string name); - public Task WriteFileStream(string name, Stream dataStream); - public IFileAccess Clone(); -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileCompressAccess.cs b/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileCompressAccess.cs deleted file mode 100644 index 9b652bf..0000000 --- a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileCompressAccess.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess; - -public interface IFileCompressAccess -{ - public Task Compress(string[] names); - public Task Decompress(string name); -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileLaunchAccess.cs b/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileLaunchAccess.cs deleted file mode 100644 index 3d8b93c..0000000 --- a/Moonlight/Features/FileManager/Models/Abstractions/FileAccess/IFileLaunchAccess.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Moonlight.Features.FileManager.Models.Abstractions.FileAccess; - -public interface IFileLaunchAccess -{ - public Task GetLaunchUrl(); -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Models/Abstractions/FileUpload.cs b/Moonlight/Features/FileManager/Models/Abstractions/FileUpload.cs deleted file mode 100644 index 8dc9643..0000000 --- a/Moonlight/Features/FileManager/Models/Abstractions/FileUpload.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.FileManager.Models.Abstractions; - -public class FileUpload -{ - public string Name { get; set; } - public Stream Stream { get; set; } - public long Size { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Models/Abstractions/FileUploadConnection.cs b/Moonlight/Features/FileManager/Models/Abstractions/FileUploadConnection.cs deleted file mode 100644 index 1995ad8..0000000 --- a/Moonlight/Features/FileManager/Models/Abstractions/FileUploadConnection.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Moonlight.Features.FileManager.Models.Abstractions; - -public class FileUploadConnection -{ - public int Id { get; set; } - public string Url { get; set; } - public Func? OnFileReceived { get; set; } - public Func? OnUrlChanged { get; set; } - public DateTime LastSeenAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Services/DropzoneService.cs b/Moonlight/Features/FileManager/Services/DropzoneService.cs deleted file mode 100644 index c6705f7..0000000 --- a/Moonlight/Features/FileManager/Services/DropzoneService.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Microsoft.JSInterop; -using MoonCore.Attributes; - -namespace Moonlight.Features.FileManager.Services; - -[Scoped] -public class DropzoneService -{ - private readonly IJSRuntime JsRuntime; - - public DropzoneService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - } - - public async Task Create(string id, string initialUrl) - { - await JsRuntime.InvokeVoidAsync("moonlight.dropzone.create", id, initialUrl); - } - - public async Task UpdateUrl(string id, string url) - { - await JsRuntime.InvokeVoidAsync("moonlight.dropzone.updateUrl", id, url); - } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Services/EditorService.cs b/Moonlight/Features/FileManager/Services/EditorService.cs deleted file mode 100644 index ad5b494..0000000 --- a/Moonlight/Features/FileManager/Services/EditorService.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Microsoft.JSInterop; -using MoonCore.Attributes; - -namespace Moonlight.Features.FileManager.Services; - -[Scoped] -public class EditorService -{ - private readonly IJSRuntime JsRuntime; - - public EditorService(IJSRuntime jsRuntime) - { - JsRuntime = jsRuntime; - } - - public async Task Create(string mount, string theme = "one_dark", string mode = "text", string initialContent = "", - int lines = 30, int fontSize = 15) - { - await JsRuntime.InvokeVoidAsync( - "moonlight.editor.create", - mount, - theme, - mode, - initialContent, - lines, - fontSize - ); - } - - public async Task SetValue(string content) => await JsRuntime.InvokeVoidAsync("moonlight.editor.setValue", content); - - public async Task GetValue() => await JsRuntime.InvokeAsync("moonlight.editor.getValue"); - - public async Task SetMode(string mode) => await JsRuntime.InvokeVoidAsync("moonlight.editor.setMode", mode); -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/Services/SharedFileAccessService.cs b/Moonlight/Features/FileManager/Services/SharedFileAccessService.cs deleted file mode 100644 index 0a1e049..0000000 --- a/Moonlight/Features/FileManager/Services/SharedFileAccessService.cs +++ /dev/null @@ -1,62 +0,0 @@ -using MoonCore.Attributes; -using Moonlight.Core.Services.Utils; -using Moonlight.Features.FileManager.Models.Abstractions.FileAccess; - -namespace Moonlight.Features.FileManager.Services; - -[Singleton] -public class SharedFileAccessService -{ - private readonly JwtService JwtService; - private readonly List FileAccesses = new(); - - public SharedFileAccessService(JwtService jwtService) - { - JwtService = jwtService; - } - - public Task Register(IFileAccess fileAccess) - { - lock (FileAccesses) - { - if(!FileAccesses.Contains(fileAccess)) - FileAccesses.Add(fileAccess); - } - - return Task.FromResult(fileAccess.GetHashCode()); - } - - public Task Unregister(IFileAccess fileAccess) - { - lock (FileAccesses) - { - if (FileAccesses.Contains(fileAccess)) - FileAccesses.Remove(fileAccess); - } - - return Task.CompletedTask; - } - - public Task Get(int id) - { - lock (FileAccesses) - { - var fileAccess = FileAccesses.FirstOrDefault(x => x.GetHashCode() == id); - - if (fileAccess == null) - return Task.FromResult(null); - - return Task.FromResult(fileAccess.Clone()); - } - } - - public async Task GenerateToken(IFileAccess fileAccess) - { - var token = await JwtService.Create(data => - { - data.Add("FileAccessId", fileAccess.GetHashCode().ToString()); - }, "FileAccess", TimeSpan.FromMinutes(6)); - - return token; - } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/UI/Components/Editor.razor b/Moonlight/Features/FileManager/UI/Components/Editor.razor deleted file mode 100644 index 84b456f..0000000 --- a/Moonlight/Features/FileManager/UI/Components/Editor.razor +++ /dev/null @@ -1,48 +0,0 @@ -@using Moonlight.Features.FileManager.Services -@inject EditorService EditorService - -
    - -@code -{ - [Parameter] public string InitialContent { get; set; } = ""; - [Parameter] public string Theme { get; set; } = "one_dark"; - [Parameter] public string Mode { get; set; } = "text"; - [Parameter] public int Lines { get; set; } = 30; - [Parameter] public int FontSize { get; set; } = 15; - [Parameter] public bool EnableAutoInit { get; set; } = false; - - private string Identifier; - - protected override void OnInitialized() - { - Identifier = "editor" + GetHashCode(); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - if(EnableAutoInit) - await Initialize(); - } - } - - public async Task Initialize() - { - await EditorService.Create( - Identifier, - Theme, - Mode, - InitialContent, - Lines, - FontSize - ); - } - - public async Task GetContent() => await EditorService.GetValue(); - - public async Task SetContent(string content) => await EditorService.SetValue(content); - - public async Task SetMode(string mode) => await EditorService.SetMode(mode); -} diff --git a/Moonlight/Features/FileManager/UI/Components/FileEditor.razor b/Moonlight/Features/FileManager/UI/Components/FileEditor.razor deleted file mode 100644 index 8fb9221..0000000 --- a/Moonlight/Features/FileManager/UI/Components/FileEditor.razor +++ /dev/null @@ -1,115 +0,0 @@ -@inject ToastService ToastService -@inject HotKeyService HotKeyService - -@using Moonlight.Features.FileManager.Models.Abstractions.FileAccess -@using MoonCoreUI.Services -@using Moonlight.Core.Services -@using MoonCore.Helpers -@using Moonlight.Features.FileManager.Helpers - -@implements IDisposable - -
    -
    -
    -
    - @(File.Name) (@(Formatter.FormatSize(File.Size))) -
    -
    - - Back - - - Save - -
    -
    -
    -
    - - - -@code -{ - [Parameter] public FileEntry File { get; set; } - - [Parameter] public IFileAccess FileAccess { get; set; } - - [Parameter] public bool CloseOnSave { get; set; } = false; - - [Parameter] public Func? OnClosed { get; set; } - - private Editor Editor; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - // Initialize the editor - await Editor.Initialize(); - - // Load file and check the file type - var fileData = await FileAccess.ReadFile(File.Name); - var mode = EditorModeDetector.GetModeFromFile(File.Name); - - // Finalize editor - await Editor.SetMode(mode); - await Editor.SetContent(fileData); - - HotKeyService.HotKeyPressed += OnHotKeyPressed; - } - } - - private async Task OnClose() - { - if (OnClosed != null) - await OnClosed.Invoke(); - } - - private async Task OnSave() - { - try - { - var content = await Editor.GetContent(); - await FileAccess.WriteFile(File.Name, content); - } - catch (Exception e) - { - Logger.Warn($"An unhandled error has occured while saving a file using access type {FileAccess.GetType().FullName}"); - Logger.Warn(e); - - await ToastService.Danger("An unknown error has occured while saving the file. Please try again later"); - return; - } - - await ToastService.Success("Successfully saved file"); - - if (CloseOnSave) - { - if (OnClosed != null) - await OnClosed.Invoke(); - } - } - - private async Task OnHotKeyPressed(string hotKey) - { - if (hotKey == "save") - { - await OnSave(); - return; - } - - if (hotKey == "close") - { - await OnClose(); - return; - } - - // Define more hotkeys here - } - - public void Dispose() - { - HotKeyService.HotKeyPressed -= OnHotKeyPressed; - } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/UI/Components/FileManager.razor b/Moonlight/Features/FileManager/UI/Components/FileManager.razor deleted file mode 100644 index c066d6d..0000000 --- a/Moonlight/Features/FileManager/UI/Components/FileManager.razor +++ /dev/null @@ -1,268 +0,0 @@ -@using Moonlight.Features.FileManager.Models.Abstractions.FileAccess -@using Moonlight.Core.Configuration -@using MoonCore.Helpers -@using MoonCore.Services -@using MoonCoreUI.Services - -@inject AlertService AlertService -@inject ConfigService ConfigService -@inject ToastService ToastService - -
    -
    -
    -
    - @{ - var elements = Path - .Split("/") - .Where(x => !string.IsNullOrEmpty(x)) - .ToList(); - - int i = 1; - var root = "/"; - } - - / - @foreach (var element in elements) - { - var pathToCd = "/" + string.Join('/', elements.Take(i)); - - @(element) -
    /
    - - i++; - } -
    -
    -
    - @if (ShowFileUploader) - { - - } - else - { - - - Launch - - - - } -
    -
    -
    - @if (ShowFileUploader) - { - - } - else if (ShowFileEditor) - { - - } - else - { - - } -
    -
    - - - - - - - -@code -{ - [Parameter] public IFileAccess FileAccess { get; set; } - - // Navigation - private string Path = "/"; - private FileView? FileView; - - // Uploading - private bool ShowFileUploader = false; - private FileUploader? FileUploader; - - // Editing - private bool ShowFileEditor = false; - private FileEntry EditorOpenFile; - - // Move - private FileEntry MoveEntry; - private SmartModal MoveModal; - private IFileAccess MoveAccess; - - private async Task OnPathChanged(string path) - { - Path = path; - await InvokeAsync(StateHasChanged); - } - - private async Task NavigateToPath(string path) - { - if (ShowFileUploader) - await ToggleFileUploader(false); - - if (FileView == null) - return; - - await FileView.NavigateToPath(path); - } - - #region Uploader - - private async Task ToggleFileUploader() => await ToggleFileUploader(!ShowFileUploader); - - private async Task ToggleFileUploader(bool b) - { - ShowFileUploader = b; - await InvokeAsync(StateHasChanged); - } - - #endregion - - #region mkdir / touch - - private async Task CreateFile() - { - if (FileView == null) - return; - - var name = await AlertService.Text("Enter the filename", ""); - - await FileAccess.CreateFile(name); - - await FileView.Refresh(); - - // Open editor to start editing - await OpenEditor(new FileEntry() - { - Size = 0, - Name = name, - IsFile = true, - IsDirectory = false, - LastModifiedAt = DateTime.UtcNow - }); - } - - private async Task CreateDirectory() - { - if (FileView == null) - return; - - var name = await AlertService.Text("Enter the foldername", ""); - - await FileAccess.CreateDirectory(name); - - await FileView.Refresh(); - } - - #endregion - - #region Editor - - private async Task OnFileClicked(FileEntry fileEntry) => await OpenEditor(fileEntry); - - private async Task OpenEditor(FileEntry fileEntry) - { - var fileSizeInKilobytes = ByteSizeValue.FromBytes(fileEntry.Size).KiloBytes; - - if (fileSizeInKilobytes > ConfigService.Get().FileManager.MaxFileOpenSize) - { - await ToastService.Danger("Unable to open file as it exceeds the max file size limit"); - return; - } - - EditorOpenFile = fileEntry; - - // Prepare editor - ShowFileEditor = true; - await InvokeAsync(StateHasChanged); - } - - private async Task OnEditorClosed() - { - ShowFileEditor = false; - await InvokeAsync(StateHasChanged); - } - - #endregion - - #region Move - - private async Task StartMove(FileEntry fileEntry) - { - MoveEntry = fileEntry; - MoveAccess = FileAccess.Clone(); - - await MoveAccess.SetDirectory("/"); - await MoveModal.Show(); - } - - private async Task FinishMove() - { - var pathToMove = await MoveAccess.GetCurrentDirectory(); - MoveAccess.Dispose(); - - // Ensure path ends with a / - if (!pathToMove.EndsWith("/")) - pathToMove += "/"; - - // Perform move and process ui updates - await FileAccess.Move(MoveEntry.Name, pathToMove); - - await MoveModal.Hide(); - - if (FileView == null) - return; - - await FileView.Refresh(); - } - - #endregion - -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/UI/Components/FileUploader.razor b/Moonlight/Features/FileManager/UI/Components/FileUploader.razor deleted file mode 100644 index e4a9ac3..0000000 --- a/Moonlight/Features/FileManager/UI/Components/FileUploader.razor +++ /dev/null @@ -1,92 +0,0 @@ -@using Moonlight.Features.FileManager.Models.Abstractions.FileAccess -@using Moonlight.Features.FileManager.Services - -@inject DropzoneService DropzoneService -@inject SharedFileAccessService SharedFileAccessService - -@implements IDisposable - -
    -
    -
    -
    -
    -
    -
    - Drag a file or folder or click to upload files -
    -
    - Upload icon -
    -
    -
    - -
    -
    -
    -
    - -@code -{ - [Parameter] public IFileAccess FileAccess { get; set; } - - private CancellationTokenSource Cancellation = new(); - private string DropzoneId; - - protected override void OnInitialized() - { - DropzoneId = $"dropzone{GetHashCode()}"; - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await SharedFileAccessService.Register(FileAccess); - - var token = await SharedFileAccessService.GenerateToken(FileAccess); - var url = $"/api/upload?token={token}"; - - await DropzoneService.Create(DropzoneId, url); - - Task.Run(async () => // Update the dropzone url every 5 minutes so the token does not expire - { - while (!Cancellation.IsCancellationRequested) - { - await Task.Delay(TimeSpan.FromMinutes(5)); - - var newToken = await SharedFileAccessService.GenerateToken(FileAccess); - var newUrl = $"/api/upload?token={newToken}"; - await DropzoneService.UpdateUrl(DropzoneId, newUrl); - } - }); - } - } - - public async void Dispose() - { - Cancellation.Cancel(); - await SharedFileAccessService.Unregister(FileAccess); - } -} \ No newline at end of file diff --git a/Moonlight/Features/FileManager/UI/Components/FileView.razor b/Moonlight/Features/FileManager/UI/Components/FileView.razor deleted file mode 100644 index f02bfa6..0000000 --- a/Moonlight/Features/FileManager/UI/Components/FileView.razor +++ /dev/null @@ -1,427 +0,0 @@ -@using Moonlight.Features.FileManager.Models.Abstractions.FileAccess -@using MoonCoreUI.Services -@using MoonCore.Helpers -@using Moonlight.Features.FileManager.Services - -@inject ToastService ToastService -@inject AlertService AlertService -@inject SharedFileAccessService SharedFileAccessService -@inject NavigationManager Navigation - -@implements IDisposable - - - - - - @if (ShowHeader) - { - - @if (ShowSelect) - { - - } - @if (ShowIcons) - { - - } - - @if (ShowSize) - { - - } - @if (ShowLastModified) - { - - } - @if (SelectedEntries.Count == 0) - { - - } - else - { - - } - - } - - @if (ShowGoUp && Path != "/" && !DisableNavigation) - { - - @if (ShowSelect) - { - - } - @if (ShowIcons) - { - - } - - @if (ShowSize) - { - - } - @if (ShowLastModified) - { - - } - @if (ShowActions) - { - - } - - } - - @foreach (var entry in Entries) - { - - @if (ShowSelect) - { - - } - @if (ShowIcons) - { - - } - - @if (ShowSize) - { - - } - @if (ShowLastModified) - { - - } - @if (ShowActions) - { - - } - - } - -
    -
    - -
    -
    - Name - - Size - - Last modified at - - @SelectedEntries.Count element(s) selected -
    - - - -
    -
    - - - @{ - var upPath = ".."; - } - - - Go up - - - - - - - - -
    -
    - @if (SelectedEntries.Contains(entry)) - { - - } - else - { - - } -
    -
    - @if (entry.IsFile) - { - - } - else - { - - } - - @if (DisableNavigation) - { - @(entry.Name) - } - else - { - - @(entry.Name) - - } - - @if (entry.IsFile) - { - @(Formatter.FormatSize(entry.Size)) - } - else - { - - - } - - @(Formatter.FormatDate(entry.LastModifiedAt)) - -
    - - - - - -
    -
    -
    - - -@code -{ - [Parameter] public IFileAccess FileAccess { get; set; } - - [Parameter] public Func? Filter { get; set; } - [Parameter] public bool ShowSize { get; set; } = true; - [Parameter] public bool ShowLastModified { get; set; } = true; - [Parameter] public bool ShowIcons { get; set; } = true; - [Parameter] public bool ShowActions { get; set; } = true; - [Parameter] public bool ShowSelect { get; set; } = true; - [Parameter] public bool ShowGoUp { get; set; } = true; - [Parameter] public bool ShowHeader { get; set; } = true; - [Parameter] public bool DisableNavigation { get; set; } = false; - [Parameter] public Func? OnFileClicked { get; set; } - [Parameter] public Func? OnSelectionChanged { get; set; } - [Parameter] public Func? OnPathChanged { get; set; } - [Parameter] public Func? OnMoveRequested { get; set; } - - public readonly List SelectedEntries = new(); - - private LazyLoader LazyLoader; - private FileEntry[] Entries; - private string Path = "/"; - - private async Task Load(LazyLoader lazyLoader) - { - await lazyLoader.SetText("Loading files and folders"); - - // Load all entries - Entries = await FileAccess.List(); - - await lazyLoader.SetText("Sorting files and folders"); - - // Perform sorting and filtering - if (Filter != null) - { - Entries = Entries - .Where(x => Filter.Invoke(x)) - .ToArray(); - } - - Entries = Entries - .GroupBy(x => x.IsFile) - .OrderBy(x => x.Key) - .SelectMany(x => x.OrderBy(y => y.Name)) - .ToArray(); - - SelectedEntries.Clear(); - - Path = await FileAccess.GetCurrentDirectory(); - - if (OnPathChanged != null) - await OnPathChanged.Invoke(Path); - } - - private async Task HandleClick(FileEntry fileEntry) - { - if (fileEntry.IsDirectory && !DisableNavigation) - { - await Navigate(fileEntry.Name); - } - else - { - if (OnFileClicked != null) - await OnFileClicked.Invoke(fileEntry); - } - } - - #region Actions - - private async Task Delete(params FileEntry[] entries) - { - if (entries.Length == 0) - return; - - var toastId = "fileDelete" + GetHashCode(); - await ToastService.CreateProgress(toastId, $"[0/{entries.Length}] Deleting items"); - - int i = 0; - foreach (var entry in entries) - { - await ToastService.ModifyProgress(toastId, $"[{i + 1}/{entries.Length}] Deleting '{entry.Name}'"); - - await FileAccess.Delete(entry.Name); - - i++; - } - - await ToastService.RemoveProgress(toastId); - await ToastService.Success($"Successfully deleted {i} item(s)"); - - await LazyLoader.Reload(); - } - - private async Task Rename(FileEntry fileEntry) - { - var name = await AlertService.Text($"Rename '{fileEntry.Name}'", "", fileEntry.Name); - - if (string.IsNullOrEmpty(name)) - return; - - await FileAccess.Move(fileEntry.Name, name); - - await LazyLoader.Reload(); - } - - private async Task RequestMove(FileEntry fileEntry) - { - if (OnMoveRequested == null) - return; - - await OnMoveRequested.Invoke(fileEntry); - } - - private async Task Download(FileEntry fileEntry) - { - try - { - await SharedFileAccessService.Register(FileAccess); - var token = await SharedFileAccessService.GenerateToken(FileAccess); - var url = $"/api/download?token={token}&name={fileEntry.Name}"; - - await ToastService.Info("Starting download..."); - Navigation.NavigateTo(url, true); - } - catch (Exception e) - { - Logger.Warn("Unable to start download"); - Logger.Warn(e); - - await ToastService.Danger("Failed to start download"); - } - } - - #endregion - - #region Selection - - private async Task HandleSelected(FileEntry fileEntry, ChangeEventArgs args) - { - if (args.Value == null) // This should never be called. Still i want to handle it - return; - - if (args.Value.ToString() == "True") - { - if (!SelectedEntries.Contains(fileEntry)) - SelectedEntries.Add(fileEntry); - } - else - { - if (SelectedEntries.Contains(fileEntry)) - SelectedEntries.Remove(fileEntry); - } - - if (OnSelectionChanged != null) - await OnSelectionChanged.Invoke(); - - await InvokeAsync(StateHasChanged); - } - - private async Task ToggleAll(ChangeEventArgs args) - { - if (args.Value == null) - return; - - if (args.Value.ToString() == "True") - { - foreach (var entry in Entries) - { - if (!SelectedEntries.Contains(entry)) - SelectedEntries.Add(entry); - } - } - else - { - SelectedEntries.Clear(); - } - - await InvokeAsync(StateHasChanged); - } - - #endregion - - #region Navigation - - public async Task Navigate(string name) - { - await LazyLoader.Reload(async loader => - { - await loader.SetText("Switching directory on target"); - await FileAccess.ChangeDirectory(name); - - if (OnPathChanged != null) - await OnPathChanged.Invoke(await FileAccess.GetCurrentDirectory()); - }); - } - - public async Task NavigateToPath(string path) - { - await LazyLoader.Reload(async loader => - { - await loader.SetText("Switching directory on target"); - await FileAccess.SetDirectory(path); - - if (OnPathChanged != null) - await OnPathChanged.Invoke(await FileAccess.GetCurrentDirectory()); - }); - } - - #endregion - - public async Task Refresh() => await LazyLoader.Reload(); - - public async void Dispose() - { - await SharedFileAccessService.Unregister(FileAccess); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Actions/ServerActions.cs b/Moonlight/Features/Servers/Actions/ServerActions.cs deleted file mode 100644 index 6f65e3c..0000000 --- a/Moonlight/Features/Servers/Actions/ServerActions.cs +++ /dev/null @@ -1,157 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Exceptions; -using MoonCore.Helpers; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Models.Enums; -using Moonlight.Features.Servers.Services; -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.ServiceManagement.Models.Abstractions; -using Newtonsoft.Json; - -namespace Moonlight.Features.Servers.Actions; - -public class ServerActions : ServiceActions -{ - public override async Task Create(IServiceProvider provider, Service service) - { - // Load all dependencies from the di - var serverRepo = provider.GetRequiredService>(); - var imageRepo = provider.GetRequiredService>(); - var nodeRepo = provider.GetRequiredService>(); - var allocationRepo = provider.GetRequiredService>(); - var serverService = provider.GetRequiredService(); - - // Parse the configuration file - var config = - JsonConvert.DeserializeObject(service.ConfigJsonOverride ?? service.Product.ConfigJson)!; - - // Load and validate image - - var image = imageRepo - .Get() - .Include(x => x.DockerImages) - .Include(x => x.Variables) - .FirstOrDefault(x => x.Id == config.ImageId); - - if (image == null) - throw new DisplayException("An image with this is is not found"); - - // Load and validate node - - ServerNode? node = null; - - if (config.NodeId != 0) - { - node = nodeRepo - .Get() - .FirstOrDefault(x => x.Id == config.NodeId); - } - - if (node == null) - { - //TODO: Implement auto deploy - throw new DisplayException("Auto deploy has not been implemented yet. Please specify the node id in the product configuration"); - } - - // Load and validate server allocations - ServerAllocation[] allocations = Array.Empty(); - - if (config.DedicatedIp) - { - throw new DisplayException("The dedicated ip mode has not been implemented yet. Please disable the dedicated ip option in the product configuration"); - } - else - { - allocations = allocationRepo - .Get() - .FromSqlRaw( - $"SELECT * FROM `ServerAllocations` WHERE ServerId IS NULL AND ServerNodeId={node.Id} LIMIT {image.AllocationsNeeded}") - .ToArray(); - } - - if (allocations.Length < 1 || allocations.Length < image.AllocationsNeeded) - throw new DisplayException($"Not enough free allocations found on node '{node.Name}'"); - - // Build server db model - - var server = new Server() - { - Service = service, - Cpu = config.Cpu, - Memory = config.Memory, - Disk = config.Disk, - Node = node, - MainAllocation = allocations.First(), - Image = image, - OverrideStartupCommand = null, - DockerImageIndex = image.DefaultDockerImageIndex - }; - - // Add allocations - foreach (var allocation in allocations) - server.Allocations.Add(allocation); - - // Add variables - foreach (var variable in image.Variables) - { - server.Variables.Add(new() - { - Key = variable.Key, - Value = variable.DefaultValue - }); - } - - serverRepo.Add(server); - - await serverService.Sync(server); - await serverService.Console.SendAction(server, PowerAction.Install); - } - - public override Task Update(IServiceProvider provider, Service service) - { - throw new NotImplementedException(); - } - - public override async Task Delete(IServiceProvider provider, Service service) - { - // Load dependencies from di - var serverRepo = provider.GetRequiredService>(); - var serverService = provider.GetRequiredService(); - var serverVariableRepo = provider.GetRequiredService>(); - - // Load server - var server = serverRepo - .Get() - .Include(x => x.Variables) - .Include(x => x.MainAllocation) - .FirstOrDefault(x => x.Service.Id == service.Id); - - // Check if server already has been deleted - if (server == null) - { - Logger.Warn($"Server for service {service.Id} is missing when trying to delete the service. Maybe it already has been deleted"); - return; - } - - // Notify the node - await serverService.SyncDelete(server); - - // Clear and delete the variables - var variables = server.Variables.ToArray(); - - server.Variables.Clear(); - - serverRepo.Update(server); - - try - { - foreach (var variable in variables) - serverVariableRepo.Delete(variable); - } - catch (Exception) { /* ignored, as we dont want a operation to fail which just deletes some old data */ } - - // Delete the model - serverRepo.Delete(server); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Actions/ServerConfig.cs b/Moonlight/Features/Servers/Actions/ServerConfig.cs deleted file mode 100644 index 83b7135..0000000 --- a/Moonlight/Features/Servers/Actions/ServerConfig.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.ComponentModel; - -namespace Moonlight.Features.Servers.Actions; - -public class ServerConfig -{ - [Description("The amount of cpu cores for a server instance. 100% = 1 Core")] - public int Cpu { get; set; } = 100; - - [Description("The amount of memory in megabytes for a server instance")] - public int Memory { get; set; } = 1024; - - [Description("The amount of disk space in megabytes for a server instance")] - public int Disk { get; set; } = 1024; - - [Description("The id of the image to use for a server")] - public int ImageId { get; set; } = 1; - - [Description( - "The id of the node to use for the server. If not set, moonlight will search automaticly for the best node to deploy on")] - public int NodeId { get; set; } = 0; - - [Description( - "This options specifies if moonlight should give the server an allocation which ip has not been used by another server. So the server will has its own ip")] - public bool DedicatedIp { get; set; } = false; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Actions/ServerServiceDefinition.cs b/Moonlight/Features/Servers/Actions/ServerServiceDefinition.cs deleted file mode 100644 index 630d9b0..0000000 --- a/Moonlight/Features/Servers/Actions/ServerServiceDefinition.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Moonlight.Features.Servers.UI.Layouts; -using Moonlight.Features.Servers.UI.UserViews; -using Moonlight.Features.ServiceManagement.Models.Abstractions; -using Console = Moonlight.Features.Servers.UI.UserViews.Console; - -namespace Moonlight.Features.Servers.Actions; - -public class ServerServiceDefinition : ServiceDefinition -{ - public override ServiceActions Actions => new ServerActions(); - public override Type ConfigType => typeof(ServerConfig); - - public override async Task BuildUserView(ServiceViewContext context) - { - context.Layout = typeof(UserLayout); - - await context.AddPage("Console", "/", "bx bx-sm bxs-terminal"); - await context.AddPage("Files", "/files", "bx bx-sm bxs-folder"); - await context.AddPage("Network", "/network", "bx bx-sm bx-cloud"); - await context.AddPage("Schedules", "/schedules", "bx bx-sm bx-timer"); - await context.AddPage("Variables", "/variables", "bx bx-sm bx-slider"); - await context.AddPage("Reset", "/reset", "bx bx-sm bx-revision"); - } - - public override Task BuildAdminView(ServiceViewContext context) - { - throw new NotImplementedException(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Api/Packets/ServerOutputMessage.cs b/Moonlight/Features/Servers/Api/Packets/ServerOutputMessage.cs deleted file mode 100644 index fb870b0..0000000 --- a/Moonlight/Features/Servers/Api/Packets/ServerOutputMessage.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Moonlight.Features.Servers.Api.Packets; - -public class ServerOutputMessage -{ - public int Id { get; set; } - public string Message { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Api/Packets/ServerStateUpdate.cs b/Moonlight/Features/Servers/Api/Packets/ServerStateUpdate.cs deleted file mode 100644 index 79304aa..0000000 --- a/Moonlight/Features/Servers/Api/Packets/ServerStateUpdate.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Moonlight.Features.Servers.Models.Enums; - -namespace Moonlight.Features.Servers.Api.Packets; - -public class ServerStateUpdate -{ - public int Id { get; set; } - public ServerState State { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Api/Requests/SendCommand.cs b/Moonlight/Features/Servers/Api/Requests/SendCommand.cs deleted file mode 100644 index 0101aab..0000000 --- a/Moonlight/Features/Servers/Api/Requests/SendCommand.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Moonlight.Features.Servers.Api.Requests; - -public class SendCommand -{ - public string Command { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/BackgroundServices/InitBackgroundService.cs b/Moonlight/Features/Servers/BackgroundServices/InitBackgroundService.cs deleted file mode 100644 index 24763f8..0000000 --- a/Moonlight/Features/Servers/BackgroundServices/InitBackgroundService.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System.Net.Sockets; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Helpers; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Services; -using BackgroundService = MoonCore.Abstractions.BackgroundService; - -namespace Moonlight.Features.Servers.BackgroundServices; - -[BackgroundService] -public class InitBackgroundService : BackgroundService -{ - private readonly IServiceProvider ServiceProvider; - - public InitBackgroundService(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public override async Task Run() - { - Logger.Info("Booting all nodes"); - - using var scope = ServiceProvider.CreateScope(); - - var nodeRepo = scope.ServiceProvider.GetRequiredService>(); - var nodeService = scope.ServiceProvider.GetRequiredService(); - - foreach (var node in nodeRepo.Get().ToArray()) - { - try - { - await nodeService.Boot(node); - } - catch (HttpRequestException e) - { - if(e.InnerException is SocketException socketException) - Logger.Warn($"Unable to auto boot node '{node.Name}'. Unable to reach the daemon: {socketException.Message}"); - else - { - Logger.Warn($"An error occured while booting node '{node.Name}'"); - Logger.Warn(e); - } - } - catch (Exception e) - { - Logger.Warn($"An error occured while booting node '{node.Name}'"); - Logger.Warn(e); - } - } - - Logger.Info("Booted all nodes"); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/BackgroundServices/ScheduleRunnerService.cs b/Moonlight/Features/Servers/BackgroundServices/ScheduleRunnerService.cs deleted file mode 100644 index 7be1ec7..0000000 --- a/Moonlight/Features/Servers/BackgroundServices/ScheduleRunnerService.cs +++ /dev/null @@ -1,125 +0,0 @@ -using Cronos; -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Helpers; -using MoonCore.Services; -using Moonlight.Core.Configuration; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Entities.Enums; -using Moonlight.Features.Servers.Services; -using BackgroundService = MoonCore.Abstractions.BackgroundService; - -namespace Moonlight.Features.Servers.BackgroundServices; - -public class ScheduleRunnerService : BackgroundService -{ - private readonly IServiceProvider ServiceProvider; - private readonly ConfigService ConfigService; - - public ScheduleRunnerService(IServiceProvider serviceProvider, ConfigService configService) - { - ServiceProvider = serviceProvider; - ConfigService = configService; - } - - public override async Task Run() - { - var config = ConfigService.Get().Servers.Schedules; - - if(config.Disable) - Logger.Info("Server schedules are disabled"); - - while (!Cancellation.IsCancellationRequested) - { - Logger.Debug("Performing scheduler run"); - - // Resolve services from di - using var scope = ServiceProvider.CreateScope(); - var serverRepo = scope.ServiceProvider.GetRequiredService>(); - var scheduleRepo = scope.ServiceProvider.GetRequiredService>(); - var serverService = scope.ServiceProvider.GetRequiredService(); - - // Load required data - var servers = serverRepo - .Get() - .Include(x => x.Schedules) - .Where(x => x.Schedules.Any()) - .ToArray(); - - Logger.Debug($"Found {servers.Length} servers with schedules"); - - foreach (var server in servers) - { - foreach (var schedule in server.Schedules) - { - if (!CronExpression.TryParse(schedule.Cron, CronFormat.Standard, out CronExpression cronExpression)) - { - Logger.Warn($"Unable to parse cron expression for schedule '{schedule.Name}' for server '{server.Id}'"); - continue; - } - - var nextRun = cronExpression.GetNextOccurrence(schedule.LastRunAt, TimeZoneInfo.Utc); - - if (nextRun == null) - { - Logger.Warn($"Unable to determine next run time for schedule '{schedule.Name}' for server '{server.Id}'"); - continue; - } - - // Check if the next run is in the past - if (DateTime.UtcNow > nextRun) - { - var diff = DateTime.UtcNow - nextRun; - - if(diff.Value.TotalMinutes > 0) - Logger.Warn($"Missed executing schedule '{schedule.Name}' for server '{server.Id}'. Was moonlight offline for a while?"); - else - Logger.Warn($"Missed executing schedule '{schedule.Name}' for server '{server.Id}'. The miss difference ({diff.Value.TotalSeconds}s) indicate a miss configuration. Increase your time drift or lower your check delay to fix the error"); - - schedule.LastRunAt = DateTime.UtcNow; - schedule.WasLastRunAutomatic = false; - - scheduleRepo.Update(schedule); - continue; - } - - // Check if the next run is too far in the future - if ((nextRun - DateTime.UtcNow).Value.TotalSeconds > config.TimeDrift) - continue; - - // Its time to execute the schedule :D - await RunSchedule(server, schedule, scope.ServiceProvider); - - schedule.LastRunAt = DateTime.UtcNow; - schedule.WasLastRunAutomatic = true; - - scheduleRepo.Update(schedule); - } - } - - await Task.Delay(config.CheckDelay, Cancellation.Token); - } - } - - public async Task RunSchedule(Server server, ServerSchedule schedule, IServiceProvider? provider = null) - { - IServiceProvider serviceProvider; - - if (provider != null) - serviceProvider = provider; - else - serviceProvider = ServiceProvider.CreateScope().ServiceProvider; - - switch (schedule.ActionType) - { - case ScheduleActionType.Power: - - //TODO: Implement actual action here - - break; - default: - Logger.Warn($"Schedule action type {schedule.ActionType} has not been implemented yet"); - break; - } - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Configuration/ServersData.cs b/Moonlight/Features/Servers/Configuration/ServersData.cs deleted file mode 100644 index cfda890..0000000 --- a/Moonlight/Features/Servers/Configuration/ServersData.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using Newtonsoft.Json; - -namespace Moonlight.Features.Servers.Configuration; - -public class ServersData -{ - [JsonProperty("Schedules")] public SchedulesData Schedules { get; set; } = new(); - - public class SchedulesData - { - [JsonProperty("Disable")] - [Description("This flag stops the schedule execution system from starting. Changing this requires a restart")] - public bool Disable { get; set; } = false; - - [JsonProperty("SchedulePerServer")] - [Description("This specifies the schedules a user can create for a server")] - public int SchedulePerServer { get; set; } = 10; - - [JsonProperty("CheckDelay")] - [Description("The delay in seconds between every schedule run")] - public int CheckDelay { get; set; } = 10; - - [JsonProperty("TimeDrift")] - [Description( - "The amount of seconds the planned execution time is allowed to vary to the current time and still be executed")] - public int TimeDrift { get; set; } = 30; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/Enums/ScheduleActionType.cs b/Moonlight/Features/Servers/Entities/Enums/ScheduleActionType.cs deleted file mode 100644 index c32a0a8..0000000 --- a/Moonlight/Features/Servers/Entities/Enums/ScheduleActionType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.Servers.Entities.Enums; - -public enum ScheduleActionType -{ - Command = 0, - Power = 1, - Backup = 2 -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/Server.cs b/Moonlight/Features/Servers/Entities/Server.cs deleted file mode 100644 index 78e0351..0000000 --- a/Moonlight/Features/Servers/Entities/Server.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Moonlight.Features.ServiceManagement.Entities; - -namespace Moonlight.Features.Servers.Entities; - -public class Server -{ - public int Id { get; set; } - public Service Service { get; set; } - - public int Cpu { get; set; } - public int Memory { get; set; } - public int Disk { get; set; } - - public ServerImage Image { get; set; } - public int DockerImageIndex { get; set; } - public string? OverrideStartupCommand { get; set; } - public List Variables { get; set; } = new(); - - public ServerNode Node { get; set; } - public ServerAllocation MainAllocation { get; set; } - public List Allocations { get; set; } = new(); - - public List Schedules { get; set; } = new(); -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/ServerAllocation.cs b/Moonlight/Features/Servers/Entities/ServerAllocation.cs deleted file mode 100644 index b1c75c9..0000000 --- a/Moonlight/Features/Servers/Entities/ServerAllocation.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.Servers.Entities; - -public class ServerAllocation -{ - public int Id { get; set; } - public string IpAddress { get; set; } = "0.0.0.0"; - public int Port { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/ServerDockerImage.cs b/Moonlight/Features/Servers/Entities/ServerDockerImage.cs deleted file mode 100644 index cfc302e..0000000 --- a/Moonlight/Features/Servers/Entities/ServerDockerImage.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Moonlight.Features.Servers.Entities; - -public class ServerDockerImage -{ - public int Id { get; set; } - public string Name { get; set; } - public string DisplayName { get; set; } - public bool AutoPull { get; set; } = true; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/ServerImage.cs b/Moonlight/Features/Servers/Entities/ServerImage.cs deleted file mode 100644 index 9fc4e8f..0000000 --- a/Moonlight/Features/Servers/Entities/ServerImage.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace Moonlight.Features.Servers.Entities; - -public class ServerImage -{ - public int Id { get; set; } - public string Name { get; set; } - - public int AllocationsNeeded { get; set; } - public string StartupCommand { get; set; } - public string StopCommand { get; set; } - public string OnlineDetection { get; set; } - public string ParseConfigurations { get; set; } = "[]"; - - public string InstallDockerImage { get; set; } - public string InstallShell { get; set; } - public string InstallScript { get; set; } - - public string Author { get; set; } - public string? DonateUrl { get; set; } - public string? UpdateUrl { get; set; } - - public List Variables { get; set; } = new(); - - public int DefaultDockerImageIndex { get; set; } = 0; - public bool AllowUserToChangeDockerImage { get; set; } - public List DockerImages { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/ServerImageVariable.cs b/Moonlight/Features/Servers/Entities/ServerImageVariable.cs deleted file mode 100644 index bda1a4a..0000000 --- a/Moonlight/Features/Servers/Entities/ServerImageVariable.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Moonlight.Features.Servers.Entities; - -public class ServerImageVariable -{ - public int Id { get; set; } - public string Key { get; set; } - public string DefaultValue { get; set; } - - public string DisplayName { get; set; } - public string Description { get; set; } - public bool AllowUserToEdit { get; set; } - public bool AllowUserToView { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/ServerNode.cs b/Moonlight/Features/Servers/Entities/ServerNode.cs deleted file mode 100644 index 59dd514..0000000 --- a/Moonlight/Features/Servers/Entities/ServerNode.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Moonlight.Features.Servers.Entities; - -public class ServerNode -{ - public int Id { get; set; } - public string Name { get; set; } - - public string Fqdn { get; set; } - public bool UseSsl { get; set; } - public string Token { get; set; } - public int HttpPort { get; set; } - public int FtpPort { get; set; } - - public List Allocations { get; set; } = new(); -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/ServerSchedule.cs b/Moonlight/Features/Servers/Entities/ServerSchedule.cs deleted file mode 100644 index 44c29e3..0000000 --- a/Moonlight/Features/Servers/Entities/ServerSchedule.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Moonlight.Features.Servers.Entities.Enums; - -namespace Moonlight.Features.Servers.Entities; - -public class ServerSchedule -{ - public int Id { get; set; } - public string Name { get; set; } - public string Cron { get; set; } - - public ScheduleActionType ActionType { get; set; } - public string ActionData { get; set; } = ""; - - public DateTime LastRunAt { get; set; } = DateTime.Now; - public bool WasLastRunAutomatic { get; set; } = false; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Entities/ServerVariable.cs b/Moonlight/Features/Servers/Entities/ServerVariable.cs deleted file mode 100644 index 92f892e..0000000 --- a/Moonlight/Features/Servers/Entities/ServerVariable.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.Servers.Entities; - -public class ServerVariable -{ - public int Id { get; set; } - public string Key { get; set; } - public string Value { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Exceptions/NodeException.cs b/Moonlight/Features/Servers/Exceptions/NodeException.cs deleted file mode 100644 index 0991dd8..0000000 --- a/Moonlight/Features/Servers/Exceptions/NodeException.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace Moonlight.Features.Servers.Exceptions; - -public class NodeException : Exception -{ - public NodeException() - { - } - - public NodeException(string message) : base(message) - { - } - - public NodeException(string message, Exception inner) : base(message, inner) - { - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Extensions/Attributes/EnableNodeMiddlewareAttribute.cs b/Moonlight/Features/Servers/Extensions/Attributes/EnableNodeMiddlewareAttribute.cs deleted file mode 100644 index 4fa7ced..0000000 --- a/Moonlight/Features/Servers/Extensions/Attributes/EnableNodeMiddlewareAttribute.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Moonlight.Features.Servers.Extensions.Attributes; - -public class EnableNodeMiddlewareAttribute : Attribute -{ - -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Extensions/NodeExtensions.cs b/Moonlight/Features/Servers/Extensions/NodeExtensions.cs deleted file mode 100644 index ee4c7ae..0000000 --- a/Moonlight/Features/Servers/Extensions/NodeExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using MoonCore.Helpers; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Exceptions; - -namespace Moonlight.Features.Servers.Extensions; - -public static class NodeExtensions -{ - public static HttpApiClient CreateHttpClient(this ServerNode node) - { - var protocol = node.UseSsl ? "https" : "http"; - var remoteUrl = $"{protocol}://{node.Fqdn}:{node.HttpPort}/"; - - return new HttpApiClient(remoteUrl, node.Token); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Extensions/ServerExtensions.cs b/Moonlight/Features/Servers/Extensions/ServerExtensions.cs deleted file mode 100644 index aeb06f6..0000000 --- a/Moonlight/Features/Servers/Extensions/ServerExtensions.cs +++ /dev/null @@ -1,91 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Helpers; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Exceptions; -using Moonlight.Features.Servers.Models.Abstractions; - -namespace Moonlight.Features.Servers.Extensions; - -public static class ServerExtensions -{ - public static ServerConfiguration ToServerConfiguration(this Server server) - { - var serverConfiguration = new ServerConfiguration(); - - // Set general information - serverConfiguration.Id = server.Id; - - // Set variables - serverConfiguration.Variables = server.Variables - .ToDictionary(x => x.Key, x => x.Value); - - // Set server image - serverConfiguration.Image = new() - { - OnlineDetection = server.Image.OnlineDetection, - ParseConfigurations = server.Image.ParseConfigurations, - StartupCommand = server.Image.StartupCommand, - StopCommand = server.Image.StopCommand - }; - - // Find docker image by index - ServerDockerImage dockerImage; - - if (server.DockerImageIndex >= server.Image.DockerImages.Count || server.DockerImageIndex == -1) - dockerImage = server.Image.DockerImages.Last(); - else - dockerImage = server.Image.DockerImages[server.DockerImageIndex]; - - serverConfiguration.Image.DockerImage = dockerImage.Name; - serverConfiguration.Image.PullDockerImage = dockerImage.AutoPull; - - // Set server limits - serverConfiguration.Limits = new() - { - Cpu = server.Cpu, - Memory = server.Memory, - Disk = server.Disk - }; - - // Set allocations - serverConfiguration.Allocations = server.Allocations.Select(x => new ServerConfiguration.AllocationData() - { - IpAddress = x.IpAddress, - Port = x.Port - }).ToList(); - - // Set main allocation - serverConfiguration.MainAllocation = new() - { - IpAddress = server.MainAllocation.IpAddress, - Port = server.MainAllocation.Port - }; - - return serverConfiguration; - } - - public static ServerInstallConfiguration ToServerInstallConfiguration(this Server server) - { - var installConfiguration = new ServerInstallConfiguration(); - - installConfiguration.DockerImage = server.Image.InstallDockerImage; - installConfiguration.Script = server.Image.InstallScript; - installConfiguration.Shell = server.Image.InstallShell; - - return installConfiguration; - } - - public static HttpApiClient CreateHttpClient(this Server server, IServiceProvider serviceProvider) - { - using var scope = serviceProvider.CreateScope(); - var serverRepo = scope.ServiceProvider.GetRequiredService>(); - - var serverWithNode = serverRepo - .Get() - .Include(x => x.Node) - .First(x => x.Id == server.Id); - - return serverWithNode.Node.CreateHttpClient(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Helpers/MetaCache.cs b/Moonlight/Features/Servers/Helpers/MetaCache.cs deleted file mode 100644 index cb25932..0000000 --- a/Moonlight/Features/Servers/Helpers/MetaCache.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Moonlight.Features.Servers.Helpers; - -public class MetaCache -{ - private readonly Dictionary Cache = new(); - - public Task Update(int id, Action metaAction) - { - lock (Cache) - { - T? meta = default; - - if (Cache.ContainsKey(id)) - meta = Cache[id]; - - if (meta == null) - { - meta = Activator.CreateInstance(); - Cache.Add(id, meta); - } - - metaAction.Invoke(meta); - } - - return Task.CompletedTask; - } - - public Task Get(int id) - { - lock (Cache) - { - if(!Cache.ContainsKey(id)) - Cache.Add(id, Activator.CreateInstance()); - - return Task.FromResult(Cache[id]); - } - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Helpers/ServerFtpFileAccess.cs b/Moonlight/Features/Servers/Helpers/ServerFtpFileAccess.cs deleted file mode 100644 index bd6bdf8..0000000 --- a/Moonlight/Features/Servers/Helpers/ServerFtpFileAccess.cs +++ /dev/null @@ -1,259 +0,0 @@ -using System.Net; -using System.Text; -using FluentFTP; -using MoonCore.Helpers; -using Moonlight.Features.FileManager.Models.Abstractions.FileAccess; - -namespace Moonlight.Features.Servers.Helpers; - -public class ServerFtpFileAccess : IFileAccess -{ - private FtpClient Client; - private string CurrentDirectory = "/"; - - private readonly string Host; - private readonly int Port; - private readonly string Username; - private readonly string Password; - private readonly int OperationTimeout; - - public ServerFtpFileAccess(string host, int port, string username, string password, int operationTimeout = 5) - { - Host = host; - Port = port; - Username = username; - Password = password; - OperationTimeout = (int)TimeSpan.FromSeconds(5).TotalMilliseconds; - - Client = CreateClient(); - } - - public async Task List() - { - return await ExecuteHandled(() => - { - var items = Client.GetListing() ?? Array.Empty(); - var result = items.Select(item => new FileEntry - { - Name = item.Name, - IsDirectory = item.Type == FtpObjectType.Directory, - IsFile = item.Type == FtpObjectType.File, - LastModifiedAt = item.Modified, - Size = item.Size - }).ToArray(); - - return Task.FromResult(result); - }); - } - - public async Task ChangeDirectory(string relativePath) - { - await ExecuteHandled(() => - { - var newPath = Path.Combine(CurrentDirectory, relativePath); - newPath = Path.GetFullPath(newPath); - - Client.SetWorkingDirectory(newPath); - CurrentDirectory = Client.GetWorkingDirectory(); - - return Task.CompletedTask; - }); - } - - public async Task SetDirectory(string path) - { - await ExecuteHandled(() => - { - Client.SetWorkingDirectory(path); - CurrentDirectory = Client.GetWorkingDirectory(); - - return Task.CompletedTask; - }); - } - - public Task GetCurrentDirectory() - { - return Task.FromResult(CurrentDirectory); - } - - public async Task Delete(string path) - { - await ExecuteHandled(() => - { - if (Client.FileExists(path)) - Client.DeleteFile(path); - else - Client.DeleteDirectory(path); - - return Task.CompletedTask; - }); - } - - public async Task Move(string from, string to) - { - await ExecuteHandled(() => - { - var fromEntry = Client.GetObjectInfo(from); - - var dest = to + Path.GetFileName(from); - var fromWithSlash = from.StartsWith("/") ? from : "/" + from; - - if (fromWithSlash == dest) - return Task.CompletedTask; - - if (fromEntry.Type == FtpObjectType.Directory) - // We need to add the folder name here, because some ftp servers would refuse to move the folder if its missing - Client.MoveDirectory(from, dest); - else - // We need to add the file name here, because some ftp servers would refuse to move the file if its missing - Client.MoveFile(from, dest); - - return Task.CompletedTask; - }); - } - - public async Task CreateDirectory(string name) - { - await ExecuteHandled(() => - { - Client.CreateDirectory(name); - return Task.CompletedTask; - }); - } - - public async Task CreateFile(string name) - { - await ExecuteHandled(() => - { - using var stream = new MemoryStream(); - Client.UploadStream(stream, name); - - return Task.CompletedTask; - }); - } - - public async Task ReadFile(string name) - { - return await ExecuteHandled(async () => - { - await using var stream = Client.OpenRead(name); - using var reader = new StreamReader(stream, Encoding.UTF8); - return await reader.ReadToEndAsync(); - }); - } - - public async Task WriteFile(string name, string content) - { - await ExecuteHandled(() => - { - using var stream = new MemoryStream(Encoding.UTF8.GetBytes(content)); - Client.UploadStream(stream, name); - - return Task.CompletedTask; - }); - } - - public async Task ReadFileStream(string name) - { - return await ExecuteHandled(() => - { - var stream = Client.OpenRead(name); - return Task.FromResult(stream); - }); - } - - public async Task WriteFileStream(string name, Stream dataStream) - { - await ExecuteHandled(() => - { - Client.UploadStream(dataStream, name, FtpRemoteExists.Overwrite); - return Task.CompletedTask; - }); - } - - public IFileAccess Clone() - { - return new ServerFtpFileAccess(Host, Port, Username, Password) - { - CurrentDirectory = CurrentDirectory - }; - } - - public void Dispose() - { - Client.Dispose(); - } - - #region Helpers - - private Task EnsureConnected() - { - if (!Client.IsConnected) - { - Client.Connect(); - - // This will set the correct current directory - // on cloned or reconnected FtpFileAccess instances - if(CurrentDirectory != "/") - Client.SetWorkingDirectory(CurrentDirectory); - } - - return Task.CompletedTask; - } - - private async Task ExecuteHandled(Func func) - { - try - { - await EnsureConnected(); - await func.Invoke(); - } - catch (TimeoutException) - { - Client.Dispose(); - Client = CreateClient(); - - await EnsureConnected(); - - await func.Invoke(); - } - } - - private async Task ExecuteHandled(Func> func) - { - try - { - await EnsureConnected(); - return await func.Invoke(); - } - catch (TimeoutException) - { - Client.Dispose(); - Client = CreateClient(); - - await EnsureConnected(); - - return await func.Invoke(); - } - } - - - - private FtpClient CreateClient() - { - var client = new FtpClient(); - client.Host = Host; - client.Port = Port; - client.Credentials = new NetworkCredential(Username, Password); - client.Config.DataConnectionType = FtpDataConnectionType.PASV; - - client.Config.ConnectTimeout = OperationTimeout; - client.Config.ReadTimeout = OperationTimeout; - client.Config.DataConnectionConnectTimeout = OperationTimeout; - client.Config.DataConnectionReadTimeout = OperationTimeout; - - return client; - } - - #endregion -} diff --git a/Moonlight/Features/Servers/Http/Controllers/FtpController.cs b/Moonlight/Features/Servers/Http/Controllers/FtpController.cs deleted file mode 100644 index 215be2f..0000000 --- a/Moonlight/Features/Servers/Http/Controllers/FtpController.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Helpers; -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Services.Utils; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Extensions.Attributes; -using Moonlight.Features.Servers.Http.Requests; -using Moonlight.Features.ServiceManagement.Services; - -namespace Moonlight.Features.Servers.Http.Controllers; - -[ApiController] -[Route("api/servers/ftp")] -[EnableNodeMiddleware] -public class FtpController : Controller -{ - private readonly IServiceProvider ServiceProvider; - private readonly JwtService JwtService; - - public FtpController( - IServiceProvider serviceProvider, - JwtService jwtService) - { - ServiceProvider = serviceProvider; - JwtService = jwtService; - } - - [HttpPost] - public async Task Post([FromBody] FtpLogin login) - { - // If it looks like a jwt, try authenticate it - if (await TryJwtLogin(login)) - return Ok(); - - // Search for user - var userRepo = ServiceProvider.GetRequiredService>(); - var user = userRepo - .Get() - .FirstOrDefault(x => x.Username == login.Username); - - // Unknown user - if (user == null) - return StatusCode(403); - - // Check password - if (!HashHelper.Verify(login.Password, user.Password)) - { - Logger.Warn($"A failed login attempt via ftp has occured. Username: '{login.Username}', Server Id: '{login.ServerId}'"); - return StatusCode(403); - } - - // Load node from context - var node = HttpContext.Items["Node"] as ServerNode; - - // Load server from db - var serverRepo = ServiceProvider.GetRequiredService>(); - var server = serverRepo - .Get() - .Include(x => x.Service) - .FirstOrDefault(x => x.Id == login.ServerId && x.Node.Id == node!.Id); - - // Unknown server or wrong node? - if (server == null) - return StatusCode(403); - - var serviceManageService = ServiceProvider.GetRequiredService(); - - // Has user access to this server? - if (await serviceManageService.CheckAccess(server.Service, user)) - return Ok(); - - return StatusCode(403); - } - - private async Task TryJwtLogin(FtpLogin login) - { - if (!await JwtService.Validate(login.Password, "FtpServerLogin")) - return false; - - var data = await JwtService.Decode(login.Password); - - if (!data.ContainsKey("ServerId")) - return false; - - if (!int.TryParse(data["ServerId"], out int serverId)) - return false; - - return login.ServerId == serverId; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Http/Controllers/NodeController.cs b/Moonlight/Features/Servers/Http/Controllers/NodeController.cs deleted file mode 100644 index e613f06..0000000 --- a/Moonlight/Features/Servers/Http/Controllers/NodeController.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System.Net.WebSockets; -using Microsoft.AspNetCore.Mvc; -using MoonCore.Helpers; -using Moonlight.Features.Servers.Api.Packets; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Extensions.Attributes; -using Moonlight.Features.Servers.Services; - -namespace Moonlight.Features.Servers.Http.Controllers; - -[ApiController] -[Route("api/servers/node")] -[EnableNodeMiddleware] -public class NodeController : Controller -{ - private readonly NodeService NodeService; - private readonly ServerService ServerService; - - public NodeController(NodeService nodeService, ServerService serverService) - { - NodeService = nodeService; - ServerService = serverService; - } - - [HttpPost("notify/start")] - public async Task NotifyBootStart() - { - // Load node from request context - var node = (HttpContext.Items["Node"] as ServerNode)!; - - await NodeService.Meta.Update(node.Id, meta => { meta.IsBooting = true; }); - - return Ok(); - } - - [HttpPost("notify/finish")] - public async Task NotifyBootFinish() - { - // Load node from request context - var node = (HttpContext.Items["Node"] as ServerNode)!; - - await NodeService.Meta.Update(node.Id, meta => { meta.IsBooting = false; }); - - return Ok(); - } - - [HttpGet("ws")] - public async Task Ws() - { - // Validate if it is even a websocket connection - if (!HttpContext.WebSockets.IsWebSocketRequest) - return BadRequest("This endpoint is only available for websockets"); - - // Accept websocket connection - var websocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); - - // Build connection wrapper - var wsPacketConnection = new WsPacketConnection(websocket); - - // Register packets - await wsPacketConnection.RegisterPacket("serverStateUpdate"); - await wsPacketConnection.RegisterPacket("serverOutputMessage"); - - while (websocket.State == WebSocketState.Open) - { - var packet = await wsPacketConnection.Receive(); - - if (packet is ServerStateUpdate serverStateUpdate) - { - await ServerService.Meta.Update(serverStateUpdate.Id, meta => - { - meta.State = serverStateUpdate.State; - meta.LastChangeTimestamp = DateTime.UtcNow; - }); - - await (await ServerService.Meta.Get(serverStateUpdate.Id)).OnStateChanged.Invoke(); - } - - if (packet is ServerOutputMessage serverOutputMessage) - { - await ServerService.Meta.Update(serverOutputMessage.Id, meta => - { - lock (meta.ConsoleMessages) - meta.ConsoleMessages.Add(serverOutputMessage.Message); - }); - - await (await ServerService.Meta.Get(serverOutputMessage.Id)).OnConsoleMessage.Invoke(serverOutputMessage - .Message); - } - } - - await wsPacketConnection.Close(); - - return Ok(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Http/Controllers/ServersControllers.cs b/Moonlight/Features/Servers/Http/Controllers/ServersControllers.cs deleted file mode 100644 index 3d81e46..0000000 --- a/Moonlight/Features/Servers/Http/Controllers/ServersControllers.cs +++ /dev/null @@ -1,113 +0,0 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Helpers; - - -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Extensions; -using Moonlight.Features.Servers.Extensions.Attributes; -using Moonlight.Features.Servers.Models.Abstractions; - -namespace Moonlight.Features.Servers.Http.Controllers; - -[ApiController] -[Route("api/servers")] -[EnableNodeMiddleware] -public class ServersControllers : Controller -{ - private readonly Repository ServerRepository; - - public ServersControllers(Repository serverRepository) - { - ServerRepository = serverRepository; - } - - [HttpGet("ws")] - public async Task GetAllServersWs() - { - // Validate if it is even a websocket connection - if (!HttpContext.WebSockets.IsWebSocketRequest) - return BadRequest("This endpoint is only available for websockets"); - - // Accept websocket connection - var websocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); - - // Build connection wrapper - var wsPacketConnection = new WsPacketConnection(websocket); - await wsPacketConnection.RegisterPacket("amount"); - await wsPacketConnection.RegisterPacket("serverConfiguration"); - - // Read server data for the node - var node = (HttpContext.Items["Node"] as ServerNode)!; - - // Load server data with including the relational data - var servers = ServerRepository - .Get() - .Include(x => x.Allocations) - .Include(x => x.Variables) - .Include(x => x.MainAllocation) - .Include(x => x.Image) - .ThenInclude(x => x.DockerImages) - .Where(x => x.Node.Id == node.Id) - .ToArray(); - - // Convert the data to server configurations - var serverConfigurations = servers - .Select(x => x.ToServerConfiguration()) - .ToArray(); - - // Send the amount of configs the node will receive - await wsPacketConnection.Send(servers.Length); - - // Send the server configurations - foreach (var serverConfiguration in serverConfigurations) - await wsPacketConnection.Send(serverConfiguration); - - await wsPacketConnection.WaitForClose(); - - return Ok(); - } - - [HttpGet("{id:int}")] - public async Task> GetServerById(int id) - { - var node = (HttpContext.Items["Node"] as ServerNode)!; - - var server = ServerRepository - .Get() - .Include(x => x.Allocations) - .Include(x => x.Variables) - .Include(x => x.MainAllocation) - .Include(x => x.Image) - .ThenInclude(x => x.DockerImages) - .Where(x => x.Node.Id == node.Id) - .FirstOrDefault(x => x.Id == id); - - if (server == null) - return NotFound(); - - var configuration = server.ToServerConfiguration(); - - return Ok(configuration); - } - - [HttpGet("{id:int}/install")] - public async Task> GetServerInstallById(int id) - { - var node = (HttpContext.Items["Node"] as ServerNode)!; - - var server = ServerRepository - .Get() - .Include(x => x.Image) - .Where(x => x.Node.Id == node.Id) - .FirstOrDefault(x => x.Id == id); - - if (server == null) - return NotFound(); - - var configuration = server.ToServerInstallConfiguration(); - - return Ok(configuration); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Http/Middleware/NodeMiddleware.cs b/Moonlight/Features/Servers/Http/Middleware/NodeMiddleware.cs deleted file mode 100644 index 07ad24b..0000000 --- a/Moonlight/Features/Servers/Http/Middleware/NodeMiddleware.cs +++ /dev/null @@ -1,92 +0,0 @@ -using Microsoft.AspNetCore.Http.Features; -using MoonCore.Abstractions; - -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Extensions.Attributes; - -namespace Moonlight.Features.Servers.Http.Middleware; - -public class NodeMiddleware -{ - private RequestDelegate Next; - private readonly IServiceProvider ServiceProvider; - - public NodeMiddleware(RequestDelegate next, IServiceProvider serviceProvider) - { - Next = next; - ServiceProvider = serviceProvider; - } - - public async Task Invoke(HttpContext context) - { - // Check if the path is targeting the /api/servers endpoints - if (!context.Request.Path.HasValue || !context.Request.Path.Value.StartsWith("/api/servers")) - { - await Next(context); - return; - } - - // Load endpoint - var endpoint = context.Features.Get(); - - // Null checks to ensure we have data to check - if (endpoint == null || endpoint.Endpoint == null) - { - await Next(context); - return; - } - - // Reference to the controller meta - var controllerMeta = endpoint.Endpoint.Metadata; - - // If the node middleware attribute is missing, we want to continue - if(controllerMeta.All(x => x is EnableNodeMiddlewareAttribute)) - { - await Next(context); - return; - } - - // Now we actually want to validate the request - // so every return after this text will prevent - // the call of the controller action - - // Check if header exists - if (!context.Request.Headers.ContainsKey("Authorization")) - { - // TODO: Add a proper extensions pack to support proper error messages - context.Response.StatusCode = 403; - return; - } - - var token = context.Request.Headers["Authorization"].ToString(); - - // Check if header is null - if (string.IsNullOrEmpty(token)) - { - context.Response.StatusCode = 403; - return; - } - - using var scope = ServiceProvider.CreateScope(); - var nodeRepo = scope.ServiceProvider.GetRequiredService>(); - - // Check if any node has the token specified by the request - var node = nodeRepo - .Get() - .FirstOrDefault(x => x.Token == token); - - if (node == null) - { - context.Response.StatusCode = 403; - return; - } - - // Request is valid, because we found a node by this token - // so now we want to save it for the controller to use and - // continue in the request pipeline - - context.Items["Node"] = node; - - await Next(context); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Http/Requests/FtpLogin.cs b/Moonlight/Features/Servers/Http/Requests/FtpLogin.cs deleted file mode 100644 index 3c72cfd..0000000 --- a/Moonlight/Features/Servers/Http/Requests/FtpLogin.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.Servers.Http.Requests; - -public class FtpLogin -{ - public string Username { get; set; } - public string Password { get; set; } - public int ServerId { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Abstractions/NodeMeta.cs b/Moonlight/Features/Servers/Models/Abstractions/NodeMeta.cs deleted file mode 100644 index ae5f8f0..0000000 --- a/Moonlight/Features/Servers/Models/Abstractions/NodeMeta.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Moonlight.Features.Servers.Models.Abstractions; - -public class NodeMeta -{ - public bool IsBooting { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Abstractions/ServerConfiguration.cs b/Moonlight/Features/Servers/Models/Abstractions/ServerConfiguration.cs deleted file mode 100644 index e3bf058..0000000 --- a/Moonlight/Features/Servers/Models/Abstractions/ServerConfiguration.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace Moonlight.Features.Servers.Models.Abstractions; - -public class ServerConfiguration -{ - public int Id { get; set; } - - public LimitsData Limits { get; set; } - public ImageData Image { get; set; } - public AllocationData MainAllocation { get; set; } - public List Allocations { get; set; } - public Dictionary Variables { get; set; } = new(); - - public class LimitsData - { - public int Cpu { get; set; } - public int Memory { get; set; } - public int Disk { get; set; } - } - - public class ImageData - { - public string DockerImage { get; set; } - public bool PullDockerImage { get; set; } - public string StartupCommand { get; set; } - public string StopCommand { get; set; } - public string OnlineDetection { get; set; } - public string ParseConfigurations { get; set; } - } - - public class AllocationData - { - public string IpAddress { get; set; } - public int Port { get; set; } - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Abstractions/ServerInstallConfiguration.cs b/Moonlight/Features/Servers/Models/Abstractions/ServerInstallConfiguration.cs deleted file mode 100644 index ee4a1ec..0000000 --- a/Moonlight/Features/Servers/Models/Abstractions/ServerInstallConfiguration.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.Servers.Models.Abstractions; - -public class ServerInstallConfiguration -{ - public string DockerImage { get; set; } - public string Shell { get; set; } - public string Script { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Abstractions/ServerMeta.cs b/Moonlight/Features/Servers/Models/Abstractions/ServerMeta.cs deleted file mode 100644 index a002f74..0000000 --- a/Moonlight/Features/Servers/Models/Abstractions/ServerMeta.cs +++ /dev/null @@ -1,13 +0,0 @@ -using MoonCore.Helpers; -using Moonlight.Features.Servers.Models.Enums; - -namespace Moonlight.Features.Servers.Models.Abstractions; - -public class ServerMeta -{ - public ServerState State { get; set; } - public DateTime LastChangeTimestamp { get; set; } = DateTime.UtcNow; - public SmartEventHandler OnStateChanged { get; set; } = new(); - public SmartEventHandler OnConsoleMessage { get; set; } = new(); - public List ConsoleMessages { get; set; } = new(); -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Enums/PowerAction.cs b/Moonlight/Features/Servers/Models/Enums/PowerAction.cs deleted file mode 100644 index 097d1bc..0000000 --- a/Moonlight/Features/Servers/Models/Enums/PowerAction.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Moonlight.Features.Servers.Models.Enums; - -public enum PowerAction -{ - Start, - Stop, - Kill, - Install -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Enums/ServerState.cs b/Moonlight/Features/Servers/Models/Enums/ServerState.cs deleted file mode 100644 index 376bb9b..0000000 --- a/Moonlight/Features/Servers/Models/Enums/ServerState.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Moonlight.Features.Servers.Models.Enums; - -public enum ServerState -{ - Offline, - Starting, - Online, - Stopping, - Installing, - Join2Start -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateDockerImage.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateDockerImage.cs deleted file mode 100644 index 3b1a2c7..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateDockerImage.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images; - -public class CreateDockerImage -{ - [Required(ErrorMessage = "You need to specify a docker image name")] - [Description("This is the name of the docker image. E.g. moonlightpanel/moonlight:canary")] - public string Name { get; set; } - - [Required(ErrorMessage = "You need to specify a display name")] - [Description("This will be shown if the user is able to change the docker image as the image name")] - public string DisplayName { get; set; } - - [Description("Specifies if the docker image should be pulled/updated when creating a server instance. Disable this for only local existing docker images")] - public bool AutoPull { get; set; } = true; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateImageForm.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateImageForm.cs deleted file mode 100644 index db9d95d..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateImageForm.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images; - -public class CreateImageForm -{ - [Required(ErrorMessage = "You need to specify a name")] - public string Name { get; set; } - - [Required(ErrorMessage = "You need to specify a author")] - public string Author { get; set; } - - [Description("The donate button on your image will lead to the page you specify here")] - public string? DonateUrl { get; set; } - - [Description("This field allows you to specify an direct http(s) url to fetch image updates from")] - public string? UpdateUrl { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateImageVariable.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateImageVariable.cs deleted file mode 100644 index 779a4ae..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/CreateImageVariable.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images; - -public class CreateImageVariable -{ - [Required(ErrorMessage = "You need to specify a key")] - [Description("This is the environment variable name")] - public string Key { get; set; } - - [Description("This is the default value which will be set when a server is created")] - public string DefaultValue { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a display name")] - [Description("This is the display name of the variable which will be shown to the user if enabled to edit/view the variable")] - public string DisplayName { get; set; } - - [Description("This text should describe what the variable does for the user if allowed to view and/or change")] - public string Description { get; set; } = ""; - - [Description("Allow the user to edit the variable. Wont work if view is disabled")] - public bool AllowUserToEdit { get; set; } = false; - - [Description("Allow the user to view the variable but not edit it unless specified otherwise")] - public bool AllowUserToView { get; set; } = false; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/Parsing/ParseConfigForm.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/Parsing/ParseConfigForm.cs deleted file mode 100644 index 294f562..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/Parsing/ParseConfigForm.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images.Parsing; - -public class ParseConfigForm -{ - [Required(ErrorMessage = "You need to specify a type in a parse configuration")] - public string Type { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a file in a parse configuration")] - public string File { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/Parsing/ParseConfigOptionForm.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/Parsing/ParseConfigOptionForm.cs deleted file mode 100644 index 5c8e2c2..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/Parsing/ParseConfigOptionForm.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images.Parsing; - -public class ParseConfigOptionForm -{ - [Required(ErrorMessage = "You need to specify the key of an option")] - public string Key { get; set; } = ""; - public string Value { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateDockerImage.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateDockerImage.cs deleted file mode 100644 index 6a4cdb9..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateDockerImage.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images; - -public class UpdateDockerImage -{ - [Required(ErrorMessage = "You need to specify a docker image name")] - [Description("This is the name of the docker image. E.g. moonlightpanel/moonlight:canary")] - public string Name { get; set; } - - [Required(ErrorMessage = "You need to specify a display name")] - [Description("This will be shown if the user is able to change the docker image as the image name")] - public string DisplayName { get; set; } - - [Description("Specifies if the docker image should be pulled/updated when creating a server instance. Disable this for only local existing docker images")] - public bool AutoPull { get; set; } = true; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageDetailsForm.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageDetailsForm.cs deleted file mode 100644 index 226bd81..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageDetailsForm.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images; - -public class UpdateImageDetailsForm -{ - [Description("The allocations (aka. ports) a image needs in order to be created")] - [Range(1, int.MaxValue)] - public int AllocationsNeeded { get; set; } - - [Required(ErrorMessage = "You need to specify a startup command")] - [Description("This command gets passed to the container of the image to execute")] - public string StartupCommand { get; set; } - - [Required(ErrorMessage = "You need to specify a stop command")] - [Description("This command will get written into the input stream of the server process when the server should get stopped")] - public string StopCommand { get; set; } - - [Required(ErrorMessage = "You need to specify a online detection")] - [Description("The regex string you specify here will be used in order to detect if a server is up and running")] - public string OnlineDetection { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageForm.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageForm.cs deleted file mode 100644 index 091bdb6..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageForm.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images; - -public class UpdateImageForm -{ - [Required(ErrorMessage = "You need to specify a name")] - public string Name { get; set; } - - [Required(ErrorMessage = "You need to specify a author")] - public string Author { get; set; } - - [Description("The donate button on your image will lead to the page you specify here")] - public string? DonateUrl { get; set; } - - [Description("This field allows you to specify an direct http(s) url to fetch image updates from")] - public string? UpdateUrl { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageInstallationForm.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageInstallationForm.cs deleted file mode 100644 index eff3cab..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageInstallationForm.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images; - -public class UpdateImageInstallationForm -{ - [Required(ErrorMessage = "You need to specify a install docker image")] - [Description("This specifies the docker image to use for the script execution")] - public string InstallDockerImage { get; set; } - - [Required(ErrorMessage = "You need to specify a install shell")] - [Description("This is the shell to pass the install script to")] - public string InstallShell { get; set; } - - [Required(ErrorMessage = "You need to specify a install script")] - public string InstallScript { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageVariable.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageVariable.cs deleted file mode 100644 index b336c9e..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Images/UpdateImageVariable.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Images; - -public class UpdateImageVariable -{ - [Required(ErrorMessage = "You need to specify a key")] - [Description("This is the environment variable name")] - public string Key { get; set; } - - [Description("This is the default value which will be set when a server is created")] - public string DefaultValue { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a display name")] - [Description("This is the display name of the variable which will be shown to the user if enabled to edit/view the variable")] - public string DisplayName { get; set; } - - [Description("This text should describe what the variable does for the user if allowed to view and/or change")] - public string Description { get; set; } = ""; - - [Description("Allow the user to edit the variable. Wont work if view is disabled")] - public bool AllowUserToEdit { get; set; } = false; - - [Description("Allow the user to view the variable but not edit it unless specified otherwise")] - public bool AllowUserToView { get; set; } = false; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/CreateNodeForm.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/CreateNodeForm.cs deleted file mode 100644 index b6b1e0e..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/CreateNodeForm.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Nodes; - -public class CreateNodeForm -{ - [Required(ErrorMessage = "You need to specify a name")] - public string Name { get; set; } - - [Required(ErrorMessage = "You need to specify a fqdn")] - [Description("This needs to be the ip or domain of the node")] - public string Fqdn { get; set; } - - [Description("This enables ssl for the http conenctions to the node. Only enable this if you have the cert installed on the node")] - public bool UseSsl { get; set; } - - [Description("This is the http(s) port used by the node to allow communication to the node from the panel")] - public int HttpPort { get; set; } = 8080; - - [Description("This is the ftp port the panel and the users use to access their servers filesystem")] - public int FtpPort { get; set; } = 2021; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/CreateServerAllocation.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/CreateServerAllocation.cs deleted file mode 100644 index d647f7d..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/CreateServerAllocation.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Nodes; - -public class CreateServerAllocation -{ - [Required(ErrorMessage = "You need to provide a bind ip address")] - public string IpAddress { get; set; } = "0.0.0.0"; - - [Range(1, 65535, ErrorMessage = "You need to provide a valid port")] - public int Port { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/UpdateNodeForm.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/UpdateNodeForm.cs deleted file mode 100644 index 5d84df7..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/UpdateNodeForm.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Nodes; - -public class UpdateNodeForm -{ - [Required(ErrorMessage = "You need to specify a name")] - public string Name { get; set; } - - [Required(ErrorMessage = "You need to specify a fqdn")] - [Description("This needs to be the ip or domain of the node")] - public string Fqdn { get; set; } - - [Description("This enables ssl for the http conenctions to the node. Only enable this if you have the cert installed on the node")] - public bool UseSsl { get; set; } - - [Description("This is the http(s) port used by the node to allow communication to the node from the panel")] - public int HttpPort { get; set; } = 8080; - - [Description("This is the ftp port the panel and the users use to access their servers filesystem")] - public int FtpPort { get; set; } = 2021; -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/UpdateServerAllocation.cs b/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/UpdateServerAllocation.cs deleted file mode 100644 index e599924..0000000 --- a/Moonlight/Features/Servers/Models/Forms/Admin/Nodes/UpdateServerAllocation.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Servers.Models.Forms.Admin.Nodes; - -public class UpdateServerAllocation -{ - [Required(ErrorMessage = "You need to provide a bind ip address")] - public string IpAddress { get; set; } = "0.0.0.0"; - - [Range(1, 65535, ErrorMessage = "You need to provide a valid port")] - public int Port { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Models/ServerParseConfig.cs b/Moonlight/Features/Servers/Models/ServerParseConfig.cs deleted file mode 100644 index 417c809..0000000 --- a/Moonlight/Features/Servers/Models/ServerParseConfig.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.Servers.Models; - -public class ServerParseConfig -{ - public string Type { get; set; } = ""; - public string File { get; set; } = ""; - public Dictionary Configuration { get; set; } = new(); -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Services/NodeService.cs b/Moonlight/Features/Servers/Services/NodeService.cs deleted file mode 100644 index a2dbacd..0000000 --- a/Moonlight/Features/Servers/Services/NodeService.cs +++ /dev/null @@ -1,26 +0,0 @@ -using MoonCore.Attributes; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Extensions; -using Moonlight.Features.Servers.Helpers; -using Moonlight.Features.Servers.Models.Abstractions; - -namespace Moonlight.Features.Servers.Services; - -[Singleton] -public class NodeService -{ - public readonly MetaCache Meta = new(); - - private readonly IServiceProvider ServiceProvider; - - public NodeService(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public async Task Boot(ServerNode node) - { - using var httpClient = node.CreateHttpClient(); - await httpClient.Post("system/boot"); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Services/ServerConsoleService.cs b/Moonlight/Features/Servers/Services/ServerConsoleService.cs deleted file mode 100644 index 863a5ff..0000000 --- a/Moonlight/Features/Servers/Services/ServerConsoleService.cs +++ /dev/null @@ -1,40 +0,0 @@ -using MoonCore.Attributes; -using Moonlight.Features.Servers.Api.Requests; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Extensions; -using Moonlight.Features.Servers.Models.Enums; - -namespace Moonlight.Features.Servers.Services; - -[Singleton] -public class ServerConsoleService -{ - private readonly IServiceProvider ServiceProvider; - - public ServerConsoleService(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public async Task SendAction(Server server, PowerAction powerAction) - { - using var httpClient = server.CreateHttpClient(ServiceProvider); - await httpClient.Post($"servers/{server.Id}/power/{powerAction.ToString().ToLower()}"); - } - - public async Task Subscribe(Server server) - { - using var httpClient = server.CreateHttpClient(ServiceProvider); - await httpClient.Post($"servers/{server.Id}/subscribe"); - } - - public async Task SendCommand(Server server, string command) - { - using var httpClient = server.CreateHttpClient(ServiceProvider); - - await httpClient.Post($"servers/{server.Id}/command", new SendCommand() - { - Command = command - }); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/Services/ServerService.cs b/Moonlight/Features/Servers/Services/ServerService.cs deleted file mode 100644 index 99ed5b8..0000000 --- a/Moonlight/Features/Servers/Services/ServerService.cs +++ /dev/null @@ -1,32 +0,0 @@ -using MoonCore.Attributes; -using Moonlight.Features.Servers.Entities; -using Moonlight.Features.Servers.Extensions; -using Moonlight.Features.Servers.Helpers; -using Moonlight.Features.Servers.Models.Abstractions; - -namespace Moonlight.Features.Servers.Services; - -[Singleton] -public class ServerService -{ - public readonly MetaCache Meta = new(); - public ServerConsoleService Console => ServiceProvider.GetRequiredService(); - - private readonly IServiceProvider ServiceProvider; - - public ServerService(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public async Task Sync(Server server) - { - using var httpClient = server.CreateHttpClient(ServiceProvider); - await httpClient.Post($"servers/{server.Id}/sync"); - } - - public async Task SyncDelete(Server server) - { - - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Components/AdminImageViewNavigation.razor b/Moonlight/Features/Servers/UI/Components/AdminImageViewNavigation.razor deleted file mode 100644 index 169f9bc..0000000 --- a/Moonlight/Features/Servers/UI/Components/AdminImageViewNavigation.razor +++ /dev/null @@ -1,43 +0,0 @@ - - -@code -{ - [Parameter] public int Index { get; set; } - - [Parameter] public int ImageId { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Components/AdminServersNavigation.razor b/Moonlight/Features/Servers/UI/Components/AdminServersNavigation.razor deleted file mode 100644 index 4472d36..0000000 --- a/Moonlight/Features/Servers/UI/Components/AdminServersNavigation.razor +++ /dev/null @@ -1,21 +0,0 @@ -
    -
    - -
    -
    - -@code -{ - [Parameter] public int Index { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Components/ParseConfigEditor.razor b/Moonlight/Features/Servers/UI/Components/ParseConfigEditor.razor deleted file mode 100644 index 5c60c82..0000000 --- a/Moonlight/Features/Servers/UI/Components/ParseConfigEditor.razor +++ /dev/null @@ -1,158 +0,0 @@ -@using Newtonsoft.Json -@using Mappy.Net -@using MoonCore.Helpers - -@using Moonlight.Features.Servers.Models -@using Moonlight.Features.Servers.Models.Forms.Admin.Images -@using Moonlight.Features.Servers.Models.Forms.Admin.Images.Parsing - -
    -
    - Parse configurations -
    - -
    -
    -
    - @foreach (var config in Configs) - { -
    -
    -
    - -
    -
    -
    -
    -
    - -
    - A relative path from the servers main directory to the file you want to modify -
    - -
    -
    - -
    - This specifies the type of parser to use. e.g. "properties" or "file" -
    - -
    -
    -
    - Remove -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    - @foreach (var option in config.Value) - { -
    -
    - - - Remove -
    -
    - } -
    -
    -
    -
    -
    -
    -
    - } -
    -
    - -@code -{ - [Parameter] - public string InitialContent { get; set; } = ""; - - private Dictionary> Configs = new(); - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender && !string.IsNullOrEmpty(InitialContent)) - await Set(InitialContent); - } - - public async Task Set(string content) - { - Configs.Clear(); - - var configs = JsonConvert.DeserializeObject(content) - ?? Array.Empty(); - - foreach (var config in configs) - { - var options = config.Configuration.Select(x => new ParseConfigOptionForm() - { - Key = x.Key, - Value = x.Value - }).ToList(); - - - Configs.Add(Mapper.Map(config), options); - } - - await InvokeAsync(StateHasChanged); - } - - public async Task ValidateAndGet() - { - await ValidatorHelper.ValidateRange(Configs.Keys); - - foreach (var options in Configs.Values) - await ValidatorHelper.ValidateRange(options); - - var finalConfigs = Configs.Select(x => new ServerParseConfig() - { - File = x.Key.File, - Type = x.Key.Type, - Configuration = x.Value.ToDictionary(y => y.Key, y => y.Value) - }).ToList(); - - return JsonConvert.SerializeObject(finalConfigs); - } - - private async Task AddConfig() - { - Configs.Add(new(), new()); - await InvokeAsync(StateHasChanged); - } - - private async Task RemoveConfig(ParseConfigForm config) - { - Configs.Remove(config); - await InvokeAsync(StateHasChanged); - } - - private async Task AddOption(ParseConfigForm config) - { - Configs[config].Add(new()); - await InvokeAsync(StateHasChanged); - } - - private async Task RemoveOption(ParseConfigForm config, ParseConfigOptionForm option) - { - Configs[config].Remove(option); - await InvokeAsync(StateHasChanged); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Components/Terminal.razor b/Moonlight/Features/Servers/UI/Components/Terminal.razor deleted file mode 100644 index d92a0dc..0000000 --- a/Moonlight/Features/Servers/UI/Components/Terminal.razor +++ /dev/null @@ -1,79 +0,0 @@ -@using XtermBlazor - -@using MoonCoreUI.Services - -@inject ClipboardService ClipboardService -@inject ToastService ToastService - - - -@code -{ - private Xterm Term; - - private readonly TerminalOptions Options = new() - { - CursorBlink = false, - CursorWidth = 0, - Theme = - { - Background = "#000000", - CursorAccent = "#000000", - Cursor = "#000000" - }, - DisableStdin = true, - FontFamily = "monospace" - }; - - private bool HasBeenRendered = false; - private readonly List UnRenderedMessageCache = new(); - - public async Task WriteLine(string content) - { - if(HasBeenRendered) - await Term.WriteLine(content); - else - { - lock (UnRenderedMessageCache) - UnRenderedMessageCache.Add(content); - } - } - - private async void OnFirstRender() - { - try - { - await Term.InvokeAddonFunctionVoidAsync("xterm-addon-fit", "fit"); - - // This disables the key handling for xterm completely in order to allow Strg + C copying and other features - Term.AttachCustomKeyEventHandler(key => - { - if (key.CtrlKey && key.Code == "KeyC" && key.Type == "keydown") - { - Task.Run(async () => - { - var content = await Term.GetSelection(); - await ClipboardService.Copy(content); - await ToastService.Info("Copied console selection to clipboard"); - }); - } - - return false; - }); - } - catch (Exception){ /* Ignore all js errors as the addons are not that important to risk a crash of the ui */ } - - string[] messagesToWrite; - - lock (UnRenderedMessageCache) - { - messagesToWrite = UnRenderedMessageCache.ToArray(); - UnRenderedMessageCache.Clear(); - } - - foreach (var message in messagesToWrite) - await Term.WriteLine(message); - - HasBeenRendered = true; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Layouts/AdminLayout.razor b/Moonlight/Features/Servers/UI/Layouts/AdminLayout.razor deleted file mode 100644 index e1e86d8..0000000 --- a/Moonlight/Features/Servers/UI/Layouts/AdminLayout.razor +++ /dev/null @@ -1,5 +0,0 @@ -

    AdminLayout

    - -@code { - -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor b/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor deleted file mode 100644 index 8780b09..0000000 --- a/Moonlight/Features/Servers/UI/Layouts/UserLayout.razor +++ /dev/null @@ -1,289 +0,0 @@ -@using Moonlight.Features.ServiceManagement.Entities -@using Moonlight.Features.ServiceManagement.Models.Abstractions -@using Moonlight.Features.Servers.Entities -@using Moonlight.Features.Servers.Models.Abstractions -@using Moonlight.Features.Servers.Models.Enums -@using Moonlight.Features.Servers.Services -@using Moonlight.Features.Servers.UI.Components -@using MoonCore.Abstractions -@using MoonCore.Helpers -@using MoonCoreUI.Services -@using Microsoft.EntityFrameworkCore -@using Moonlight.Features.ServiceManagement.UI.Components - -@inject Repository ServerRepository -@inject ServerService ServerService -@inject ToastService ToastService - -@implements IDisposable - - -
    -
    -
    -
    - - @(Service.Nickname ?? $"Service {Service.Id}") - - - @(Server.Image.Name) - -
    -
    -
    -
    - @{ - var color = "secondary"; - - switch (Meta.State) - { - case ServerState.Stopping: - color = "warning"; - break; - - case ServerState.Starting: - color = "warning"; - break; - - case ServerState.Offline: - color = "danger"; - break; - - case ServerState.Online: - color = "success"; - break; - - case ServerState.Installing: - color = "primary"; - break; - - case ServerState.Join2Start: - color = "info"; - break; - } - } - - - - @(Meta.State) - (@(Formatter.FormatUptime(DateTime.UtcNow - Meta.LastChangeTimestamp))) - -
    -
    -
    - - - @(Server.Node.Fqdn):@(Server.MainAllocation.Port) - -
    -
    - - - 188.75.252.37:10324 - -
    -
    -
    -
    -
    -
    - @if (Meta.State == ServerState.Offline) - { - - - - } - else - { - - } - - @if (Meta.State == ServerState.Offline || Meta.State == ServerState.Installing) - { - - } - else - { - - - - } - - @if (Meta.State == ServerState.Offline || Meta.State == ServerState.Installing) - { - - } - else - { - - - - } -
    -
    -
    - -
    - -
    - @if (IsInstalling) - { -
    - -
    - } - else - { - - - - - @foreach (var uiPage in ViewContext.Pages) - { - - @uiPage.Component - - } - - - - - } -
    -
    - -@code -{ - [Parameter] - public Service Service { get; set; } - - [Parameter] - public ServiceViewContext ViewContext { get; set; } - - [Parameter] - public string? Route { get; set; } - - [Parameter] - public ServiceDefinition Implementation { get; set; } - - private Server Server; - private ServerMeta Meta; - private CancellationTokenSource BackgroundCancel = new(); - - private Terminal? InstallTerminal; - private bool IsInstalling = false; - - private async Task Load(LazyLoader lazyLoader) - { - await lazyLoader.SetText("Loading server information"); - - Server = ServerRepository - .Get() - .Include(x => x.Image) - .Include(x => x.Node) - .Include(x => x.Variables) - .Include(x => x.Allocations) - .Include(x => x.MainAllocation) - .First(x => x.Service.Id == Service.Id); - - // Load meta and setup event handlers - Meta = await ServerService.Meta.Get(Server.Id); - Meta.OnStateChanged += async Task () => - { - await InvokeAsync(StateHasChanged); - - // Change from offline to installing - // This will trigger the initialisation of the install view - if (Meta.State == ServerState.Installing && !IsInstalling) - { - IsInstalling = true; - - // After this call, we should have access to the install terminal reference - await InvokeAsync(StateHasChanged); - - Meta.OnConsoleMessage += OnInstallConsoleMessage; - } - // Change from installing to offline - // This will trigger the destruction of the install view - else if (Meta.State == ServerState.Offline && IsInstalling) - { - IsInstalling = false; - - Meta.OnConsoleMessage -= OnInstallConsoleMessage; - - // After this call, the install terminal will disappear - await InvokeAsync(StateHasChanged); - - await ToastService.Info("Server installation complete"); - } - }; - - // Send console subscription and add auto resubscribe for it - await ServerService.Console.Subscribe(Server); - - // We need this to revalidate to the daemon that we are still interested - // in the console logs. By default the expiration time is 15 minutes from last - // subscription so every 10 minutes should ensure we are subscribed - Task.Run(async () => - { - while (!BackgroundCancel.IsCancellationRequested) - { - await Task.Delay(TimeSpan.FromMinutes(10)); - await ServerService.Console.Subscribe(Server); - } - }); - - // In order to update the timer correctly, we are calling a re - Task.Run(async () => - { - while (!BackgroundCancel.IsCancellationRequested) - { - await Task.Delay(TimeSpan.FromSeconds(1)); - await InvokeAsync(StateHasChanged); - } - }); - } - - private async Task OnInstallConsoleMessage(string message) - { - if(InstallTerminal != null) - await InstallTerminal.WriteLine(message); - } - - private async Task Start() => await ServerService.Console.SendAction(Server, PowerAction.Start); - - private async Task Stop() => await ServerService.Console.SendAction(Server, PowerAction.Stop); - - private async Task Kill() => await ServerService.Console.SendAction(Server, PowerAction.Kill); - - public void Dispose() - { - BackgroundCancel.Cancel(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/UserViews/Console.razor b/Moonlight/Features/Servers/UI/UserViews/Console.razor deleted file mode 100644 index edb096d..0000000 --- a/Moonlight/Features/Servers/UI/UserViews/Console.razor +++ /dev/null @@ -1,66 +0,0 @@ -@using Moonlight.Features.Servers.Models.Abstractions -@using Moonlight.Features.Servers.Services -@using Moonlight.Features.Servers.UI.Components -@using Moonlight.Features.Servers.Entities - -@inject ServerService ServerService - -@implements IDisposable - -
    - -
    -
    - - -
    -
    -
    - -@code -{ - [CascadingParameter] - public ServerMeta Meta { get; set; } - - [CascadingParameter] - public Server Server { get; set; } - - private Terminal Terminal; - private string CommandInput = ""; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - string[] messages; - - lock (Meta.ConsoleMessages) - messages = Meta.ConsoleMessages.TakeLast(50).ToArray(); - - foreach (var message in messages) - await Terminal.WriteLine(message); - - Meta.OnConsoleMessage += OnConsoleMessage; - } - } - - private async Task OnConsoleMessage(string message) - { - await Terminal.WriteLine(message); - } - - private async Task SendCommand() - { - await ServerService.Console.SendCommand(Server, CommandInput); - CommandInput = ""; - - await InvokeAsync(StateHasChanged); - } - - public void Dispose() - { - if(Meta != null) - Meta.OnConsoleMessage -= OnConsoleMessage; - } - -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/UserViews/Files.razor b/Moonlight/Features/Servers/UI/UserViews/Files.razor deleted file mode 100644 index 675ddbd..0000000 --- a/Moonlight/Features/Servers/UI/UserViews/Files.razor +++ /dev/null @@ -1,47 +0,0 @@ -@using Moonlight.Core.Configuration -@using Moonlight.Core.Services.Utils -@using Moonlight.Features.FileManager.Models.Abstractions.FileAccess -@using Moonlight.Features.Servers.Entities -@using Moonlight.Features.ServiceManagement.Entities -@using MoonCore.Services -@using Moonlight.Features.FileManager.UI.Components -@using Moonlight.Features.Servers.Helpers - -@inject JwtService JwtService -@inject ConfigService ConfigService - -@implements IDisposable - - - - - -@code -{ - [CascadingParameter] public Service Service { get; set; } - - [CascadingParameter] public Server Server { get; set; } - - private IFileAccess FileAccess; - - private async Task Load(LazyLoader lazyLoader) - { - var ftpLoginJwt = await JwtService.Create(data => - { - data.Add("ServerId", Server.Id.ToString()); - }, "FtpServerLogin", TimeSpan.FromMinutes(5)); - - FileAccess = new ServerFtpFileAccess( - Server.Node.Fqdn, - Server.Node.FtpPort, - $"moonlight.{Server.Id}", - ftpLoginJwt, - ConfigService.Get().FileManager.OperationTimeout - ); - } - - public void Dispose() - { - FileAccess.Dispose(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/UserViews/Network.razor b/Moonlight/Features/Servers/UI/UserViews/Network.razor deleted file mode 100644 index 848d8b5..0000000 --- a/Moonlight/Features/Servers/UI/UserViews/Network.razor +++ /dev/null @@ -1,76 +0,0 @@ -@using Moonlight.Features.Servers.Entities -@using System.Net - -
    -
    -
    - -
    -
    - -
    -
    - -
    -
    - -
    -
    -
    -
    -
    - -@foreach (var allocation in Server.Allocations) -{ -
    -
    -
    -
    - @if (allocation.IpAddress == "0.0.0.0") - { - @Server.Node.Fqdn - } - else - { - @allocation.IpAddress - } -
    -
    -
    - @if (allocation.IpAddress != "0.0.0.0" || IsIpAddress(Server.Node.Fqdn)) - { -
    - - -
    - } - else - { - //TODO: Resolve domains addresses here -
    - 188.75.252.37 -
    - } -
    -
    -
    - @allocation.Port -
    -
    -
    - -
    -
    - -
    -
    -
    -} - -@code -{ - [CascadingParameter] public Server Server { get; set; } - - private bool IsIpAddress(string input) => IPAddress.TryParse(input, out _); -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/UserViews/Reset.razor b/Moonlight/Features/Servers/UI/UserViews/Reset.razor deleted file mode 100644 index 2e10d0a..0000000 --- a/Moonlight/Features/Servers/UI/UserViews/Reset.razor +++ /dev/null @@ -1,53 +0,0 @@ -@using Moonlight.Features.Servers.Entities -@using Moonlight.Features.Servers.Models.Abstractions -@using Moonlight.Features.Servers.Models.Enums -@using Moonlight.Features.Servers.Services - -@implements IDisposable - -@inject ServerService ServerService - -
    - @if (Meta.State == ServerState.Offline) - { - - } - else - { - - } -
    - -@code -{ - [CascadingParameter] - public Server Server { get; set; } - - [CascadingParameter] - public ServerMeta Meta { get; set; } - - protected override Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - Meta.OnStateChanged += OnStateChanged; - } - - return Task.CompletedTask; - } - - private async Task ResetServer() - { - await ServerService.Console.SendAction(Server, PowerAction.Install); - } - - private async Task OnStateChanged() - { - await InvokeAsync(StateHasChanged); - } - - public void Dispose() - { - Meta.OnStateChanged -= OnStateChanged; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/UserViews/Schedules.razor b/Moonlight/Features/Servers/UI/UserViews/Schedules.razor deleted file mode 100644 index 09911ba..0000000 --- a/Moonlight/Features/Servers/UI/UserViews/Schedules.razor +++ /dev/null @@ -1,9 +0,0 @@ -@using Moonlight.Features.Servers.Entities - - - -@code -{ - [CascadingParameter] - public Server Server { get; set; } -} diff --git a/Moonlight/Features/Servers/UI/UserViews/Variables.razor b/Moonlight/Features/Servers/UI/UserViews/Variables.razor deleted file mode 100644 index d1f4dee..0000000 --- a/Moonlight/Features/Servers/UI/UserViews/Variables.razor +++ /dev/null @@ -1,110 +0,0 @@ -@using Moonlight.Features.Servers.Entities -@using MoonCore.Abstractions -@using Microsoft.EntityFrameworkCore -@using MoonCoreUI.Services - -@inject Repository ServerRepository -@inject Repository ImageRepository -@inject Repository ServerVariableRepository -@inject ToastService ToastService - - -
    -
    -
    - - @if (Image.AllowUserToChangeDockerImage) - { - - } - else - { - - } -
    -
    -
    -
    - @foreach (var variable in Server.Variables) - { - var imageVariable = Image.Variables.FirstOrDefault(x => x.Key == variable.Key); - - if (imageVariable != null && imageVariable.AllowUserToView) - { -
    -
    - -
    - @imageVariable.Description -
    -
    - @if (imageVariable.AllowUserToEdit) - { -
    - - - - -
    - } - else - { -
    - -
    - } -
    -
    -
    - } - } -
    -
    - -@code -{ - [CascadingParameter] public Server Server { get; set; } - - private ServerImage Image; - private LazyLoader LazyLoader; - - private ServerDockerImage SelectedDockerImage; - - private async Task Load(LazyLoader lazyLoader) - { - await lazyLoader.SetText("Loading server image data"); - - Image = ImageRepository - .Get() - .Include(x => x.Variables) - .Include(x => x.DockerImages) - .First(x => x.Id == Server.Image.Id); - - if (Server.DockerImageIndex >= Image.DockerImages.Count || Server.DockerImageIndex == -1) - SelectedDockerImage = Image.DockerImages.Last(); - else - SelectedDockerImage = Image.DockerImages[Server.DockerImageIndex]; - } - - private async Task OnDockerImageChanged() - { - Server.DockerImageIndex = Image.DockerImages.IndexOf(SelectedDockerImage); - ServerRepository.Update(Server); - - await ToastService.Success("Successfully changed docker image"); - await LazyLoader.Reload(); - } - - private async Task UpdateVariable(ServerVariable variable) - { - ServerVariableRepository.Update(variable); - - await ToastService.Success("Successfully changed variable"); - await LazyLoader.Reload(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Images/Index.razor b/Moonlight/Features/Servers/UI/Views/Admin/Images/Index.razor deleted file mode 100644 index 2e75bac..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Images/Index.razor +++ /dev/null @@ -1,141 +0,0 @@ -@page "/admin/servers/images" - -@using BlazorTable -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions -@using MoonCore.Exceptions -@using MoonCoreUI.Services - - - -@using Moonlight.Features.Servers.Entities -@using Moonlight.Features.Servers.UI.Components - -@inject Repository ImageRepository -@inject Repository ImageVariableRepository -@inject Repository DockerImageRepository -@inject Repository ServerRepository -@inject ToastService ToastService - - - -
    -
    -

    Manage server images

    -
    - - - -
    -
    -
    - - - - - - - - - - - - - -
    -
    -
    -
    - -@code -{ - private LazyLoader LazyLoader; - private ServerImage[] Images; - - private Task Load(LazyLoader arg) - { - Images = ImageRepository - .Get() - .ToArray(); - - return Task.CompletedTask; - } - - private async Task Update(ServerImage image) - { - } - - private async Task Delete(ServerImage image) - { - var anyServerWithThisImage = ServerRepository - .Get() - .Any(x => x.Image.Id == image.Id); - - if (anyServerWithThisImage) - throw new DisplayException("This image cannot be deleted, because one or more server depend on it. Delete the server(s) first and then delete the image"); - - var imageWithData = ImageRepository - .Get() - .Include(x => x.Variables) - .Include(x => x.DockerImages) - .First(x => x.Id == image.Id); - - // Cache and clear relational data - - var variables = imageWithData.Variables.ToArray(); - var dockerImages = imageWithData.DockerImages.ToArray(); - - imageWithData.DockerImages.Clear(); - imageWithData.Variables.Clear(); - - ImageRepository.Update(imageWithData); - - foreach (var variable in variables) - ImageVariableRepository.Delete(variable); - - foreach (var dockerImage in dockerImages) - DockerImageRepository.Delete(dockerImage); - - // And now we can clear the image - - ImageRepository.Delete(imageWithData); - - // and notify the user - await ToastService.Success("Successfully deleted image"); - await LazyLoader.Reload(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Images/New.razor b/Moonlight/Features/Servers/UI/Views/Admin/Images/New.razor deleted file mode 100644 index 6a4d3dd..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Images/New.razor +++ /dev/null @@ -1,55 +0,0 @@ -@page "/admin/servers/images/new" - -@using Moonlight.Features.Servers.Models.Forms.Admin.Images - - -@using Moonlight.Features.Servers.Entities -@using Mappy.Net -@using MoonCore.Abstractions -@using MoonCoreUI.Services - -@inject NavigationManager Navigation -@inject ToastService ToastService -@inject Repository ImageRepository - -
    -
    - Create new image -
    - -
    - -
    - -
    -
    - -@code -{ - private CreateImageForm Form = new(); - - private async Task Submit() - { - var image = Mapper.Map(Form); - - image.InstallDockerImage = "alpine:latest"; - image.InstallShell = "/bin/ash"; - image.InstallScript = "#! /bin/ash\necho Installation done"; - - image.AllocationsNeeded = 1; - image.StartupCommand = ""; - image.StopCommand = "^C"; - image.OnlineDetection = "Done"; - - image.ParseConfigurations = "[]"; - - ImageRepository.Add(image); - - await ToastService.Success("Successfully created image"); - Navigation.NavigateTo("/admin/servers/images"); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/ConfigParsing.razor b/Moonlight/Features/Servers/UI/Views/Admin/Images/View/ConfigParsing.razor deleted file mode 100644 index 35bd68f..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/ConfigParsing.razor +++ /dev/null @@ -1,66 +0,0 @@ -@page "/admin/servers/images/{Id:int}/configparsing" - -@using Moonlight.Features.Servers.Entities - - -@using Moonlight.Features.Servers.UI.Components - -@using MoonCore.Exceptions -@using MoonCore.Abstractions -@using MoonCoreUI.Services - -@inject Repository ImageRepository -@inject ToastService ToastService - - - @if (Image == null) - { - - } - else - { - - - - -
    -
    - -
    -
    - } -
    - -@code -{ - [Parameter] - public int Id { get; set; } - - private ServerImage? Image; - - private ParseConfigEditor ParseConfigEditor; - - private Task Load(LazyLoader arg) - { - Image = ImageRepository - .Get() - .FirstOrDefault(x => x.Id == Id); - - return Task.CompletedTask; - } - - private async Task OnSave() - { - try - { - Image!.ParseConfigurations = await ParseConfigEditor.ValidateAndGet(); - ImageRepository.Update(Image); - - await ToastService.Success("Successfully updated image"); - } - catch (DisplayException e) - { - await ToastService.Danger(e.Message); - } - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Details.razor b/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Details.razor deleted file mode 100644 index 657c18f..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Details.razor +++ /dev/null @@ -1,72 +0,0 @@ -@page "/admin/servers/images/{Id:int}/details" - -@using Moonlight.Features.Servers.Entities - -@using Moonlight.Features.Servers.Models.Forms.Admin.Images -@using Mappy.Net -@using MoonCore.Abstractions -@using MoonCoreUI.Services - -@using Moonlight.Features.Servers.UI.Components - -@inject Repository ImageRepository -@inject ToastService ToastService - - - @if (Image == null) - { - - } - else - { - - -
    -
    - Update image details -
    - -
    - -
    - -
    -
    - } -
    - -@code -{ - [Parameter] - public int Id { get; set; } - - private ServerImage? Image; - - private UpdateImageDetailsForm Form = new(); - - private Task Load(LazyLoader arg) - { - Image = ImageRepository - .Get() - .FirstOrDefault(x => x.Id == Id); - - if (Image != null) - { - Form = Mapper.Map(Image); - } - - return Task.CompletedTask; - } - - private async Task Submit() - { - Image = Mapper.Map(Image, Form); - ImageRepository.Update(Image!); - - await ToastService.Success("Successfully updated image"); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/DockerImages.razor b/Moonlight/Features/Servers/UI/Views/Admin/Images/View/DockerImages.razor deleted file mode 100644 index 437863d..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/DockerImages.razor +++ /dev/null @@ -1,130 +0,0 @@ -@page "/admin/servers/images/{Id:int}/dockerimages" - -@using Moonlight.Features.Servers.Entities - -@using Moonlight.Features.Servers.Models.Forms.Admin.Images -@using Moonlight.Features.Servers.UI.Components -@using BlazorTable -@using Microsoft.EntityFrameworkCore - -@using Microsoft.AspNetCore.Components.Forms -@using MoonCore.Abstractions -@using MoonCoreUI.Services - -@inject Repository ImageRepository -@inject ToastService ToastService - - - @if (Image == null) - { - - } - else - { - - -
    -
    -
    -
    - - -
    -
    - -
    - -
    -
    -
    -
    - -
    - - - - - - - - - - - - } -
    - -@code -{ - [Parameter] public int Id { get; set; } - - private ServerImage? Image; - - private ServerDockerImage? SelectedDockerImage - { - get - { - if (Image == null) - return null; - - if (Image.DefaultDockerImageIndex >= Image.DockerImages.Count) - return null; - - if (Image.DefaultDockerImageIndex == -1) - return null; - - return Image.DockerImages[Image.DefaultDockerImageIndex]; - } - set - { - if (Image == null) - return; - - if (value == null) - { - Image.DefaultDockerImageIndex = -1; - return; - } - - Image.DefaultDockerImageIndex = Image.DockerImages.IndexOf(value); - } - } - - private Task Load(LazyLoader arg) - { - Image = ImageRepository - .Get() - .Include(x => x.DockerImages) - .FirstOrDefault(x => x.Id == Id); - - return Task.CompletedTask; - } - - private async Task OnSave() - { - ImageRepository.Update(Image!); - - await ToastService.Success("Successfully updated image"); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Index.razor b/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Index.razor deleted file mode 100644 index e145858..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Index.razor +++ /dev/null @@ -1,72 +0,0 @@ -@page "/admin/servers/images/{Id:int}" - -@using Moonlight.Features.Servers.Entities - -@using Moonlight.Features.Servers.Models.Forms.Admin.Images -@using Mappy.Net -@using MoonCore.Abstractions -@using MoonCoreUI.Services - -@using Moonlight.Features.Servers.UI.Components - -@inject Repository ImageRepository -@inject ToastService ToastService - - - @if (Image == null) - { - - } - else - { - - -
    -
    - Update image -
    - -
    - -
    - -
    -
    - } -
    - -@code -{ - [Parameter] - public int Id { get; set; } - - private ServerImage? Image; - - private UpdateImageForm Form = new(); - - private Task Load(LazyLoader arg) - { - Image = ImageRepository - .Get() - .FirstOrDefault(x => x.Id == Id); - - if (Image != null) - { - Form = Mapper.Map(Image); - } - - return Task.CompletedTask; - } - - private async Task Submit() - { - Image = Mapper.Map(Image, Form); - ImageRepository.Update(Image!); - - await ToastService.Success("Successfully updated image"); - } -} diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Installation.razor b/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Installation.razor deleted file mode 100644 index fd0b42c..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Installation.razor +++ /dev/null @@ -1,72 +0,0 @@ -@page "/admin/servers/images/{Id:int}/installation" - -@using Moonlight.Features.Servers.Entities - -@using Moonlight.Features.Servers.Models.Forms.Admin.Images -@using Mappy.Net -@using MoonCore.Abstractions -@using MoonCoreUI.Services - -@using Moonlight.Features.Servers.UI.Components - -@inject Repository ImageRepository -@inject ToastService ToastService - - - @if (Image == null) - { - - } - else - { - - -
    -
    - Update image installation details -
    - -
    - -
    - -
    -
    - } -
    - -@code -{ - [Parameter] - public int Id { get; set; } - - private ServerImage? Image; - - private UpdateImageInstallationForm Form = new(); - - private Task Load(LazyLoader arg) - { - Image = ImageRepository - .Get() - .FirstOrDefault(x => x.Id == Id); - - if (Image != null) - { - Form = Mapper.Map(Image); - } - - return Task.CompletedTask; - } - - private async Task Submit() - { - Image = Mapper.Map(Image, Form); - ImageRepository.Update(Image!); - - await ToastService.Success("Successfully updated image"); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Variables.razor b/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Variables.razor deleted file mode 100644 index 033da61..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Images/View/Variables.razor +++ /dev/null @@ -1,78 +0,0 @@ -@page "/admin/servers/images/{Id:int}/variables" - -@using Moonlight.Features.Servers.Entities - -@using Moonlight.Features.Servers.UI.Components -@using Microsoft.EntityFrameworkCore -@using BlazorTable -@using MoonCore.Abstractions -@using Moonlight.Features.Servers.Models.Forms.Admin.Images - -@inject Repository ImageRepository - - - @if (Image == null) - { - - } - else - { - - - - - - - - - - - - - - - - - } - - -@code -{ - [Parameter] public int Id { get; set; } - - private ServerImage? Image; - - private Task Load(LazyLoader arg) - { - Image = ImageRepository - .Get() - .Include(x => x.Variables) - .FirstOrDefault(x => x.Id == Id); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Index.razor b/Moonlight/Features/Servers/UI/Views/Admin/Index.razor deleted file mode 100644 index 50475f2..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Index.razor +++ /dev/null @@ -1,76 +0,0 @@ -@page "/admin/servers" - -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - -@using Moonlight.Features.Servers.UI.Components -@using Moonlight.Features.Servers.Entities -@using Moonlight.Features.Servers.Models.Forms.Admin -@using Microsoft.EntityFrameworkCore - - -@using BlazorTable -@using MoonCore.Abstractions -@using MoonCore.Exceptions -@using MoonCore.Helpers -@using Moonlight.Features.Servers.Models.Forms.Admin.Nodes - -@attribute [RequirePermission(Permission.AdminServers)] - -@inject Repository NodeRepository - - - - - - - - - - - - - - - - -@code -{ - private ServerNode[] Load(Repository repository) - { - return repository.Get().ToArray(); - } - - private Task ValidateAdd(ServerNode node) - { - // Generate token - node.Token = Formatter.GenerateString(32); - - return Task.CompletedTask; - } - - private Task ValidateDelete(ServerNode n) - { - var nodeHasAllocations = NodeRepository - .Get() - .Include(x => x.Allocations) - .First(x => x.Id == n.Id) - .Allocations - .Any(); - - if (nodeHasAllocations) - throw new DisplayException("The node still has allocations. Delete them in order to delete the node"); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Servers/UI/Views/Admin/Nodes/View.razor b/Moonlight/Features/Servers/UI/Views/Admin/Nodes/View.razor deleted file mode 100644 index b08795c..0000000 --- a/Moonlight/Features/Servers/UI/Views/Admin/Nodes/View.razor +++ /dev/null @@ -1,166 +0,0 @@ -@page "/admin/servers/nodes/{Id:int}" - -@using BlazorTable -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions -@using MoonCore.Exceptions -@using MoonCoreUI.Services -@using Moonlight.Features.Servers.Entities -@using Moonlight.Features.Servers.Models.Forms.Admin.Nodes - -@inject Repository NodeRepository -@inject Repository ServerRepository -@inject Repository AllocationRepository -@inject ToastService ToastService -@inject AlertService AlertService - - - @if (Node == null) - { - - } - else - { -
    -
    - -
    -
    -
    -
    - Allocation Quick Add -
    -
    -
    - - - - - -
    -
    -
    - - -
    - - - -
    -
    - - - - - -
    -
    -
    - } -
    - -@code -{ - [Parameter] public int Id { get; set; } - - private ServerNode? Node; - private int AllocationStart = 2000; - private int AllocationEnd = 3000; - - private LazyLoader LazyLoader; - - private async Task Load(LazyLoader lazyLoader) - { - await lazyLoader.SetText("Loading allocations"); - - Node = NodeRepository - .Get() - .Include(x => x.Allocations) - .FirstOrDefault(x => x.Id == Id); - } - - private async Task AddAllocations() - { - int skipped = 0; - int added = 0; - - for (int i = AllocationStart; i <= AllocationEnd; i++) - { - if (Node!.Allocations.Any(x => x.Port == i)) - skipped++; - else - { - Node.Allocations.Add(new() - { - Port = i - }); - - added++; - } - } - - NodeRepository.Update(Node!); - - await ToastService.Success($"Added {added} allocations and skipped {skipped} ports due to existing allocations"); - await LazyLoader.Reload(); - } - - private Task ValidateAdd(ServerAllocation allocation) - { - if (Node!.Allocations.Any(x => x.Port == allocation.Port && x.IpAddress == allocation.IpAddress)) - throw new DisplayException("A allocation with these ip and port does already exist"); - - return Task.CompletedTask; - } - - private Task ValidateUpdate(ServerAllocation allocation) - { - if (Node!.Allocations.Any(x => x.Port == allocation.Port && x.IpAddress == allocation.IpAddress && x.Id != allocation.Id)) - throw new DisplayException("A allocation with these ip and port does already exist"); - - return Task.CompletedTask; - } - - private Task ValidateDelete(ServerAllocation allocation) - { - if (ServerRepository - .Get() - .Any(x => x.Allocations.Any(y => y.Id == allocation.Id))) - { - throw new DisplayException("A server is using this allocation. Delete the server in order to delete this allocation"); - } - - return Task.CompletedTask; - } - - private async Task DeleteAllAllocations() - { - if (!await AlertService.YesNo("Do you really want to delete all allocations?", "Yes", "No")) - return; - - foreach (var allocation in Node!.Allocations.ToArray()) // To array in order to prevent collection modified exception - { - if (ServerRepository - .Get() - .Any(x => x.Allocations.Any(y => y.Id == allocation.Id))) - { - await ToastService.Danger($"Unable to delete allocation with port {allocation.Port} due to a server using this allocation"); - continue; - } - - AllocationRepository.Delete(allocation); - } - - await ToastService.Success("Successfully deleted allocations"); - await LazyLoader.Reload(); - } - -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Entities/Enums/ServiceType.cs b/Moonlight/Features/ServiceManagement/Entities/Enums/ServiceType.cs deleted file mode 100644 index 50df6dd..0000000 --- a/Moonlight/Features/ServiceManagement/Entities/Enums/ServiceType.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Moonlight.Features.ServiceManagement.Entities.Enums; - -public enum ServiceType -{ - Server, - Webspace, - Database, - Domain -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Entities/Service.cs b/Moonlight/Features/ServiceManagement/Entities/Service.cs deleted file mode 100644 index 7e1c624..0000000 --- a/Moonlight/Features/ServiceManagement/Entities/Service.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Moonlight.Core.Database.Entities; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.ServiceManagement.Entities; - -public class Service -{ - public int Id { get; set; } - public string? Nickname { get; set; } - - public bool Suspended { get; set; } = false; - - public Product Product { get; set; } - public string? ConfigJsonOverride { get; set; } - - public User Owner { get; set; } - public List Shares { get; set; } = new(); - - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; - public DateTime RenewAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Entities/ServiceShare.cs b/Moonlight/Features/ServiceManagement/Entities/ServiceShare.cs deleted file mode 100644 index 20b5f8a..0000000 --- a/Moonlight/Features/ServiceManagement/Entities/ServiceShare.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Moonlight.Core.Database.Entities; - -namespace Moonlight.Features.ServiceManagement.Entities; - -public class ServiceShare -{ - public int Id { get; set; } - public User User { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceActions.cs b/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceActions.cs deleted file mode 100644 index 2c04d8a..0000000 --- a/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceActions.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Moonlight.Features.ServiceManagement.Entities; - -namespace Moonlight.Features.ServiceManagement.Models.Abstractions; - -public abstract class ServiceActions -{ - public abstract Task Create(IServiceProvider provider, Service service); - public abstract Task Update(IServiceProvider provider, Service service); - public abstract Task Delete(IServiceProvider provider, Service service); -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceDefinition.cs b/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceDefinition.cs deleted file mode 100644 index 221ffbe..0000000 --- a/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceDefinition.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Moonlight.Features.ServiceManagement.Models.Abstractions; - -public abstract class ServiceDefinition -{ - // Config - public abstract ServiceActions Actions { get; } - public abstract Type ConfigType { get; } - - // Methods - public abstract Task BuildUserView(ServiceViewContext context); - public abstract Task BuildAdminView(ServiceViewContext context); -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceUiPage.cs b/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceUiPage.cs deleted file mode 100644 index 27f866f..0000000 --- a/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceUiPage.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Microsoft.AspNetCore.Components; - -namespace Moonlight.Features.ServiceManagement.Models.Abstractions; - -public class ServiceUiPage -{ - public string Name { get; set; } - public string Route { get; set; } - public string Icon { get; set; } - public RenderFragment Component { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceViewContext.cs b/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceViewContext.cs deleted file mode 100644 index 1ec70c7..0000000 --- a/Moonlight/Features/ServiceManagement/Models/Abstractions/ServiceViewContext.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Microsoft.AspNetCore.Components; -using MoonCoreUI.Helpers; -using Moonlight.Core.Database.Entities; - -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.ServiceManagement.Models.Abstractions; - -public class ServiceViewContext -{ - // Meta - public Service Service { get; set; } - public User User { get; set; } - public Product Product { get; set; } - - // Content - public List Pages { get; set; } = new(); - public Type Layout { get; set; } - - public Task AddPage(string name, string route, string icon = "") where T : ComponentBase - { - Pages.Add(new() - { - Name = name, - Route = route, - Icon = icon, - Component = ComponentHelper.FromType() - }); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Models/Forms/AddUserToServiceForm.cs b/Moonlight/Features/ServiceManagement/Models/Forms/AddUserToServiceForm.cs deleted file mode 100644 index 48afc85..0000000 --- a/Moonlight/Features/ServiceManagement/Models/Forms/AddUserToServiceForm.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.ServiceManagement.Models.Forms; - -public class AddUserToServiceForm -{ - [Required(ErrorMessage = "You need to provide an username")] - [MinLength(7, ErrorMessage = "The username is too short")] - [MaxLength(20, ErrorMessage = "The username cannot be longer than 20 characters")] - [RegularExpression("^[a-z][a-z0-9]*$", - ErrorMessage = "Usernames can only contain lowercase characters and numbers")] - public string Username { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Services/ServiceAdminService.cs b/Moonlight/Features/ServiceManagement/Services/ServiceAdminService.cs deleted file mode 100644 index d55a518..0000000 --- a/Moonlight/Features/ServiceManagement/Services/ServiceAdminService.cs +++ /dev/null @@ -1,93 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Exceptions; -using Moonlight.Core.Database.Entities; - - -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.ServiceManagement.Services; - -[Singleton] -public class ServiceAdminService -{ - private readonly IServiceScopeFactory ServiceScopeFactory; - private readonly ServiceDefinitionService ServiceDefinitionService; - - public ServiceAdminService(IServiceScopeFactory serviceScopeFactory, ServiceDefinitionService serviceDefinitionService) - { - ServiceScopeFactory = serviceScopeFactory; - ServiceDefinitionService = serviceDefinitionService; - } - - public async Task Create(User u, Product p, Action? modifyService = null) - { - var impl = ServiceDefinitionService.Get(p); - - // Load models in new scope - using var scope = ServiceScopeFactory.CreateScope(); - var userRepo = scope.ServiceProvider.GetRequiredService>(); - var productRepo = scope.ServiceProvider.GetRequiredService>(); - var serviceRepo = scope.ServiceProvider.GetRequiredService>(); - - var user = userRepo.Get().First(x => x.Id == u.Id); - var product = productRepo.Get().First(x => x.Id == p.Id); - - // Create database model - var service = new Service() - { - Product = product, - Owner = user, - Suspended = false, - CreatedAt = DateTime.UtcNow - }; - - // Allow further modifications - if(modifyService != null) - modifyService.Invoke(service); - - // Add new service in database - var finishedService = serviceRepo.Add(service); - - try - { - // Call the action for the logic behind the service type - await impl.Actions.Create(scope.ServiceProvider, finishedService); - } - catch (Exception) // Handle any implementation errors and let the creation fail - { - serviceRepo.Delete(finishedService); - throw; - } - - return finishedService; - } - - public async Task Delete(Service s) - { - using var scope = ServiceScopeFactory.CreateScope(); - var serviceRepo = scope.ServiceProvider.GetRequiredService>(); - var serviceShareRepo = scope.ServiceProvider.GetRequiredService>(); - - var service = serviceRepo - .Get() - .Include(x => x.Shares) - .FirstOrDefault(x => x.Id == s.Id); - - if (service == null) - throw new DisplayException("Service does not exist anymore"); - - var impl = ServiceDefinitionService.Get(service); - - await impl.Actions.Delete(scope.ServiceProvider, service); - - foreach (var share in service.Shares.ToArray()) - { - serviceShareRepo.Delete(share); - } - - serviceRepo.Delete(service); - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Services/ServiceDefinitionService.cs b/Moonlight/Features/ServiceManagement/Services/ServiceDefinitionService.cs deleted file mode 100644 index 421fe5d..0000000 --- a/Moonlight/Features/ServiceManagement/Services/ServiceDefinitionService.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; - -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.ServiceManagement.Entities.Enums; -using Moonlight.Features.ServiceManagement.Models.Abstractions; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.ServiceManagement.Services; - -[Singleton] -public class ServiceDefinitionService -{ - private readonly Dictionary ServiceImplementations = new(); - - private readonly IServiceScopeFactory ServiceScopeFactory; - - public ServiceDefinitionService(IServiceScopeFactory serviceScopeFactory) - { - ServiceScopeFactory = serviceScopeFactory; - } - - public void Register(ServiceType type) where T : ServiceDefinition - { - var impl = Activator.CreateInstance() as ServiceDefinition; - - if (impl == null) - throw new ArgumentException("The provided type is not an service implementation"); - - if (ServiceImplementations.ContainsKey(type)) - throw new ArgumentException($"An implementation for {type} has already been registered"); - - ServiceImplementations.Add(type, impl); - } - - public ServiceDefinition Get(Service s) - { - using var scope = ServiceScopeFactory.CreateScope(); - var serviceRepo = scope.ServiceProvider.GetRequiredService>(); - - var service = serviceRepo - .Get() - .Include(x => x.Product) - .First(x => x.Id == s.Id); - - return Get(service.Product); - } - - public ServiceDefinition Get(Product p) => Get(p.Type); - - public ServiceDefinition Get(ServiceType type) - { - if (!ServiceImplementations.ContainsKey(type)) - throw new ArgumentException($"No service implementation found for {type}"); - - return ServiceImplementations[type]; - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Services/ServiceManageService.cs b/Moonlight/Features/ServiceManagement/Services/ServiceManageService.cs deleted file mode 100644 index 7e04a28..0000000 --- a/Moonlight/Features/ServiceManagement/Services/ServiceManageService.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Models.Abstractions; -using Moonlight.Core.Models.Enums; - -using Moonlight.Features.ServiceManagement.Entities; - -namespace Moonlight.Features.ServiceManagement.Services; - -[Singleton] -public class ServiceManageService -{ - private readonly IServiceScopeFactory ServiceScopeFactory; - - public ServiceManageService(IServiceScopeFactory serviceScopeFactory) - { - ServiceScopeFactory = serviceScopeFactory; - } - - public Task CheckAccess(Service s, User user) - { - var permissionStorage = new PermissionStorage(user.Permissions); - - // Is admin? - if(permissionStorage[Permission.AdminServices]) - return Task.FromResult(true); - - using var scope = ServiceScopeFactory.CreateScope(); - var serviceRepo = scope.ServiceProvider.GetRequiredService>(); - - var service = serviceRepo - .Get() - .Include(x => x.Owner) - .Include(x => x.Shares) - .ThenInclude(x => x.User) - .First(x => x.Id == s.Id); - - // Is owner? - if(service.Owner.Id == user.Id) - return Task.FromResult(true); - - // Is shared user - if(service.Shares.Any(x => x.User.Id == user.Id)) - return Task.FromResult(true); - - // No match - return Task.FromResult(false); - } - - public Task NeedsRenewal(Service s) - { - // We fetch the service in a new scope wo ensure that we are not caching - using var scope = ServiceScopeFactory.CreateScope(); - var serviceRepo = scope.ServiceProvider.GetRequiredService>(); - - var service = serviceRepo - .Get() - .First(x => x.Id == s.Id); - - return Task.FromResult(DateTime.UtcNow > service.RenewAt); - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/Services/ServiceService.cs b/Moonlight/Features/ServiceManagement/Services/ServiceService.cs deleted file mode 100644 index bbb6e24..0000000 --- a/Moonlight/Features/ServiceManagement/Services/ServiceService.cs +++ /dev/null @@ -1,118 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Exceptions; -using Moonlight.Core.Database.Entities; - - -using Moonlight.Features.ServiceManagement.Entities; - -namespace Moonlight.Features.ServiceManagement.Services; - -[Scoped] -public class ServiceService // This service is used for managing services and create the connection to the actual logic behind a service type -{ - private readonly IServiceProvider ServiceProvider; - private readonly Repository ServiceRepository; - private readonly Repository UserRepository; - - public ServiceAdminService Admin => ServiceProvider.GetRequiredService(); - public ServiceDefinitionService Definition => ServiceProvider.GetRequiredService(); - public ServiceManageService Manage => ServiceProvider.GetRequiredService(); - - public ServiceService(IServiceProvider serviceProvider, Repository serviceRepository, Repository userRepository) - { - ServiceProvider = serviceProvider; - ServiceRepository = serviceRepository; - UserRepository = userRepository; - } - - public Task Get(User user) - { - var result = ServiceRepository - .Get() - .Include(x => x.Product) - .Where(x => x.Owner.Id == user.Id) - .ToArray(); - - return Task.FromResult(result); - } - - public Task GetShared(User user) - { - var result = ServiceRepository - .Get() - .Include(x => x.Product) - .Include(x => x.Owner) - .Where(x => x.Shares.Any(y => y.User.Id == user.Id)) - .ToArray(); - - return Task.FromResult(result); - } - - public Task AddSharedUser(Service s, string username) - { - var userToAdd = UserRepository - .Get() - .FirstOrDefault(x => x.Username == username); - - if (userToAdd == null) - throw new DisplayException("No user found with this username"); - - var service = ServiceRepository - .Get() - .Include(x => x.Owner) - .Include(x => x.Shares) - .ThenInclude(x => x.User) - .First(x => x.Id == s.Id); - - if (service.Owner.Id == userToAdd.Id) - throw new DisplayException("The owner cannot be added as a shared user"); - - if (service.Shares.Any(x => x.User.Id == userToAdd.Id)) - throw new DisplayException("The user has already access to this service"); - - service.Shares.Add(new () - { - User = userToAdd - }); - - ServiceRepository.Update(service); - - return Task.CompletedTask; - } - - public Task GetSharedUsers(Service s) - { - var service = ServiceRepository - .Get() - .Include(x => x.Shares) - .ThenInclude(x => x.User) - .First(x => x.Id == s.Id); - - var result = service.Shares - .Select(x => x.User) - .ToArray(); - - return Task.FromResult(result); - } - - public Task RemoveSharedUser(Service s, User user) - { - var service = ServiceRepository - .Get() - .Include(x => x.Shares) - .ThenInclude(x => x.User) - .First(x => x.Id == s.Id); - - var shareToRemove = service.Shares.FirstOrDefault(x => x.User.Id == user.Id); - - if (shareToRemove == null) - throw new DisplayException("This user does not have access to this service"); - - service.Shares.Remove(shareToRemove); - ServiceRepository.Update(service); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/UI/Components/ManageServiceShareModal.razor b/Moonlight/Features/ServiceManagement/UI/Components/ManageServiceShareModal.razor deleted file mode 100644 index d8e5bd8..0000000 --- a/Moonlight/Features/ServiceManagement/UI/Components/ManageServiceShareModal.razor +++ /dev/null @@ -1,106 +0,0 @@ -@using BlazorTable -@using Moonlight.Core.Database.Entities -@using Moonlight.Features.ServiceManagement.Entities -@using Moonlight.Features.ServiceManagement.Models.Forms -@using Moonlight.Features.ServiceManagement.Services - -@inject ServiceService ServiceService - - - - - - - -@code -{ - [Parameter] - public Service Service { get; set; } - - private SmartModal Modal; - private LazyLoader LazyLoader; - private User[] Users; - - private AddUserToServiceForm Form = new(); - - private async Task Load(LazyLoader _) - { - Users = await ServiceService.GetSharedUsers(Service); - } - - private async Task Add() - { - await ServiceService.AddSharedUser(Service, Form.Username); - Form = new(); - await LazyLoader.Reload(); - } - - private async Task Remove(User user) - { - await ServiceService.RemoveSharedUser(Service, user); - await LazyLoader.Reload(); - } - - public async Task Show() - { - await Modal.Show(); - } - - public async Task Hide() - { - await Modal.Hide(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/UI/Components/NeedsRenewalAlert.razor b/Moonlight/Features/ServiceManagement/UI/Components/NeedsRenewalAlert.razor deleted file mode 100644 index a21d6d4..0000000 --- a/Moonlight/Features/ServiceManagement/UI/Components/NeedsRenewalAlert.razor +++ /dev/null @@ -1,16 +0,0 @@ -
    -
    -
    -
    - Expired illustration -
    -

    - This service has expired -

    -
    - This service has expired and has to be renewed in order to manage it -
    - Go back to services -
    -
    -
    \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/UI/Components/ServiceItem.razor b/Moonlight/Features/ServiceManagement/UI/Components/ServiceItem.razor deleted file mode 100644 index 3dc9533..0000000 --- a/Moonlight/Features/ServiceManagement/UI/Components/ServiceItem.razor +++ /dev/null @@ -1,278 +0,0 @@ - - -@using Moonlight.Core.Services - -@using Moonlight.Features.ServiceManagement.Entities -@using Moonlight.Features.ServiceManagement.Services -@using Moonlight.Features.StoreSystem.Services -@using MoonCore.Helpers -@using MoonCore.Services -@using MoonCore.Exceptions -@using MoonCoreUI.Services -@using Moonlight.Core.Configuration - -@inject ConfigService ConfigService -@inject ToastService ToastService -@inject ServiceService ServiceService -@inject StoreService StoreService -@inject IdentityService IdentityService - -@if (ShowDeletionScreen) -{ -
    -
    -

    - Do you really want to delete @(Service.Nickname ?? $"Service {Service.Id}") -

    -
    -
    -

    - This action cannot be undone. Your service data will be deleted and cannot be restored -

    -
    - -
    -} -else if (ShowRenewScreen) -{ -
    -
    -

    - Do you want to renew @(Service.Nickname ?? $"Service {Service.Id}") -

    -
    -
    - - - @{ - var actualPrice = Service.Product.Price * DurationMultiplier; - var currency = ConfigService.Get().Store.Currency; - } - -
    -
    Today
    -
    - @(currency) @(actualPrice) -
    -
    -
    -
    Renew
    -
    - @(currency) @(Service.Product.Price) -
    -
    -
    -
    Duration
    -
    - @(Service.Product.Duration * DurationMultiplier) days -
    -
    -
    -
    -
    Total
    -
    - @(currency) @(actualPrice) -
    -
    -
    - @if (!CanBeRenewed && !string.IsNullOrEmpty(ErrorMessage)) - { -
    - @ErrorMessage -
    - } -
    -
    - @if (IsValidating) - { - - } - else - { - if (CanBeRenewed) - { - - } - else - { - - } - } -
    -
    - -
    -} -else -{ -
    -
    -

    - - @(Service.Nickname ?? $"Service {Service.Id}") - @if (NeedsRenewal) - { - (Expired) - } - - @(Service.Product.Name) -

    -
    -
    -
    -
    Renew price
    -
    - @(ConfigService.Get().Store.Currency) @(Service.Product.Price) -
    -
    -
    -
    Renew at
    -
    - @(Formatter.FormatDate(Service.RenewAt)) -
    -
    -
    -
    Created at
    -
    - @(Formatter.FormatDate(Service.CreatedAt)) -
    -
    -
    - -
    - - -} - - - -@code -{ - [Parameter] - public Service Service { get; set; } - - [Parameter] - public Func OnChange { get; set; } - - // Renew access state - private bool NeedsRenewal = false; - - // States - private bool ShowDeletionScreen = false; - private ManageServiceShareModal ShareModal; - - // Renewing - private int DurationMultiplier = 1; - private bool CanBeRenewed = false; - private bool IsValidating = false; - private string ErrorMessage = ""; - private bool ShowRenewScreen = false; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - NeedsRenewal = await ServiceService.Manage.NeedsRenewal(Service); - await InvokeAsync(StateHasChanged); - } - } - - private Task Revalidate() - { - IsValidating = true; - InvokeAsync(StateHasChanged); - - Task.Run(async () => - { - try - { - await StoreService.Order.ValidateRenew(IdentityService.CurrentUser, Service, DurationMultiplier); - CanBeRenewed = true; - } - catch (DisplayException e) - { - CanBeRenewed = false; - ErrorMessage = e.Message; - } - - IsValidating = false; - await InvokeAsync(StateHasChanged); - }); - - return Task.CompletedTask; - } - - private async Task Renew() - { - await StoreService.Order.Renew(IdentityService.CurrentUser, Service, DurationMultiplier); - - await ToastService.Success("Successfully renewed service"); - await OnChange.Invoke(); - } - - private async Task SetDurationMultiplier(int i) - { - DurationMultiplier = i; - await Revalidate(); - } - - private async Task SetShowDeletion(bool b) - { - ShowDeletionScreen = b; - await InvokeAsync(StateHasChanged); - } - - private async Task SetShowRenew(bool b) - { - ShowRenewScreen = b; - - if (b) // Revalidate when the renew screen is shown - await Revalidate(); - - await InvokeAsync(StateHasChanged); - } - - public async Task Delete() - { - await ServiceService.Admin.Delete(Service); - - await ToastService.Success("Successfully deleted service"); - await OnChange.Invoke(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/UI/Views/Admin/Index.razor b/Moonlight/Features/ServiceManagement/UI/Views/Admin/Index.razor deleted file mode 100644 index ac2a259..0000000 --- a/Moonlight/Features/ServiceManagement/UI/Views/Admin/Index.razor +++ /dev/null @@ -1,72 +0,0 @@ -@page "/admin/services" -@using Microsoft.EntityFrameworkCore -@using BlazorTable -@using MoonCore.Abstractions -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - -@using Moonlight.Features.ServiceManagement.Entities - -@attribute [RequirePermission(Permission.AdminServices)] - -@inject Repository ServiceRepository - -
    -
    -

    Services

    -
    -
    - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    - -@code -{ - private Service[] Services; - - private Task Load(LazyLoader lazyLoader) - { - Services = ServiceRepository - .Get() - .Include(x => x.Owner) - .Include(x => x.Product) - .ToArray(); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/UI/Views/Admin/View.razor b/Moonlight/Features/ServiceManagement/UI/Views/Admin/View.razor deleted file mode 100644 index 5a85b50..0000000 --- a/Moonlight/Features/ServiceManagement/UI/Views/Admin/View.razor +++ /dev/null @@ -1,81 +0,0 @@ -@page "/admin/services/view/{Id:int}/{Route?}" - -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums -@using Moonlight.Core.Services -@using Moonlight.Features.ServiceManagement.Entities -@using Moonlight.Features.ServiceManagement.Models.Abstractions -@using Moonlight.Features.ServiceManagement.Services - -@attribute [RequirePermission(Permission.AdminServices)] - -@inject Repository ServiceRepository -@inject ServiceService ServiceService -@inject IdentityService IdentityService -@inject PluginService PluginService - - - @if (Service == null) - { - - } - else - { - - - - - @ViewContext.Layout - - - - - } - - -@code -{ - [Parameter] - public int Id { get; set; } - - [Parameter] - public string? Route { get; set; } - - private Service? Service; - private ServiceDefinition Definition; - private ServiceViewContext ViewContext; - - private async Task Load(LazyLoader lazyLoader) - { - await lazyLoader.SetText("Requesting service"); - - // Load service with relational data - Service = ServiceRepository - .Get() - .Include(x => x.Product) - .Include(x => x.Owner) - .FirstOrDefault(x => x.Id == Id); - - if(Service == null) - return; - - // Load implementation - await lazyLoader.SetText("Loading implementation"); - Definition = ServiceService.Definition.Get(Service.Product.Type); - - // Build dynamic user interface - await lazyLoader.SetText("Building dynamic user interface"); - - ViewContext = new ServiceViewContext() - { - Service = Service, - Product = Service.Product, - User = IdentityService.CurrentUser - }; - - await Definition.BuildAdminView(ViewContext); - await PluginService.BuildAdminServiceView(ViewContext); - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/UI/Views/Index.razor b/Moonlight/Features/ServiceManagement/UI/Views/Index.razor deleted file mode 100644 index 4a895f1..0000000 --- a/Moonlight/Features/ServiceManagement/UI/Views/Index.razor +++ /dev/null @@ -1,85 +0,0 @@ -@page "/services" - - -@using Moonlight.Core.Services -@using Moonlight.Features.ServiceManagement.Entities -@using Moonlight.Features.ServiceManagement.Services -@using Moonlight.Features.ServiceManagement.UI.Components -@using MoonCore.Helpers - -@inject ServiceService ServiceService -@inject IdentityService IdentityService - - -
    - @foreach (var service in MyServices) - { -
    - -
    - } - - @foreach (var service in SharedServices) - { - var needsRenewal = SharedRenewalStates[service]; - -
    -
    -
    -

    - - @(service.Nickname ?? $"Service {service.Id}") - @if (needsRenewal) - { - (Expired) - } - - @(service.Product.Name) -

    -
    -
    -
    -
    Shared by
    -
    - @(service.Owner.Username) -
    -
    - -
    -
    Created at
    -
    - @(Formatter.FormatDate(service.CreatedAt)) -
    -
    -
    - -
    -
    - } -
    -
    - -@code -{ - private LazyLoader LazyLoader; - - private Service[] MyServices; - private Service[] SharedServices; - private Dictionary SharedRenewalStates = new(); - - private async Task Load(LazyLoader _) - { - // Load all services - MyServices = await ServiceService.Get(IdentityService.CurrentUser); - SharedServices = await ServiceService.GetShared(IdentityService.CurrentUser); - - // Load all services renewal states - foreach (var service in SharedServices) - { - if(!SharedRenewalStates.ContainsKey(service)) - SharedRenewalStates.Add(service, await ServiceService.Manage.NeedsRenewal(service)); - } - } -} \ No newline at end of file diff --git a/Moonlight/Features/ServiceManagement/UI/Views/View.razor b/Moonlight/Features/ServiceManagement/UI/Views/View.razor deleted file mode 100644 index 695244c..0000000 --- a/Moonlight/Features/ServiceManagement/UI/Views/View.razor +++ /dev/null @@ -1,102 +0,0 @@ -@page "/service/{Id:int}/{Route?}" - -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions -@using MoonCoreUI.Helpers -@using Moonlight.Features.ServiceManagement.UI.Components -@using Moonlight.Core.Services -@using Moonlight.Features.ServiceManagement.Entities -@using Moonlight.Features.ServiceManagement.Models.Abstractions -@using Moonlight.Features.ServiceManagement.Services - -@inject Repository ServiceRepository -@inject ServiceService ServiceService -@inject IdentityService IdentityService -@inject PluginService PluginService - - - @if (Service == null) - { - - } - else - { - if (NeedsRenewal) - { - - } - else - { - @Layout - } - } - - -@code -{ - [Parameter] - public int Id { get; set; } - - [Parameter] - public string? Route { get; set; } - - private Service? Service; - private ServiceDefinition Definition; - private ServiceViewContext ViewContext; - - private bool NeedsRenewal = false; - - private RenderFragment Layout; - - private async Task Load(LazyLoader lazyLoader) - { - await lazyLoader.SetText("Requesting service"); - - // Load service with relational data - Service = ServiceRepository - .Get() - .Include(x => x.Product) - .Include(x => x.Owner) - .FirstOrDefault(x => x.Id == Id); - - if(Service == null) - return; - - // Check permissions - if (!await ServiceService.Manage.CheckAccess(Service, IdentityService.CurrentUser)) - Service = null; - - if (Service == null) - return; - - NeedsRenewal = await ServiceService.Manage.NeedsRenewal(Service); - - if(NeedsRenewal) // Stop loading more data - return; - - // Load implementation - await lazyLoader.SetText("Loading implementation"); - Definition = ServiceService.Definition.Get(Service.Product.Type); - - // Build dynamic user interface - await lazyLoader.SetText("Building dynamic user interface"); - - ViewContext = new ServiceViewContext() - { - Service = Service, - Product = Service.Product, - User = IdentityService.CurrentUser - }; - - await Definition.BuildUserView(ViewContext); - await PluginService.BuildUserServiceView(ViewContext); - - Layout = ComponentHelper.FromType(ViewContext.Layout, parameters => - { - parameters.Add("Service", Service); - parameters.Add("Implementation", Definition); - parameters.Add("Route", Route!); - parameters.Add("ViewContext", ViewContext); - }); - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Configuration/StoreData.cs b/Moonlight/Features/StoreSystem/Configuration/StoreData.cs deleted file mode 100644 index fe59504..0000000 --- a/Moonlight/Features/StoreSystem/Configuration/StoreData.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.ComponentModel; -using Newtonsoft.Json; - -namespace Moonlight.Features.StoreSystem.Configuration; - -public class StoreData -{ - [JsonProperty("Currency")] - [Description("A string value representing the currency which will be shown to a user")] - public string Currency { get; set; } = "€"; -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Entities/Category.cs b/Moonlight/Features/StoreSystem/Entities/Category.cs deleted file mode 100644 index ad88074..0000000 --- a/Moonlight/Features/StoreSystem/Entities/Category.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Moonlight.Features.StoreSystem.Entities; - -public class Category -{ - public int Id { get; set; } - public string Name { get; set; } = ""; - public string Description { get; set; } = ""; - public string Slug { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Entities/Coupon.cs b/Moonlight/Features/StoreSystem/Entities/Coupon.cs deleted file mode 100644 index 0f5f91e..0000000 --- a/Moonlight/Features/StoreSystem/Entities/Coupon.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Moonlight.Features.StoreSystem.Entities; - -public class Coupon -{ - public int Id { get; set; } - public string Code { get; set; } = ""; - public int Percent { get; set; } - public int Amount { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Entities/CouponUse.cs b/Moonlight/Features/StoreSystem/Entities/CouponUse.cs deleted file mode 100644 index 54007ba..0000000 --- a/Moonlight/Features/StoreSystem/Entities/CouponUse.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Moonlight.Features.StoreSystem.Entities; - -public class CouponUse -{ - public int Id { get; set; } - public Coupon Coupon { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Entities/GiftCode.cs b/Moonlight/Features/StoreSystem/Entities/GiftCode.cs deleted file mode 100644 index 36a784c..0000000 --- a/Moonlight/Features/StoreSystem/Entities/GiftCode.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Moonlight.Features.StoreSystem.Entities; - -public class GiftCode -{ - public int Id { get; set; } - public string Code { get; set; } = ""; - public double Value { get; set; } - public int Amount { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Entities/GiftCodeUse.cs b/Moonlight/Features/StoreSystem/Entities/GiftCodeUse.cs deleted file mode 100644 index 4a129e7..0000000 --- a/Moonlight/Features/StoreSystem/Entities/GiftCodeUse.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Moonlight.Features.StoreSystem.Entities; - -public class GiftCodeUse -{ - public int Id { get; set; } - public GiftCode GiftCode { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Entities/Product.cs b/Moonlight/Features/StoreSystem/Entities/Product.cs deleted file mode 100644 index 1650085..0000000 --- a/Moonlight/Features/StoreSystem/Entities/Product.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Moonlight.Features.ServiceManagement.Entities.Enums; - -namespace Moonlight.Features.StoreSystem.Entities; - -public class Product -{ - public int Id { get; set; } - public Category Category { get; set; } - - public string Name { get; set; } = ""; - public string Description { get; set; } = ""; - public string Slug { get; set; } = ""; - - public double Price { get; set; } - public int Stock { get; set; } - public int MaxPerUser { get; set; } - public int Duration { get; set; } - - public ServiceType Type { get; set; } - public string ConfigJson { get; set; } = "{}"; - - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Entities/Transaction.cs b/Moonlight/Features/StoreSystem/Entities/Transaction.cs deleted file mode 100644 index feb531e..0000000 --- a/Moonlight/Features/StoreSystem/Entities/Transaction.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Moonlight.Features.StoreSystem.Entities; - -public class Transaction -{ - public int Id { get; set; } - public double Price { get; set; } - public string Text { get; set; } = ""; - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Abstractions/PaymentGateway.cs b/Moonlight/Features/StoreSystem/Models/Abstractions/PaymentGateway.cs deleted file mode 100644 index 1ceb232..0000000 --- a/Moonlight/Features/StoreSystem/Models/Abstractions/PaymentGateway.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Moonlight.Features.StoreSystem.Models.Abstractions; - -public abstract class PaymentGateway -{ - public abstract string Name { get; } - public abstract string Icon { get; } - public abstract Task Start(double price); -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Forms/AddCategoryForm.cs b/Moonlight/Features/StoreSystem/Models/Forms/AddCategoryForm.cs deleted file mode 100644 index a6a67a4..0000000 --- a/Moonlight/Features/StoreSystem/Models/Forms/AddCategoryForm.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.StoreSystem.Models.Forms; - -public class AddCategoryForm -{ - [Required(ErrorMessage = "You need to specify a name")] - public string Name { get; set; } = ""; - - public string Description { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a slug")] - [RegularExpression("^[a-z0-9-]+$", ErrorMessage = "You need to enter a valid slug only containing lowercase characters and numbers")] - public string Slug { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Forms/AddCouponForm.cs b/Moonlight/Features/StoreSystem/Models/Forms/AddCouponForm.cs deleted file mode 100644 index 7538d50..0000000 --- a/Moonlight/Features/StoreSystem/Models/Forms/AddCouponForm.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.StoreSystem.Models.Forms; - -public class AddCouponForm -{ - [MinLength(5, ErrorMessage = "The code needs to be longer than 4")] - [MaxLength(15, ErrorMessage = "The code should not be longer than 15 characters")] - public string Code { get; set; } = ""; - - [Range(1, 99, ErrorMessage = "The percent needs to be between 1 and 99")] - public int Percent { get; set; } - - [Range(0, int.MaxValue, ErrorMessage = "The amount needs to be equals or greater than 0")] - public int Amount { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Forms/AddGiftCodeForm.cs b/Moonlight/Features/StoreSystem/Models/Forms/AddGiftCodeForm.cs deleted file mode 100644 index e46d578..0000000 --- a/Moonlight/Features/StoreSystem/Models/Forms/AddGiftCodeForm.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.StoreSystem.Models.Forms; - -public class AddGiftCodeForm -{ - [MinLength(5, ErrorMessage = "The code needs to be longer than 4")] - [MaxLength(15, ErrorMessage = "The code should not be longer than 15 characters")] - public string Code { get; set; } = ""; - - [Range(0, int.MaxValue, ErrorMessage = "The value needs to be equals or greater than 0")] - public double Value { get; set; } - - [Range(0, int.MaxValue, ErrorMessage = "The amount needs to be equals or greater than 0")] - public int Amount { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Forms/AddProductForm.cs b/Moonlight/Features/StoreSystem/Models/Forms/AddProductForm.cs deleted file mode 100644 index 177ea6c..0000000 --- a/Moonlight/Features/StoreSystem/Models/Forms/AddProductForm.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using MoonCoreUI.Attributes; -using Moonlight.Core.Extensions.Attributes; -using Moonlight.Features.ServiceManagement.Entities.Enums; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.StoreSystem.Models.Forms; - -public class AddProductForm -{ - [Required(ErrorMessage = "You need to specify a category")] - [Selector(DisplayProp = "Name", SelectorProp = "Name", UseDropdown = true)] - public Category Category { get; set; } - - [Required(ErrorMessage = "You need to specify a name")] - [Description("Teeeeeeeeeeeeeeeeeeeeeeeeeest")] - public string Name { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a description")] - public string Description { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a slug")] - [RegularExpression("^[a-z0-9-]+$", ErrorMessage = "You need to enter a valid slug only containing lowercase characters and numbers")] - public string Slug { get; set; } = ""; - - [Range(0, double.MaxValue, ErrorMessage = "The price needs to be equals or greater than 0")] - public double Price { get; set; } - - [Range(0, double.MaxValue, ErrorMessage = "The stock needs to be equals or greater than 0")] - public int Stock { get; set; } - - [Range(0, double.MaxValue, ErrorMessage = "The max per user amount needs to be equals or greater than 0")] - public int MaxPerUser { get; set; } - - [Range(0, double.MaxValue, ErrorMessage = "The duration needs to be equals or greater than 0")] - public int Duration { get; set; } - - public ServiceType Type { get; set; } - public string ConfigJson { get; set; } = "{}"; -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Forms/EditCategoryForm.cs b/Moonlight/Features/StoreSystem/Models/Forms/EditCategoryForm.cs deleted file mode 100644 index f47a63a..0000000 --- a/Moonlight/Features/StoreSystem/Models/Forms/EditCategoryForm.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.StoreSystem.Models.Forms; - -public class EditCategoryForm -{ - [Required(ErrorMessage = "You need to specify a name")] - public string Name { get; set; } = ""; - - public string Description { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a slug")] - [RegularExpression("^[a-z0-9-]+$", ErrorMessage = "You need to enter a valid slug only containing lowercase characters and numbers")] - public string Slug { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Forms/EditCouponForm.cs b/Moonlight/Features/StoreSystem/Models/Forms/EditCouponForm.cs deleted file mode 100644 index 02dd8c2..0000000 --- a/Moonlight/Features/StoreSystem/Models/Forms/EditCouponForm.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.StoreSystem.Models.Forms; - -public class EditCouponForm -{ - [MinLength(5, ErrorMessage = "The code needs to be longer than 4")] - [MaxLength(15, ErrorMessage = "The code should not be longer than 15 characters")] - public string Code { get; set; } = ""; - - [Range(1, 99, ErrorMessage = "The percent needs to be between 1 and 99")] - public int Percent { get; set; } - - [Range(0, int.MaxValue, ErrorMessage = "The amount needs to be equals or greater than 0")] - public int Amount { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Forms/EditGiftCodeForm.cs b/Moonlight/Features/StoreSystem/Models/Forms/EditGiftCodeForm.cs deleted file mode 100644 index 881cd24..0000000 --- a/Moonlight/Features/StoreSystem/Models/Forms/EditGiftCodeForm.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.StoreSystem.Models.Forms; - -public class EditGiftCodeForm -{ - [MinLength(5, ErrorMessage = "The code needs to be longer than 4")] - [MaxLength(15, ErrorMessage = "The code should not be longer than 15 characters")] - public string Code { get; set; } = ""; - - [Range(0, int.MaxValue, ErrorMessage = "The value needs to be equals or greater than 0")] - public double Value { get; set; } - - [Range(0, int.MaxValue, ErrorMessage = "The amount needs to be equals or greater than 0")] - public int Amount { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Models/Forms/EditProductForm.cs b/Moonlight/Features/StoreSystem/Models/Forms/EditProductForm.cs deleted file mode 100644 index 775a1b1..0000000 --- a/Moonlight/Features/StoreSystem/Models/Forms/EditProductForm.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using Moonlight.Features.ServiceManagement.Entities.Enums; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.StoreSystem.Models.Forms; - -public class EditProductForm -{ - [Required(ErrorMessage = "You need to specify a category")] - public Category Category { get; set; } - - [Required(ErrorMessage = "You need to specify a name")] - public string Name { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a description")] - public string Description { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a slug")] - [RegularExpression("^[a-z0-9-]+$", ErrorMessage = "You need to enter a valid slug only containing lowercase characters and numbers")] - public string Slug { get; set; } = ""; - - [Range(0, double.MaxValue, ErrorMessage = "The price needs to be equals or above 0")] - public double Price { get; set; } - - [Range(0, double.MaxValue, ErrorMessage = "The stock needs to be equals or above 0")] - public int Stock { get; set; } - - [Range(0, double.MaxValue, ErrorMessage = "The max per user amount needs to be equals or above 0")] - public int MaxPerUser { get; set; } - - [Range(0, double.MaxValue, ErrorMessage = "The duration needs to be equals or above 0")] - public int Duration { get; set; } - - public ServiceType Type { get; set; } - public string ConfigJson { get; set; } = "{}"; -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Services/StoreAdminService.cs b/Moonlight/Features/StoreSystem/Services/StoreAdminService.cs deleted file mode 100644 index 3bcde9a..0000000 --- a/Moonlight/Features/StoreSystem/Services/StoreAdminService.cs +++ /dev/null @@ -1,146 +0,0 @@ -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Exceptions; - - -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.ServiceManagement.Entities.Enums; -using Moonlight.Features.ServiceManagement.Services; -using Moonlight.Features.StoreSystem.Entities; -using Newtonsoft.Json; - -namespace Moonlight.Features.StoreSystem.Services; - -[Scoped] -public class StoreAdminService -{ - private readonly Repository ProductRepository; - private readonly Repository CategoryRepository; - private readonly Repository ServiceRepository; - private readonly ServiceService ServiceService; - - public StoreAdminService( - Repository productRepository, - Repository categoryRepository, - ServiceService serviceService, - Repository serviceRepository) - { - ProductRepository = productRepository; - CategoryRepository = categoryRepository; - ServiceService = serviceService; - ServiceRepository = serviceRepository; - } - - public Task AddCategory(string name, string description, string slug) - { - if (CategoryRepository.Get().Any(x => x.Slug == slug)) - throw new DisplayException("A category with this slug does already exist"); - - var result = CategoryRepository.Add(new Category() - { - Name = name, - Description = description, - Slug = slug - }); - - return Task.FromResult(result); - } - - public Task AddProduct(string name, string description, string slug, ServiceType type, Action? modifyProduct = null) - { - if (ProductRepository.Get().Any(x => x.Slug == slug)) - throw new DisplayException("A product with that slug does already exist"); - - var product = new Product() - { - Name = name, - Description = description, - Slug = slug, - Type = type, - ConfigJson = "{}" - }; - - if(modifyProduct != null) - modifyProduct.Invoke(product); - - var result = ProductRepository.Add(product); - - return Task.FromResult(result); - } - - public Task UpdateCategory(Category category) - { - if (CategoryRepository.Get().Any(x => x.Id != category.Id && x.Slug == category.Slug)) - throw new DisplayException("A category with that slug does already exist"); - - CategoryRepository.Update(category); - - return Task.CompletedTask; - } - - public Task UpdateProduct(Product product) - { - if (ProductRepository.Get().Any(x => x.Id != product.Id && x.Slug == product.Slug)) - throw new DisplayException("A product with that slug does already exist"); - - ProductRepository.Update(product); - - return Task.CompletedTask; - } - - public Task DeleteCategory(Category category) - { - var hasProductsInIt = ProductRepository - .Get() - .Any(x => x.Category!.Id == category.Id); - - if (hasProductsInIt) - throw new DisplayException("The category contains products. You need to delete the products in order to delete the category"); - - CategoryRepository.Delete(category); - - return Task.CompletedTask; - } - - public Task DeleteProduct(Product product) - { - if (ServiceRepository.Get().Any(x => x.Product.Id == product.Id)) - throw new DisplayException("Product cannot be deleted as services related to this products exist. Delete the services first"); - - ProductRepository.Delete(product); - - return Task.CompletedTask; - } - - // Product config - public Type GetProductConfigType(ServiceType type) - { - try - { - var impl = ServiceService.Definition.Get(type); - return impl.ConfigType; - } - catch (ArgumentException) - { - return typeof(object); - } - } - public object CreateNewProductConfig(ServiceType type) - { - var config = Activator.CreateInstance(GetProductConfigType(type))!; - return config; - } - public object GetProductConfig(Product product) - { - var impl = ServiceService.Definition.Get(product.Type); - - return JsonConvert.DeserializeObject(product.ConfigJson, impl.ConfigType) ?? - CreateNewProductConfig(product.Type); - } - - public void SaveProductConfig(Product product, object config) - { - product.ConfigJson = JsonConvert.SerializeObject(config); - ProductRepository.Update(product); - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Services/StoreGiftService.cs b/Moonlight/Features/StoreSystem/Services/StoreGiftService.cs deleted file mode 100644 index b0a8344..0000000 --- a/Moonlight/Features/StoreSystem/Services/StoreGiftService.cs +++ /dev/null @@ -1,64 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Exceptions; -using Moonlight.Core.Database.Entities; - - -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.StoreSystem.Services; - -[Singleton] -public class StoreGiftService -{ - private readonly IServiceScopeFactory ServiceScopeFactory; - - public StoreGiftService(IServiceScopeFactory serviceScopeFactory) - { - ServiceScopeFactory = serviceScopeFactory; - } - - public async Task Redeem(User u, string code) - { - using var scope = ServiceScopeFactory.CreateScope(); - var giftCodeRepo = scope.ServiceProvider.GetRequiredService>(); - var userRepo = scope.ServiceProvider.GetRequiredService>(); - - var user = userRepo - .Get() - .Include(x => x.GiftCodeUses) - .ThenInclude(x => x.GiftCode) - .FirstOrDefault(x => x.Id == u.Id); - - if(user == null) - throw new DisplayException("Unsafe value detected. Please reload the page to proceed"); - - var giftCode = giftCodeRepo - .Get() - .FirstOrDefault(x => x.Code == code); - - if (giftCode == null) - throw new DisplayException("The gift code does not exist"); - - if (giftCode.Amount < 1) - throw new DisplayException("The gift code can no longer be used as it has exceeded the max use amount"); - - if (user.GiftCodeUses.Any(x => x.GiftCode.Id == giftCode.Id)) - throw new DisplayException("The gift code has already been used on this account"); - - giftCode.Amount--; - giftCodeRepo.Update(giftCode); - - var giftCardUse = new GiftCodeUse() - { - GiftCode = giftCode - }; - - user.GiftCodeUses.Add(giftCardUse); - userRepo.Update(user); - - var transactionService = scope.ServiceProvider.GetRequiredService(); - await transactionService.Add(u, giftCode.Value, $"Redeemed gift code '{giftCode.Code}'"); - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Services/StoreOrderService.cs b/Moonlight/Features/StoreSystem/Services/StoreOrderService.cs deleted file mode 100644 index 385c94e..0000000 --- a/Moonlight/Features/StoreSystem/Services/StoreOrderService.cs +++ /dev/null @@ -1,209 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Exceptions; -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Event; - -using Moonlight.Core.Extensions; - -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.ServiceManagement.Services; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.StoreSystem.Services; - -[Singleton] -public class StoreOrderService -{ - private readonly IServiceScopeFactory ServiceScopeFactory; - - public StoreOrderService(IServiceScopeFactory serviceScopeFactory) - { - ServiceScopeFactory = serviceScopeFactory; - } - - public Task Validate(User u, Product p, int durationMultiplier, Coupon? c) - { - using var scope = ServiceScopeFactory.CreateScope(); - var productRepo = scope.ServiceProvider.GetRequiredService>(); - var userRepo = scope.ServiceProvider.GetRequiredService>(); - var serviceRepo = scope.ServiceProvider.GetRequiredService>(); - var couponRepo = scope.ServiceProvider.GetRequiredService>(); - - // Ensure the values are safe and loaded by using the created scope to bypass the cache - - var user = userRepo - .Get() - .Include(x => x.CouponUses) - .ThenInclude(x => x.Coupon) - .FirstOrDefault(x => x.Id == u.Id); - - if (user == null) - throw new DisplayException("Unsafe value detected. Please reload the page to proceed"); - - - var product = productRepo - .Get() - .FirstOrDefault(x => x.Id == p.Id); - - if (product == null) - throw new DisplayException("Unsafe value detected. Please reload the page to proceed"); - - - Coupon? coupon = c; - - if (coupon != null) // Only check if the coupon actually has a value - { - coupon = couponRepo - .Get() - .FirstOrDefault(x => x.Id == coupon.Id); - - if (coupon == null) - throw new DisplayException("Unsafe value detected. Please reload the page to proceed"); - } - - // Perform checks on selected order - - if (coupon != null && user.CouponUses.Any(x => x.Coupon.Id == coupon.Id)) - throw new DisplayException("Coupon already used"); - - if (coupon != null && coupon.Amount < 1) - throw new DisplayException("No coupon uses left"); - - var price = product.Price * durationMultiplier; - - if (coupon != null) - price = Math.Round(price - (price * coupon.Percent / 100), 2); - - if (user.Balance < price) - throw new DisplayException("Order is too expensive"); - - var userServices = serviceRepo - .Get() - .Where(x => x.Product.Id == product.Id) - .Count(x => x.Owner.Id == user.Id); - - if (userServices >= product.MaxPerUser) - throw new DisplayException("The limit of this product on your account has been reached"); - - if (product.Stock < 1) - throw new DisplayException("The product is out of stock"); - - return Task.CompletedTask; - } - - public async Task Process(User u, Product p, int durationMultiplier, Coupon? c) - { - // Validate to ensure we dont process an illegal order - await Validate(u, p, durationMultiplier, c); - - // Create scope and get required services - using var scope = ServiceScopeFactory.CreateScope(); - var serviceService = scope.ServiceProvider.GetRequiredService(); - var transactionService = scope.ServiceProvider.GetRequiredService(); - - // Calculate price - var price = p.Price * durationMultiplier; - - if (c != null) - price = Math.Round(price - (price * c.Percent / 100), 2); - - // Calculate duration - var duration = durationMultiplier * p.Duration; - - // Add transaction - await transactionService.Add(u, -1 * price, $"Bought product '{p.Name}' for {duration} days"); - - // Process coupon if used - if (c != null) - { - // Remove one use from the coupon - var couponRepo = scope.ServiceProvider.GetRequiredService>(); - - var coupon = couponRepo - .Get() - .First(x => x.Id == c.Id); - - coupon.Amount--; - couponRepo.Update(coupon); - - // Add coupon use to user - var userRepo = scope.ServiceProvider.GetRequiredService>(); - - var user = userRepo - .Get() - .Include(x => x.CouponUses) - .First(x => x.Id == u.Id); - - user.CouponUses.Add(new () - { - Coupon = coupon - }); - - userRepo.Update(user); - } - - // Create service - var service = await serviceService.Admin.Create(u, p, - service => { service.RenewAt = DateTime.UtcNow.AddDays(duration); }); - - await Events.OnServiceOrdered.InvokeAsync(service); - - return service; - } - - public Task ValidateRenew(User u, Service s, int durationMultiplier) - { - using var scope = ServiceScopeFactory.CreateScope(); - var userRepo = scope.ServiceProvider.GetRequiredService>(); - var serviceRepo = scope.ServiceProvider.GetRequiredService>(); - - var user = userRepo.Get().FirstOrDefault(x => x.Id == u.Id); - - if(user == null) - throw new DisplayException("Unsafe value detected. Please reload the page to proceed"); - - var service = serviceRepo - .Get() - .Include(x => x.Product) - .Include(x => x.Owner) - .FirstOrDefault(x => x.Id == s.Id); - - if(service == null) - throw new DisplayException("Unsafe value detected. Please reload the page to proceed"); - - var price = service.Product.Price * durationMultiplier; - - if (user.Balance < price) - throw new DisplayException("Order is too expensive"); - - return Task.CompletedTask; - } - - public async Task Renew(User u, Service s, int durationMultiplier) - { - await ValidateRenew(u, s, durationMultiplier); - - using var scope = ServiceScopeFactory.CreateScope(); - var serviceRepo = scope.ServiceProvider.GetRequiredService>(); - var transactionService = scope.ServiceProvider.GetRequiredService(); - - var service = serviceRepo - .Get() - .Include(x => x.Product) - .Include(x => x.Owner) - .First(x => x.Id == s.Id); - - var price = service.Product.Price * durationMultiplier; - - // Calculate duration - var duration = durationMultiplier * service.Product.Duration; - - // Add transaction - await transactionService.Add(u, -1 * price, $"Renewed service '{service.Nickname ?? $"Service {service.Id}"}' for {duration} days"); - - service.RenewAt = service.RenewAt.AddDays(duration); - serviceRepo.Update(service); - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Services/StorePaymentService.cs b/Moonlight/Features/StoreSystem/Services/StorePaymentService.cs deleted file mode 100644 index f60f856..0000000 --- a/Moonlight/Features/StoreSystem/Services/StorePaymentService.cs +++ /dev/null @@ -1,17 +0,0 @@ -using MoonCore.Attributes; -using Moonlight.Core.Models.Abstractions; -using Moonlight.Features.StoreSystem.Models.Abstractions; - -namespace Moonlight.Features.StoreSystem.Services; - -[Singleton] -public class StorePaymentService -{ - public readonly List Gateways = new(); - - public Task RegisterGateway(PaymentGateway gateway) - { - Gateways.Add(gateway); - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Services/StoreService.cs b/Moonlight/Features/StoreSystem/Services/StoreService.cs deleted file mode 100644 index 2a4dcce..0000000 --- a/Moonlight/Features/StoreSystem/Services/StoreService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using MoonCore.Attributes; - -namespace Moonlight.Features.StoreSystem.Services; - -[Scoped] -public class StoreService -{ - private readonly IServiceProvider ServiceProvider; - - public StoreAdminService Admin => ServiceProvider.GetRequiredService(); - public StoreOrderService Order => ServiceProvider.GetRequiredService(); - public StorePaymentService Payment => ServiceProvider.GetRequiredService(); - public StoreGiftService Gift => ServiceProvider.GetRequiredService(); - - public StoreService(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/Services/TransactionService.cs b/Moonlight/Features/StoreSystem/Services/TransactionService.cs deleted file mode 100644 index cf3b429..0000000 --- a/Moonlight/Features/StoreSystem/Services/TransactionService.cs +++ /dev/null @@ -1,46 +0,0 @@ -using MoonCore.Abstractions; -using MoonCore.Attributes; -using Moonlight.Core.Database.Entities; -using Moonlight.Core.Event; -using Moonlight.Core.Extensions; -using Moonlight.Features.StoreSystem.Entities; - -namespace Moonlight.Features.StoreSystem.Services; - -[Scoped] -public class TransactionService -{ - private readonly Repository UserRepository; - - public TransactionService(Repository userRepository) - { - UserRepository = userRepository; - } - - public async Task Add(User u, double amount, string message) - { - var user = UserRepository.Get().First(x => x.Id == u.Id); // Load user with current repo - - var transaction = new Transaction() - { - Text = message, - Price = amount - }; - - user.Transactions.Add(transaction); - UserRepository.Update(user); - - // We divide the call to ensure the transaction can be written to the database - - user.Balance += amount; - user.Balance = Math.Round(user.Balance, 2); // To prevent weird numbers - - UserRepository.Update(user); - - await Events.OnTransactionCreated.InvokeAsync(new() - { - Transaction = transaction, - User = user - }); - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/UI/Components/AdminStoreNavigation.razor b/Moonlight/Features/StoreSystem/UI/Components/AdminStoreNavigation.razor deleted file mode 100644 index 0adb6ee..0000000 --- a/Moonlight/Features/StoreSystem/UI/Components/AdminStoreNavigation.razor +++ /dev/null @@ -1,32 +0,0 @@ - - -@code -{ - [Parameter] - public int Index { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/UI/Components/StoreModals.razor b/Moonlight/Features/StoreSystem/UI/Components/StoreModals.razor deleted file mode 100644 index 421dab7..0000000 --- a/Moonlight/Features/StoreSystem/UI/Components/StoreModals.razor +++ /dev/null @@ -1,349 +0,0 @@ -@using Mappy.Net -@using MoonCore.Abstractions -@using MoonCoreUI.Services - - -@using Moonlight.Features.ServiceManagement.Entities.Enums -@using Moonlight.Features.StoreSystem.Entities -@using Moonlight.Features.StoreSystem.Models.Forms -@using Moonlight.Features.StoreSystem.Services - -@inject StoreService StoreService -@inject ToastService ToastService -@inject Repository CategoryRepository - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@code -{ - [Parameter] - public Func OnUpdate { get; set; } - - #region Add category - - private SmartModal AddCategoryModal; - private AddCategoryForm AddCategoryForm = new(); - - public Task AddCategoryShow => AddCategoryModal.Show(); - - private async Task AddCategorySubmit() - { - await StoreService.Admin.AddCategory( - AddCategoryForm.Name, - AddCategoryForm.Description, - AddCategoryForm.Slug - ); - - await ToastService.Success("Successfully added category"); - await AddCategoryModal.Hide(); - - AddCategoryForm = new(); - await OnUpdate.Invoke(); - } - - #endregion - - #region Edit category - - private SmartModal EditCategoryModal; - private EditCategoryForm EditCategoryForm = new(); - private Category EditCategory; - - public async Task EditCategoryShow(Category category) - { - EditCategory = category; - - EditCategoryForm = Mapper.Map(EditCategory); - await EditCategoryModal.Show(); - } - - private async Task EditCategorySubmit() - { - EditCategory = Mapper.Map(EditCategory, EditCategoryForm); - - await StoreService.Admin.UpdateCategory(EditCategory); - - await ToastService.Success("Successfully updated category"); - await EditCategoryModal.Hide(); - - await OnUpdate.Invoke(); - } - - #endregion - - #region Add product - - private SmartModal AddProductModal; - private AddProductForm AddProductForm = new(); - private Category[] Categories; - private object AddProductConfig = new(); - - private ServiceType AddProductServiceType - { - set - { - if (AddProductConfig.GetType() != StoreService.Admin.GetProductConfigType(value)) - AddProductConfig = StoreService.Admin.CreateNewProductConfig(value); - - AddProductForm.Type = value; - InvokeAsync(StateHasChanged); - } - get => AddProductForm.Type; - } - - public Task AddProductShow => AddProductModal.Show(); - - private async Task AddProductSubmit() - { - var product = await StoreService.Admin.AddProduct( - AddProductForm.Name, - AddProductForm.Description, - AddProductForm.Slug, - AddProductForm.Type, - product => - { - product.Category = AddProductForm.Category; - product.Duration = AddProductForm.Duration; - product.Price = AddProductForm.Price; - product.Stock = AddProductForm.Stock; - product.MaxPerUser = AddProductForm.MaxPerUser; - } - ); - - StoreService.Admin.SaveProductConfig(product, AddProductConfig); - - await ToastService.Success("Successfully added product"); - await AddProductModal.Hide(); - - AddProductForm = new(); - await OnUpdate.Invoke(); - } - - #endregion - - #region Edit product - - private SmartModal EditProductModal; - private EditProductForm EditProductForm = new(); - private Product EditProduct; - private object EditProductConfig = new(); - - private ServiceType EditProductServiceType - { - set - { - if (EditProductConfig.GetType() != StoreService.Admin.GetProductConfigType(value)) - EditProductConfig = StoreService.Admin.CreateNewProductConfig(value); - - EditProductForm.Type = value; - InvokeAsync(StateHasChanged); - } - get => EditProductForm.Type; - } - - public async Task EditProductShow(Product product) - { - EditProduct = product; - EditProductConfig = StoreService.Admin.GetProductConfig(product); - - EditProductForm = Mapper.Map(EditProduct); - await EditProductModal.Show(); - } - - private async Task EditProductSubmit() - { - EditProduct = Mapper.Map(EditProduct, EditProductForm); - - await StoreService.Admin.UpdateProduct(EditProduct); - StoreService.Admin.SaveProductConfig(EditProduct, EditProductConfig); - - await ToastService.Success("Successfully updated product"); - await EditProductModal.Hide(); - - await OnUpdate.Invoke(); - } - - #endregion - - private Task LoadCategories(LazyLoader _) - { - Categories = CategoryRepository.Get().ToArray(); - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/UI/Views/Admin/Coupons.razor b/Moonlight/Features/StoreSystem/UI/Views/Admin/Coupons.razor deleted file mode 100644 index e90b2b3..0000000 --- a/Moonlight/Features/StoreSystem/UI/Views/Admin/Coupons.razor +++ /dev/null @@ -1,54 +0,0 @@ -@page "/admin/store/coupons" - -@using BlazorTable -@using MoonCore.Abstractions -@using MoonCore.Exceptions - -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - -@using Moonlight.Features.StoreSystem.Entities -@using Moonlight.Features.StoreSystem.Models.Forms -@using Moonlight.Features.StoreSystem.UI.Components - -@attribute [RequirePermission(Permission.AdminStore)] - -@inject Repository CouponRepository - - - -
    - - - - - - - - - -
    - -@code -{ - private Coupon[] LoadData(Repository repository) - { - return repository - .Get() - .ToArray(); - } - - private Task Validate(Coupon coupon) - { - if (CouponRepository.Get().Any(x => x.Code == coupon.Code && x.Id != coupon.Id)) - throw new DisplayException("A coupon with that code does already exist"); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/UI/Views/Admin/Expired.razor b/Moonlight/Features/StoreSystem/UI/Views/Admin/Expired.razor deleted file mode 100644 index 4f4d5c8..0000000 --- a/Moonlight/Features/StoreSystem/UI/Views/Admin/Expired.razor +++ /dev/null @@ -1,79 +0,0 @@ -@page "/admin/store/expired" - -@using BlazorTable -@using Microsoft.EntityFrameworkCore -@using MoonCore.Abstractions -@using MoonCore.Helpers -@using Moonlight.Core.Extensions.Attributes - -@using Moonlight.Core.Models.Enums - -@using Moonlight.Features.ServiceManagement.Entities -@using Moonlight.Features.StoreSystem.UI.Components - -@attribute [RequirePermission(Permission.AdminStore)] - -@inject Repository ServiceRepository - - - -
    -
    -

    Expired services

    -
    -
    - - - - - - - - - - - - - - - - - - - - -
    -
    -
    -
    - -@code -{ - private Service[] Services; - - private Task Load(LazyLoader lazyLoader) - { - Services = ServiceRepository - .Get() - .Include(x => x.Owner) - .Include(x => x.Product) - .Where(x => x.RenewAt < DateTime.UtcNow) - .ToArray(); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/UI/Views/Admin/Gifts.razor b/Moonlight/Features/StoreSystem/UI/Views/Admin/Gifts.razor deleted file mode 100644 index 66add8b..0000000 --- a/Moonlight/Features/StoreSystem/UI/Views/Admin/Gifts.razor +++ /dev/null @@ -1,52 +0,0 @@ -@page "/admin/store/gifts" - -@using BlazorTable -@using MoonCore.Abstractions -@using MoonCore.Exceptions - -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - -@using Moonlight.Features.StoreSystem.Entities -@using Moonlight.Features.StoreSystem.Models.Forms -@using Moonlight.Features.StoreSystem.UI.Components - -@attribute [RequirePermission(Permission.AdminStore)] - -@inject Repository GiftCodeRepository - - - -
    - - - - - - - - -
    - -@code -{ - private GiftCode[] LoadData(Repository repository) - { - return repository - .Get() - .ToArray(); - } - - private Task Validate(GiftCode giftCode) - { - if (GiftCodeRepository.Get().Any(x => x.Code == giftCode.Code && x.Id != giftCode.Id)) - throw new DisplayException("A gift code with that code does already exist"); - - return Task.CompletedTask; - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/UI/Views/Admin/Index.razor b/Moonlight/Features/StoreSystem/UI/Views/Admin/Index.razor deleted file mode 100644 index be455d5..0000000 --- a/Moonlight/Features/StoreSystem/UI/Views/Admin/Index.razor +++ /dev/null @@ -1,9 +0,0 @@ -@page "/admin/store" - -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums -@using Moonlight.Features.StoreSystem.UI.Components - -@attribute [RequirePermission(Permission.AdminStore)] - - \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/UI/Views/Index.razor b/Moonlight/Features/StoreSystem/UI/Views/Index.razor deleted file mode 100644 index 99aa4a9..0000000 --- a/Moonlight/Features/StoreSystem/UI/Views/Index.razor +++ /dev/null @@ -1,270 +0,0 @@ -@page "/store" - - -@using Moonlight.Core.Models.Enums - -@using Moonlight.Core.Services - -@using Moonlight.Features.StoreSystem.Entities -@using Moonlight.Features.StoreSystem.Services -@using Moonlight.Features.StoreSystem.UI.Components -@using MoonCore.Helpers -@using MoonCore.Services -@using MoonCore.Abstractions -@using MoonCoreUI.Services -@using Moonlight.Core.Configuration - -@inject Repository CategoryRepository -@inject Repository ProductRepository -@inject ConfigService ConfigService -@inject IdentityService IdentityService -@inject AlertService AlertService -@inject ToastService ToastService -@inject StoreService StoreService - -@{ - var currency = ConfigService.Get().Store.Currency; -} - -@if (IdentityService.Permissions[Permission.AdminStore]) -{ -
    - @if (EditMode) - { -

    Edit mode enabled. Disable it by clicking here

    - } - else - { -

    To edit the store you can enable the edit mode here

    - } -
    -} - -
    -
    -
    -
    -
    Categories
    - @if (EditMode) - { -
    - -
    - } -
    -
    - - @foreach (var category in Categories) - { -
    -
  • - - @(category.Name) - @if (EditMode) - { - Edit - Delete - } -
  • -
    - } -
    -
    -
    -
    -
    - - @if (Products.Any()) - { -
    - @foreach (var product in Products) - { -
    -
    - @if (EditMode) - { -
    - Edit -
    - Delete -
    -
    - } -
    -

    @(product.Name)

    -

    - @(Formatter.FormatLineBreaks(product.Description)) -

    - -
    - @if (product.Price == 0) - { - - Free - - } - else - { - @(currency) - - @(product.Price) - - - / - @(product.Duration) days - - } -
    - - @if (product.Stock == 0) - { - - } - else - { - Order now - } -
    -
    -
    - } - - @if (EditMode) - { -
    -
    -
    - -
    -
    -
    - } -
    - } - else - { - if (Categories.Any()) - { - if (EditMode) - { -
    -
    - -
    -
    - } - else - { -
    -
    -

    Welcome to our store

    - Select a category to start browsing -
    - -
    - Banner -
    -
    - } - } - else - { -
    -

    No products found

    -
    - } - } -
    -
    -
    - - - -@code -{ - // Category - private Category[] Categories; - private LazyLoader? CategoriesLazyLoader; - - [Parameter] - [SupplyParameterFromQuery] - public string Category { get; set; } - - private Category? SelectedCategory; - - // Products - private Product[] Products; - private LazyLoader? ProductsLazyLoader; - - // Edit stuff - private bool EditMode = false; - private StoreModals StoreModals; - - protected override async Task OnParametersSetAsync() - { - if (CategoriesLazyLoader != null) - await CategoriesLazyLoader.Reload(); - - if (ProductsLazyLoader != null) - await ProductsLazyLoader.Reload(); - } - - private async Task ToggleEdit() - { - EditMode = !EditMode; - await InvokeAsync(StateHasChanged); - } - - private Task LoadCategories(LazyLoader _) - { - Categories = CategoryRepository.Get().ToArray(); - - SelectedCategory = Categories.FirstOrDefault(x => x.Slug == Category); - - return Task.CompletedTask; - } - - private Task LoadProducts(LazyLoader _) - { - if (SelectedCategory == null) - { - Products = ProductRepository - .Get() - .Where(x => x.Category == null) - .ToArray(); - } - else - { - Products = ProductRepository - .Get() - .Where(x => x.Category!.Id == SelectedCategory.Id) - .ToArray(); - } - - return Task.CompletedTask; - } - - private async Task DeleteCategory(Category category) - { - if (!await AlertService.YesNo($"Do you really want to delete '{category.Name}'", "Continue", "Cancel")) - return; - - await StoreService.Admin.DeleteCategory(category); - - await ToastService.Success("Successfully deleted category"); - await OnParametersSetAsync(); - } - - private async Task DeleteProduct(Product product) - { - if (!await AlertService.YesNo($"Do you really want to delete '{product.Name}'", "Continue", "Cancel")) - return; - - await StoreService.Admin.DeleteProduct(product); - - await ToastService.Success("Successfully deleted product"); - await OnParametersSetAsync(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/StoreSystem/UI/Views/Order.razor b/Moonlight/Features/StoreSystem/UI/Views/Order.razor deleted file mode 100644 index c7a2ca1..0000000 --- a/Moonlight/Features/StoreSystem/UI/Views/Order.razor +++ /dev/null @@ -1,256 +0,0 @@ -@page "/store/order/{slug}" - - - - -@using Moonlight.Core.Services - -@using Moonlight.Features.StoreSystem.Entities -@using Moonlight.Features.StoreSystem.Services -@using MoonCore.Helpers -@using MoonCore.Services -@using MoonCore.Exceptions -@using MoonCoreUI.Services -@using MoonCore.Abstractions -@using Moonlight.Core.Configuration - -@inject ConfigService ConfigService -@inject StoreService StoreService -@inject IdentityService IdentityService -@inject AlertService AlertService -@inject NavigationManager Navigation -@inject Repository ProductRepository -@inject Repository CouponRepository - - - @if (SelectedProduct == null) - { - - } - else - { -
    -
    -
    -
    -

    @(SelectedProduct.Name)

    -

    - @Formatter.FormatLineBreaks(SelectedProduct.Description) -

    -
    -
    - -
    -
    -

    Apply coupon codes

    -
    - - -
    -
    -
    -
    -
    -
    -
    -
    -

    Summary

    -
    - - @{ - var defaultPrice = SelectedProduct.Price * DurationMultiplier; - double actualPrice; - - if (SelectedCoupon == null) - actualPrice = defaultPrice; - else - actualPrice = Math.Round(defaultPrice - (defaultPrice * SelectedCoupon.Percent / 100), 2); - - var currency = ConfigService.Get().Store.Currency; - } - -
    -
    -
    Today
    -
    - @(currency) @(actualPrice) -
    -
    -
    -
    Renew
    -
    - @(currency) @(SelectedProduct.Price) -
    -
    -
    -
    Duration
    -
    - @(SelectedProduct.Duration * DurationMultiplier) days -
    -
    -
    -
    -
    Discount
    -
    - @(SelectedCoupon?.Percent ?? 0)% -
    -
    -
    -
    Coupon
    -
    - @(SelectedCoupon?.Code ?? "None") -
    -
    -
    -
    -
    Total
    -
    - @(currency) @(actualPrice) -
    -
    -
    - @if (!CanBeOrdered && !string.IsNullOrEmpty(ErrorMessage)) - { -
    - @ErrorMessage -
    - } -
    -
    - -
    -
    -
    -
    - } -
    - -@code -{ - [Parameter] - public string Slug { get; set; } - - private Product? SelectedProduct; - private Coupon? SelectedCoupon; - private int DurationMultiplier = 1; - - private string CouponCode = ""; - - private bool CanBeOrdered = false; - private bool IsValidating = false; - private string ErrorMessage = ""; - - private async Task SetDurationMultiplier(int i) - { - DurationMultiplier = i; - - await Revalidate(); - } - - private async Task ApplyCoupon() - { - SelectedCoupon = CouponRepository - .Get() - .FirstOrDefault(x => x.Code == CouponCode); - - CouponCode = ""; - await InvokeAsync(StateHasChanged); - - if (SelectedCoupon == null) - { - await AlertService.Error("", "Invalid coupon code entered"); - return; - } - - await Revalidate(); - } - - private Task Revalidate() - { - if (SelectedProduct == null) // Prevent validating null - return Task.CompletedTask; - - IsValidating = true; - InvokeAsync(StateHasChanged); - - Task.Run(async () => - { - try - { - await StoreService.Order.Validate(IdentityService.CurrentUser, SelectedProduct, DurationMultiplier, SelectedCoupon); - CanBeOrdered = true; - } - catch (DisplayException e) - { - CanBeOrdered = false; - ErrorMessage = e.Message; - } - - IsValidating = false; - await InvokeAsync(StateHasChanged); - }); - - return Task.CompletedTask; - } - - private async Task Load(LazyLoader _) - { - SelectedProduct = ProductRepository - .Get() - .FirstOrDefault(x => x.Slug == Slug); - - await Revalidate(); - } - - private async Task OnSubmit() - { - if (SelectedProduct == null) // Prevent processing null - return; - - // Process the order with the selected values - var service = await StoreService - .Order - .Process( - IdentityService.CurrentUser, - SelectedProduct, - DurationMultiplier, - SelectedCoupon - ); - - Navigation.NavigateTo("/service/" + service.Id); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/Configuration/ThemeData.cs b/Moonlight/Features/Theming/Configuration/ThemeData.cs deleted file mode 100644 index cdc872b..0000000 --- a/Moonlight/Features/Theming/Configuration/ThemeData.cs +++ /dev/null @@ -1,8 +0,0 @@ -using Newtonsoft.Json; - -namespace Moonlight.Features.Theming.Configuration; - -public class ThemeData -{ - [JsonProperty("EnableDefault")] public bool EnableDefault { get; set; } = true; -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/Entities/Theme.cs b/Moonlight/Features/Theming/Entities/Theme.cs deleted file mode 100644 index 099538b..0000000 --- a/Moonlight/Features/Theming/Entities/Theme.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Moonlight.Features.Theming.Entities; - -public class Theme -{ - public int Id { get; set; } - public string Name { get; set; } = ""; - public string Author { get; set; } = ""; - public string? DonateUrl { get; set; } = ""; - public string CssUrl { get; set; } = ""; - public string? JsUrl { get; set; } = ""; - - public bool Enabled { get; set; } = false; -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/Models/Abstractions/ApplicationTheme.cs b/Moonlight/Features/Theming/Models/Abstractions/ApplicationTheme.cs deleted file mode 100644 index 5089069..0000000 --- a/Moonlight/Features/Theming/Models/Abstractions/ApplicationTheme.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace Moonlight.Features.Theming.Models.Abstractions; - -public class ApplicationTheme -{ - public int Id { get; set; } - public string Name { get; set; } = ""; - public string Author { get; set; } = ""; - public string? DonateUrl { get; set; } = ""; - public string CssUrl { get; set; } = ""; - public string? JsUrl { get; set; } = ""; - - public bool Enabled { get; set; } = false; -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/Models/Forms/AddThemeForm.cs b/Moonlight/Features/Theming/Models/Forms/AddThemeForm.cs deleted file mode 100644 index d330146..0000000 --- a/Moonlight/Features/Theming/Models/Forms/AddThemeForm.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Theming.Models.Forms; - -public class AddThemeForm -{ - [Required(ErrorMessage = "You need to specify a name for your theme")] - public string Name { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify an author for your theme")] - public string Author { get; set; } = ""; - - [Description("Enter a url to date for your theme here in order to show up when other people use this theme")] - public string? DonateUrl { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a style sheet url")] - [Description("A url to your stylesheet")] - public string CssUrl { get; set; } = ""; - - [Description("(Optional) A url to your javascript file")] - public string? JsUrl { get; set; } = null; -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/Models/Forms/EditThemeForm.cs b/Moonlight/Features/Theming/Models/Forms/EditThemeForm.cs deleted file mode 100644 index 4f6435a..0000000 --- a/Moonlight/Features/Theming/Models/Forms/EditThemeForm.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; - -namespace Moonlight.Features.Theming.Models.Forms; - -public class EditThemeForm -{ - [Required(ErrorMessage = "You need to specify a name for your theme")] - public string Name { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify an author for your theme")] - public string Author { get; set; } = ""; - - [Description("Enter a url to date for your theme here in order to show up when other people use this theme")] - public string? DonateUrl { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify a style sheet url")] - [Description("A url to your stylesheet")] - public string CssUrl { get; set; } = ""; - - [Description("(Optional) A url to your javascript file")] - public string? JsUrl { get; set; } = null; - - [Description("Enable the theme for this instance")] - public bool Enabled { get; set; } = false; -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/Models/ThemeExport.cs b/Moonlight/Features/Theming/Models/ThemeExport.cs deleted file mode 100644 index 75cda78..0000000 --- a/Moonlight/Features/Theming/Models/ThemeExport.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Moonlight.Features.Theming.Models; - -public class ThemeExport -{ - public string Name { get; set; } = ""; - public string Author { get; set; } = ""; - public string? DonateUrl { get; set; } = ""; - public string CssUrl { get; set; } = ""; - public string? JsUrl { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/Models/ThemeImport.cs b/Moonlight/Features/Theming/Models/ThemeImport.cs deleted file mode 100644 index 956e5a8..0000000 --- a/Moonlight/Features/Theming/Models/ThemeImport.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Moonlight.Features.Theming.Models; - -public class ThemeImport -{ - public string Name { get; set; } = ""; - public string Author { get; set; } = ""; - public string? DonateUrl { get; set; } = ""; - public string CssUrl { get; set; } = ""; - public string? JsUrl { get; set; } = ""; -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/Services/ThemeService.cs b/Moonlight/Features/Theming/Services/ThemeService.cs deleted file mode 100644 index b4de676..0000000 --- a/Moonlight/Features/Theming/Services/ThemeService.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Mappy.Net; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using MoonCore.Services; -using Moonlight.Core.Configuration; -using Moonlight.Core.Models.Abstractions; - -using Moonlight.Core.Services; -using Moonlight.Features.Theming.Entities; -using Moonlight.Features.Theming.Models.Abstractions; - -namespace Moonlight.Features.Theming.Services; - -[Singleton] -public class ThemeService -{ - private readonly IServiceProvider ServiceProvider; - private readonly ConfigService ConfigService; - - public ThemeService(IServiceProvider serviceProvider, ConfigService configService) - { - ServiceProvider = serviceProvider; - ConfigService = configService; - } - - public Task GetInstalled() - { - using var scope = ServiceProvider.CreateScope(); - var themeRepo = scope.ServiceProvider.GetRequiredService>(); - - var themes = new List(); - - themes.AddRange(themeRepo - .Get() - .ToArray() - .Select(x => Mapper.Map(x))); - - if (ConfigService.Get().Theme.EnableDefault) - { - themes.Insert(0, new() - { - Id = 0, - Name = "Moonlight Default", - Author = "MasuOwO", - Enabled = true, - CssUrl = "/css/theme.css", - DonateUrl = "https://ko-fi.com/masuowo" - }); - } - - return Task.FromResult(themes.ToArray()); - } - - public async Task GetEnabled() => - (await GetInstalled()) - .Where(x => x.Enabled) - .ToArray(); -} \ No newline at end of file diff --git a/Moonlight/Features/Theming/UI/Views/Admin/Themes.razor b/Moonlight/Features/Theming/UI/Views/Admin/Themes.razor deleted file mode 100644 index df77c40..0000000 --- a/Moonlight/Features/Theming/UI/Views/Admin/Themes.razor +++ /dev/null @@ -1,126 +0,0 @@ -@page "/admin/sys/themes" - -@using BlazorTable -@using Mappy.Net -@using Microsoft.AspNetCore.Components.Forms -@using MoonCore.Abstractions -@using MoonCore.Exceptions -@using MoonCoreUI.Services - -@using Moonlight.Core.Extensions.Attributes -@using Moonlight.Core.Models.Enums - - -@using Moonlight.Features.Theming.Entities -@using Moonlight.Features.Theming.Models -@using Moonlight.Features.Theming.Models.Forms -@using Newtonsoft.Json - -@attribute [RequirePermission(Permission.AdminRoot)] - -@inject ToastService ToastService -@inject Repository ThemeRepository -@inject FileDownloadService DownloadService - - - -
    - - - -
    - - Import theme -
    -
    -
    - - - - - - - - - - - - -
    -
    - -@code -{ - private SmartCustomFileSelect ThemeFileSelect; - private AutoCrud AutoCrud; - - private Theme[] LoadData(Repository repository) - { - return repository.Get().ToArray(); - } - - private async Task ExportTheme(Theme theme) - { - var model = Mapper.Map(theme); - - var json = JsonConvert.SerializeObject(model, Formatting.Indented); - - await ToastService.Info("Starting image download"); - await DownloadService.DownloadString($"{model.Name}.json", json); - } - - private async Task ImportTheme(IBrowserFile file) - { - try - { - if (file.ContentType != "application/json") - throw new DisplayException("Unknown file type. Only .json is supported"); - - var stream = file.OpenReadStream(); - var streamReader = new StreamReader(stream); - var text = await streamReader.ReadToEndAsync(); - var theme = JsonConvert.DeserializeObject(text); - - if (theme == null) - throw new DisplayException("Unable to parse theme json"); - - var themeDb = Mapper.Map(theme); - ThemeRepository.Add(themeDb); - - await ToastService.Success($"Successfully imported theme '{theme.Name}'"); - - await AutoCrud.Reload(); - } - catch (DisplayException e) - { - await ToastService.Danger(e.Message); - } - finally - { - await ThemeFileSelect.RemoveSelection(); - } - } -} \ No newline at end of file diff --git a/Moonlight/Features/Ticketing/Entities/Enums/TicketPriority.cs b/Moonlight/Features/Ticketing/Entities/Enums/TicketPriority.cs deleted file mode 100644 index 9cd0d15..0000000 --- a/Moonlight/Features/Ticketing/Entities/Enums/TicketPriority.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Moonlight.Features.Ticketing.Entities.Enums; - -public enum TicketPriority -{ - Low, - Medium, - High, - Critical -} \ No newline at end of file diff --git a/Moonlight/Features/Ticketing/Entities/Ticket.cs b/Moonlight/Features/Ticketing/Entities/Ticket.cs deleted file mode 100644 index 564f995..0000000 --- a/Moonlight/Features/Ticketing/Entities/Ticket.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Moonlight.Core.Database.Entities; -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.Ticketing.Entities.Enums; - -namespace Moonlight.Features.Ticketing.Entities; - -public class Ticket -{ - public int Id { get; set; } - public User Creator { get; set; } - public string Name { get; set; } = ""; - public string Description { get; set; } = ""; - public string Tries { get; set; } = ""; - public TicketPriority Priority { get; set; } = TicketPriority.Low; - public bool Open { get; set; } = true; - public Service? Service { get; set; } - - public List Messages { get; set; } = new(); - - public DateTime CreatedAt { get; set; } = DateTime.UtcNow; -} \ No newline at end of file diff --git a/Moonlight/Features/Ticketing/Entities/TicketMessage.cs b/Moonlight/Features/Ticketing/Entities/TicketMessage.cs deleted file mode 100644 index ec7d2c0..0000000 --- a/Moonlight/Features/Ticketing/Entities/TicketMessage.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Moonlight.Core.Database.Entities; - -namespace Moonlight.Features.Ticketing.Entities; - -public class TicketMessage -{ - public int Id { get; set; } - public User? Sender { get; set; } - public bool IsSupport { get; set; } - public string Content { get; set; } = ""; - public string? Attachment { get; set; } - public DateTime CreatedAt { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Ticketing/Models/Forms/CreateTicketForm.cs b/Moonlight/Features/Ticketing/Models/Forms/CreateTicketForm.cs deleted file mode 100644 index 6a1091e..0000000 --- a/Moonlight/Features/Ticketing/Models/Forms/CreateTicketForm.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.ComponentModel.DataAnnotations; -using Moonlight.Features.ServiceManagement.Entities; - -namespace Moonlight.Features.Ticketing.Models.Forms; - -public class CreateTicketForm -{ - [Required(ErrorMessage = "You need to enter a ticket name")] - [MinLength(8, ErrorMessage = "The title needs to be longer then 8 characters")] - [MaxLength(64, ErrorMessage = "The ticket name should not exceed 64 characters in lenght")] - public string Name { get; set; } = ""; - - [Required(ErrorMessage = "You need to enter a description")] - [MinLength(8, ErrorMessage = "The description needs to be longer then 8 characters")] - [MaxLength(256, ErrorMessage = "The description should not exceed 256 characters in lenght")] - public string Description { get; set; } = ""; - - [Required(ErrorMessage = "You need to specify what you have tried already")] - [MinLength(8, ErrorMessage = "The tries description needs to be longer then 8 characters")] - [MaxLength(256, ErrorMessage = "The tries description should not exceed 256 characters in lenght")] - public string Tries { get; set; } = ""; - - public Service? Service { get; set; } -} \ No newline at end of file diff --git a/Moonlight/Features/Ticketing/Services/TicketChatService.cs b/Moonlight/Features/Ticketing/Services/TicketChatService.cs deleted file mode 100644 index 0ba8234..0000000 --- a/Moonlight/Features/Ticketing/Services/TicketChatService.cs +++ /dev/null @@ -1,182 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using MoonCore.Abstractions; -using MoonCore.Attributes; -using Moonlight.Core.Event; -using Moonlight.Core.Event.Args; -using Moonlight.Core.Extensions; -using Moonlight.Core.Services; -using Moonlight.Features.Ticketing.Entities; -using Moonlight.Features.Ticketing.Entities.Enums; - -namespace Moonlight.Features.Ticketing.Services; - -[Scoped] -public class TicketChatService -{ - private readonly IdentityService IdentityService; - private readonly Repository TicketRepository; - private readonly BucketService BucketService; - private readonly List MessageCache = new(); - - public Ticket Ticket; - public bool IsSupporter; - public Func? OnUpdate; - public TicketMessage[] Messages => MessageCache.ToArray(); - - public TicketChatService( - IdentityService identityService, - Repository ticketRepository, - BucketService bucketService) - { - IdentityService = identityService; - TicketRepository = ticketRepository; - BucketService = bucketService; - } - - public Task Start(Ticket ticket, bool isSupporter = false) - { - IsSupporter = isSupporter; - - // Load data into local cache - Ticket = TicketRepository - .Get() - .Include(x => x.Messages) - .Include(x => x.Creator) - .Include(x => x.Service) - .First(x => x.Id == ticket.Id); - - MessageCache.AddRange(Ticket.Messages); - - // Register event handlers - Events.OnTicketMessage += OnTicketMessage; - Events.OnTicketUpdated += OnTicketUpdated; - - return Task.CompletedTask; - } - - public async Task Update(bool open, TicketPriority priority) // Updated and syncs ticket states to all listeners - { - if (Ticket.Open != open) - { - Ticket.Open = open; - - if(open) - await SendSystemMessage("Ticket has been opened"); - else - await SendSystemMessage("Ticket has been closed"); - } - - if (Ticket.Priority != priority) - { - Ticket.Priority = priority; - - await SendSystemMessage($"Ticket priority to {priority}"); - } - - TicketRepository.Update(Ticket); - - await Events.OnTicketUpdated.InvokeAsync(Ticket); - } - - public Task Stop() // Clear cache and stop listeners - { - Events.OnTicketMessage -= OnTicketMessage; - Events.OnTicketUpdated -= OnTicketUpdated; - - MessageCache.Clear(); - - return Task.CompletedTask; - } - - #region Sending - - public async Task SendSystemMessage(string content) // use this to send a message shown in a seperator - { - // Build the message model - var message = new TicketMessage() - { - Content = content, - Attachment = null, - CreatedAt = DateTime.UtcNow, - Sender = null, - IsSupport = IsSupporter - }; - - await SyncMessage(message); - } - - public async Task SendMessage(string content, Stream? attachmentStream = null, string? attachmentName = null) // Regular send method - { - if(string.IsNullOrEmpty(content)) - return; - - string? attachmentBucketName = null; - - // Check and download attachments - if (attachmentStream != null && attachmentName != null) - { - attachmentBucketName = await BucketService.Store( - "ticketAttachments", - attachmentStream, - attachmentName - ); - } - - // Build the message model - var message = new TicketMessage() - { - Content = content, - Attachment = attachmentBucketName, - CreatedAt = DateTime.UtcNow, - Sender = IdentityService.CurrentUser, - IsSupport = IsSupporter - }; - - await SyncMessage(message); - } - - private async Task SyncMessage(TicketMessage message) // Use this function to save and sync function to others - { - // Save ticket to the db - var t = TicketRepository - .Get() - .First(x => x.Id == Ticket.Id); // We do this to get a clean reference - - t.Messages.Add(message); - TicketRepository.Update(t); - - // Now emit the events - await Events.OnTicketMessage.InvokeAsync(new() - { - Ticket = t, // We use this reference as it has less data attached to it - TicketMessage = message - }); - } - - #endregion - - // Event handlers - private async void OnTicketUpdated(object? _, Ticket ticket) - { - if(Ticket.Id != ticket.Id) // Only listen to our ticket - return; - - // Update the possible values - Ticket.Open = ticket.Open; - Ticket.Priority = ticket.Priority; - - if (OnUpdate != null) - await OnUpdate.Invoke(); - } - - private async void OnTicketMessage(object? _, TicketMessageEventArgs eventArgs) - { - if(Ticket.Id != eventArgs.Ticket.Id) // Only listen to our ticket - return; - - MessageCache.Add(eventArgs.TicketMessage); - - if (OnUpdate != null) - await OnUpdate.Invoke(); - } -} \ No newline at end of file diff --git a/Moonlight/Features/Ticketing/Services/TicketCreateService.cs b/Moonlight/Features/Ticketing/Services/TicketCreateService.cs deleted file mode 100644 index e3681aa..0000000 --- a/Moonlight/Features/Ticketing/Services/TicketCreateService.cs +++ /dev/null @@ -1,44 +0,0 @@ -using MoonCore.Abstractions; -using MoonCore.Attributes; -using Moonlight.Core.Event; -using Moonlight.Core.Extensions; -using Moonlight.Core.Services; -using Moonlight.Features.ServiceManagement.Entities; -using Moonlight.Features.Ticketing.Entities; -using Moonlight.Features.Ticketing.Entities.Enums; - -namespace Moonlight.Features.Ticketing.Services; - -[Scoped] -public class TicketCreateService -{ - private readonly Repository TicketRepository; - private readonly IdentityService IdentityService; - - public TicketCreateService(Repository ticketRepository, IdentityService identityService) - { - TicketRepository = ticketRepository; - IdentityService = identityService; - } - - public async Task Perform(string name, string description, string tries, Service? service) - { - var ticket = new Ticket() - { - Creator = IdentityService.CurrentUser, - Service = service, - Description = description, - Tries = tries, - Open = true, - CreatedAt = DateTime.UtcNow, - Name = name, - Priority = TicketPriority.Low - }; - - var finalTicket = TicketRepository.Add(ticket); - - await Events.OnTicketCreated.InvokeAsync(finalTicket); - - return finalTicket; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Ticketing/Services/TicketService.cs b/Moonlight/Features/Ticketing/Services/TicketService.cs deleted file mode 100644 index 0d170b2..0000000 --- a/Moonlight/Features/Ticketing/Services/TicketService.cs +++ /dev/null @@ -1,17 +0,0 @@ -using MoonCore.Attributes; - -namespace Moonlight.Features.Ticketing.Services; - -[Scoped] -public class TicketService -{ - private readonly IServiceProvider ServiceProvider; - - public TicketChatService Chat => ServiceProvider.GetRequiredService(); - public TicketCreateService Create => ServiceProvider.GetRequiredService(); - - public TicketService(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } -} \ No newline at end of file diff --git a/Moonlight/Features/Ticketing/UI/Components/ChatFileSelect.razor b/Moonlight/Features/Ticketing/UI/Components/ChatFileSelect.razor deleted file mode 100644 index af43481..0000000 --- a/Moonlight/Features/Ticketing/UI/Components/ChatFileSelect.razor +++ /dev/null @@ -1,58 +0,0 @@ -@using Microsoft.AspNetCore.Components.Forms -@using MoonCore.Helpers -@using MoonCoreUI.Services - -@inject ToastService ToastService - -@{ - var id = $"fileUpload{GetHashCode()}"; -} - -