Remove old v2 structure
This commit is contained in:
parent
823970f617
commit
15a3789174
818 changed files with 0 additions and 61493 deletions
|
@ -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
|
10
.gitattributes
vendored
10
.gitattributes
vendored
|
@ -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
|
44
.gitignore
vendored
44
.gitignore
vendored
|
@ -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/
|
|
@ -1,21 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EfCoreCommonOptions">
|
||||
<option name="migrationsToStartupProjects">
|
||||
<map>
|
||||
<entry key="691e5ec2-4b4f-4bd1-9cbc-7d3c6efc12da" value="691e5ec2-4b4f-4bd1-9cbc-7d3c6efc12da" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="solutionLevelOptions">
|
||||
<map>
|
||||
<entry key="migrationsProject" value="691e5ec2-4b4f-4bd1-9cbc-7d3c6efc12da" />
|
||||
<entry key="startupProject" value="691e5ec2-4b4f-4bd1-9cbc-7d3c6efc12da" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="startupToMigrationsProjects">
|
||||
<map>
|
||||
<entry key="691e5ec2-4b4f-4bd1-9cbc-7d3c6efc12da" value="691e5ec2-4b4f-4bd1-9cbc-7d3c6efc12da" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EfCoreDialogsState">
|
||||
<option name="keyValueStorage">
|
||||
<map>
|
||||
<entry key="Common:691e5ec2-4b4f-4bd1-9cbc-7d3c6efc12da:dbContext" value="Moonlight.App.Database.DataContext" />
|
||||
<entry key="Common:buildConfiguration" value="Debug" />
|
||||
<entry key="Common:noBuild" value="false" />
|
||||
<entry key="Common:outputFolder" value="App/Database/Migrations" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="RiderProjectSettingsUpdater">
|
||||
<option name="vcsConfiguration" value="2" />
|
||||
</component>
|
||||
</project>
|
|
@ -1,6 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
|
@ -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
|
|
@ -1,15 +0,0 @@
|
|||
@using Moonlight.Core.UI.Layouts
|
||||
|
||||
<Router AppAssembly="@typeof(BlazorApp).Assembly">
|
||||
<Found Context="routeData">
|
||||
<CascadingValue TValue="Type" Name="TargetPageType" Value="routeData.PageType">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
|
||||
</CascadingValue>
|
||||
</Found>
|
||||
<NotFound>
|
||||
<PageTitle>Not found</PageTitle>
|
||||
<LayoutView Layout="@typeof(MainLayout)">
|
||||
<p role="alert">Sorry, there's nothing at this address.</p>
|
||||
</LayoutView>
|
||||
</NotFound>
|
||||
</Router>
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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<DummyPage>("Demo", "/demo");
|
||||
}
|
||||
|
||||
public override Task BuildAdminView(ServiceViewContext context)
|
||||
{
|
||||
context.Layout = typeof(DummyAdmin);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<h3>DummyAdmin</h3>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<h3>DummyUser</h3>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
<h3>DummyPage</h3>
|
||||
|
||||
@code {
|
||||
|
||||
}
|
|
@ -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";
|
||||
}
|
||||
}
|
|
@ -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<ConfigV1> ConfigService;
|
||||
|
||||
public DbSet<User> Users { get; set; }
|
||||
|
||||
// Store
|
||||
public DbSet<Category> Categories { get; set; }
|
||||
public DbSet<Product> Products { get; set; }
|
||||
public DbSet<Service> Services { get; set; }
|
||||
public DbSet<ServiceShare> ServiceShares { get; set; }
|
||||
|
||||
public DbSet<GiftCode> GiftCodes { get; set; }
|
||||
public DbSet<GiftCodeUse> GiftCodeUses { get; set; }
|
||||
|
||||
public DbSet<Coupon> Coupons { get; set; }
|
||||
public DbSet<CouponUse> CouponUses { get; set; }
|
||||
|
||||
// Community
|
||||
public DbSet<Post> Posts { get; set; }
|
||||
public DbSet<PostComment> PostComments { get; set; }
|
||||
public DbSet<PostLike> PostLikes { get; set; }
|
||||
public DbSet<WordFilter> WordFilters { get; set; }
|
||||
|
||||
// Tickets
|
||||
public DbSet<Ticket> Tickets { get; set; }
|
||||
public DbSet<TicketMessage> TicketMessages { get; set; }
|
||||
|
||||
// Themes
|
||||
public DbSet<Theme> Themes { get; set; }
|
||||
|
||||
// Servers
|
||||
public DbSet<Server> Servers { get; set; }
|
||||
public DbSet<ServerAllocation> ServerAllocations { get; set; }
|
||||
public DbSet<ServerImage> ServerImages { get; set; }
|
||||
public DbSet<ServerNode> ServerNodes { get; set; }
|
||||
public DbSet<ServerVariable> ServerVariables { get; set; }
|
||||
public DbSet<ServerDockerImage> ServerDockerImages { get; set; }
|
||||
public DbSet<ServerImageVariable> ServerImageVariables { get; set; }
|
||||
public DbSet<ServerSchedule> ServerSchedules { get; set; }
|
||||
|
||||
public DataContext(ConfigService<ConfigV1> 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)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Transaction> Transactions { get; set; } = new();
|
||||
|
||||
public List<CouponUse> CouponUses { get; set; } = new();
|
||||
public List<GiftCodeUse> 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;
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Username")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedUser : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Users",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Username = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Email = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Password = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Avatar = table.Column<string>(type: "TEXT", nullable: true),
|
||||
TotpKey = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Flags = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Permissions = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
TokenValidTimestamp = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Users", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Users");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,342 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Percent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Coupons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CouponId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CouponId");
|
||||
|
||||
b.ToTable("CouponUses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCode", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Value")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GiftCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("GiftCodeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("GiftCodeId");
|
||||
|
||||
b.ToTable("GiftCodeUses");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Product", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("CategoryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Duration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MaxPerUser")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Stock")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJsonOverride")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ProductId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("RenewAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,245 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddStoreModels : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Categories",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Description = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Slug = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Categories", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Coupons",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Code = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Percent = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Amount = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Coupons", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "GiftCodes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Code = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Value = table.Column<double>(type: "REAL", nullable: false),
|
||||
Amount = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_GiftCodes", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Products",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
CategoryId = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Description = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Slug = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Price = table.Column<double>(type: "REAL", nullable: false),
|
||||
Stock = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
MaxPerUser = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Duration = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Type = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ConfigJson = table.Column<string>(type: "TEXT", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
CouponId = table.Column<int>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
GiftCodeId = table.Column<int>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Nickname = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Suspended = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
ProductId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ConfigJsonOverride = table.Column<string>(type: "TEXT", nullable: true),
|
||||
OwnerId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
RenewAt = table.Column<DateTime>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
UserId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ServiceId = table.Column<int>(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");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,372 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Percent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Coupons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CouponId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Value")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GiftCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("GiftCodeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Duration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MaxPerUser")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Stock")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJsonOverride")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ProductId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("RenewAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Balance")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,130 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedUserStoreData : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Products_Categories_CategoryId",
|
||||
table: "Products");
|
||||
|
||||
migrationBuilder.AddColumn<double>(
|
||||
name: "Balance",
|
||||
table: "Users",
|
||||
type: "REAL",
|
||||
nullable: false,
|
||||
defaultValue: 0.0);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "CategoryId",
|
||||
table: "Products",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: 0,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "INTEGER",
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
name: "UserId",
|
||||
table: "GiftCodeUses",
|
||||
type: "INTEGER",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<int>(
|
||||
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);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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<int>(
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,404 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Percent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Coupons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CouponId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Value")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GiftCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("GiftCodeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Duration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MaxPerUser")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Stock")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJsonOverride")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ProductId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("RenewAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Transaction");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Balance")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedTransactions : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Transaction",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Price = table.Column<double>(type: "REAL", nullable: false),
|
||||
Text = table.Column<string>(type: "TEXT", nullable: false),
|
||||
UserId = table.Column<int>(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");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Transaction");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,540 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AuthorId");
|
||||
|
||||
b.ToTable("Posts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Percent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Coupons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CouponId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Value")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GiftCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("GiftCodeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Duration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MaxPerUser")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Stock")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJsonOverride")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ProductId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("RenewAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Transaction");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Balance")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddPostsModels : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Posts",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Title = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Content = table.Column<string>(type: "TEXT", nullable: false),
|
||||
AuthorId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Type = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Content = table.Column<string>(type: "TEXT", nullable: false),
|
||||
AuthorId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
PostId = table.Column<int>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
UserId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
PostId = table.Column<int>(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");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "PostComments");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "PostLikes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Posts");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,555 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AuthorId");
|
||||
|
||||
b.ToTable("Posts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Filter")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WordFilters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Category", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Percent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Coupons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CouponId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Value")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GiftCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("GiftCodeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Duration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MaxPerUser")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Stock")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJsonOverride")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ProductId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("RenewAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Transaction");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Balance")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedWordFilter : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "WordFilters",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Filter = table.Column<string>(type: "TEXT", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_WordFilters", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "WordFilters");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,666 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AuthorId");
|
||||
|
||||
b.ToTable("Posts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Filter")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WordFilters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Category", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Percent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Coupons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CouponId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Value")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GiftCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("GiftCodeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Duration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MaxPerUser")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Stock")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJsonOverride")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ProductId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("RenewAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Transaction");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("CreatorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Open")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Priority")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Attachment")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSupport")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("SenderId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Balance")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedTicketModels : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Tickets",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
CreatorId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Description = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Tries = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Priority = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Open = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
ServiceId = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
SenderId = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
IsSupport = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Content = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Attachment = table.Column<string>(type: "TEXT", nullable: true),
|
||||
CreatedAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
TicketId = table.Column<int>(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");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "TicketMessages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Tickets");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,698 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AuthorId");
|
||||
|
||||
b.ToTable("Posts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Filter")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WordFilters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Category", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Percent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Coupons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CouponId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Value")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GiftCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("GiftCodeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Duration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MaxPerUser")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Stock")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJsonOverride")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ProductId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("RenewAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Transaction");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Theme", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Author")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CssUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DonateUrl")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("JsUrl")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Themes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("CreatorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Open")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Priority")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Attachment")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSupport")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("SenderId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Balance")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddThemeModel : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Themes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Author = table.Column<string>(type: "TEXT", nullable: false),
|
||||
DonateUrl = table.Column<string>(type: "TEXT", nullable: true),
|
||||
CssUrl = table.Column<string>(type: "TEXT", nullable: false),
|
||||
JsUrl = table.Column<string>(type: "TEXT", nullable: true),
|
||||
Enabled = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Themes", x => x.Id);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Themes");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,701 +0,0 @@
|
|||
// <auto-generated />
|
||||
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
|
||||
{
|
||||
/// <inheritdoc />
|
||||
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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Title")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AuthorId");
|
||||
|
||||
b.ToTable("Posts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Community.PostComment", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("AuthorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("PostId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Filter")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("WordFilters");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Category", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Categories");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Coupon", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Percent")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Coupons");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.CouponUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CouponId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Amount")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Code")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Value")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("GiftCodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.GiftCodeUse", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("GiftCodeId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("CategoryId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJson")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Duration")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("MaxPerUser")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Slug")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Stock")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Type")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("CategoryId");
|
||||
|
||||
b.ToTable("Products");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Store.Service", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("ConfigJsonOverride")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Nickname")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("ProductId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("RenewAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Price")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<string>("Text")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int?>("UserId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("Transaction");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Theme", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Author")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("CssUrl")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("DonateUrl")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("JsUrl")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Themes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.Core.Database.Entities.Tickets.Ticket", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("CreatorId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("Open")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int>("Priority")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("ServiceId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Attachment")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Content")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<bool>("IsSupport")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("SenderId")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<int?>("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<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<string>("Avatar")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<double>("Balance")
|
||||
.HasColumnType("REAL");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Flags")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<int>("Permissions")
|
||||
.HasColumnType("INTEGER");
|
||||
|
||||
b.Property<DateTime>("TokenValidTimestamp")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("TotpKey")
|
||||
.HasColumnType("TEXT");
|
||||
|
||||
b.Property<string>("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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedTransactionDate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "CreatedAt",
|
||||
table: "Transaction",
|
||||
type: "TEXT",
|
||||
nullable: false,
|
||||
defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "CreatedAt",
|
||||
table: "Transaction");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,266 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedServerModels : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerImages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
AllocationsNeeded = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
StartupCommand = table.Column<string>(type: "TEXT", nullable: false),
|
||||
StopCommand = table.Column<string>(type: "TEXT", nullable: false),
|
||||
OnlineDetection = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ParseConfigurations = table.Column<string>(type: "TEXT", nullable: false),
|
||||
InstallDockerImage = table.Column<string>(type: "TEXT", nullable: false),
|
||||
InstallShell = table.Column<string>(type: "TEXT", nullable: false),
|
||||
InstallScript = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Author = table.Column<string>(type: "TEXT", nullable: false),
|
||||
DonateUrl = table.Column<string>(type: "TEXT", nullable: true),
|
||||
UpdateUrl = table.Column<string>(type: "TEXT", nullable: true),
|
||||
DefaultDockerImageIndex = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ServerImages", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerImageVariables",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Key = table.Column<string>(type: "TEXT", nullable: false),
|
||||
DefaultValue = table.Column<string>(type: "TEXT", nullable: false),
|
||||
DisplayName = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Description = table.Column<string>(type: "TEXT", nullable: false),
|
||||
AllowUserToEdit = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
AllowUserToView = table.Column<bool>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ServerImageVariables", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerNodes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Fqdn = table.Column<string>(type: "TEXT", nullable: false),
|
||||
UseSsl = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
Token = table.Column<string>(type: "TEXT", nullable: false),
|
||||
HttpPort = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
FtpPort = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ServerNodes", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerDockerImages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
DisplayName = table.Column<string>(type: "TEXT", nullable: false),
|
||||
AutoPull = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
ServerImageId = table.Column<int>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
IpAddress = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Port = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ServerId = table.Column<int>(type: "INTEGER", nullable: true),
|
||||
ServerNodeId = table.Column<int>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
ServiceId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Cpu = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Memory = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
Disk = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ImageId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
DockerImageIndex = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
OverrideStartupCommand = table.Column<string>(type: "TEXT", nullable: true),
|
||||
NodeId = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
MainAllocationId = table.Column<int>(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<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Key = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Value = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ServerId = table.Column<int>(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");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,48 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class FixedMissingPropertyInServerImage : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<int>(
|
||||
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");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,29 +0,0 @@
|
|||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedAllowUserToChangeDockerImage : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "AllowUserToChangeDockerImage",
|
||||
table: "ServerImages",
|
||||
type: "INTEGER",
|
||||
nullable: false,
|
||||
defaultValue: false);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropColumn(
|
||||
name: "AllowUserToChangeDockerImage",
|
||||
table: "ServerImages");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,51 +0,0 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.Core.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddedServerSchedules : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerSchedules",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "INTEGER", nullable: false)
|
||||
.Annotation("Sqlite:Autoincrement", true),
|
||||
Name = table.Column<string>(type: "TEXT", nullable: false),
|
||||
Cron = table.Column<string>(type: "TEXT", nullable: false),
|
||||
ActionType = table.Column<int>(type: "INTEGER", nullable: false),
|
||||
ActionData = table.Column<string>(type: "TEXT", nullable: false),
|
||||
LastRunAt = table.Column<DateTime>(type: "TEXT", nullable: false),
|
||||
WasLastRunAutomatic = table.Column<bool>(type: "INTEGER", nullable: false),
|
||||
ServerId = table.Column<int>(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");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "ServerSchedules");
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -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; }
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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<User> OnUserRegistered;
|
||||
public static EventHandler<User> OnUserPasswordChanged;
|
||||
public static EventHandler<User> OnUserTotpSet;
|
||||
public static EventHandler<MailVerificationEventArgs> OnUserMailVerify;
|
||||
public static EventHandler<Service> OnServiceOrdered;
|
||||
public static EventHandler<TransactionCreatedEventArgs> OnTransactionCreated;
|
||||
public static EventHandler<Post> OnPostCreated;
|
||||
public static EventHandler<Post> OnPostUpdated;
|
||||
public static EventHandler<Post> OnPostDeleted;
|
||||
public static EventHandler<Post> OnPostLiked;
|
||||
public static EventHandler<PostComment> OnPostCommentCreated;
|
||||
public static EventHandler<PostComment> OnPostCommentDeleted;
|
||||
public static EventHandler<Ticket> OnTicketCreated;
|
||||
public static EventHandler<TicketMessageEventArgs> OnTicketMessage;
|
||||
public static EventHandler<Ticket> OnTicketUpdated;
|
||||
public static EventHandler OnMoonlightRestart;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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<ConfigV1> configService)
|
||||
{
|
||||
var jsonUnsafe = JsonConvert.SerializeObject(configService.Get());
|
||||
var configUnsafe = JsonConvert.DeserializeObject<ConfigV1>(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);
|
||||
}
|
||||
}
|
|
@ -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<T>(this EventHandler<T>? 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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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<ActionResult> 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<ActionResult> 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<User> UserRepository;
|
||||
private readonly IdentityService IdentityService;
|
||||
private readonly JwtService JwtService;
|
||||
|
||||
public ResetController(Repository<User> userRepository, IdentityService identityService, JwtService jwtService)
|
||||
{
|
||||
UserRepository = userRepository;
|
||||
IdentityService = identityService;
|
||||
JwtService = jwtService;
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> 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("/");
|
||||
}
|
||||
}
|
|
@ -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<ActionResult> 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("/");
|
||||
}
|
||||
}
|
|
@ -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<ActionResult> 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
using Moonlight.Core.Models.Enums;
|
||||
|
||||
namespace Moonlight.Core.Models.Abstractions;
|
||||
|
||||
public class FlagStorage
|
||||
{
|
||||
private readonly List<string> 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<Permission>();
|
||||
}
|
||||
|
||||
public static Permission GetFromInteger(int id)
|
||||
{
|
||||
return GetAllPermissions().First(x => (int)x == id);
|
||||
}
|
||||
|
||||
public bool this[Permission permission] => Permissions.Contains(permission);
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
namespace Moonlight.Core.Models.Enums;
|
||||
|
||||
public enum UserFlag
|
||||
{
|
||||
MailVerified,
|
||||
PasswordPending,
|
||||
TotpEnabled
|
||||
}
|
|
@ -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; } = "";
|
||||
}
|
|
@ -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; } = "";
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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; } = "";
|
||||
}
|
|
@ -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; } = "";
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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; } = "";
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
namespace Moonlight.Core.Models.Templates;
|
||||
|
||||
public class MailVerify
|
||||
{
|
||||
public string Url { get; set; } = "";
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
namespace Moonlight.Core.Models.Templates;
|
||||
|
||||
public class ResetPassword
|
||||
{
|
||||
public string Url { get; set; } = "";
|
||||
}
|
|
@ -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<Action> PreInitTasks = new();
|
||||
public List<Action> PostInitTasks = new();
|
||||
public Action<ServiceViewContext>? BuildUserServiceView { get; set; } = null;
|
||||
public Action<ServiceViewContext>? BuildAdminServiceView { get; set; } = 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();
|
||||
}
|
|
@ -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<TEntity> : Repository<TEntity> where TEntity : class
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
private readonly DbSet<TEntity> DbSet;
|
||||
|
||||
public GenericRepository(DataContext dbContext)
|
||||
{
|
||||
DataContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext));
|
||||
DbSet = DataContext.Set<TEntity>();
|
||||
}
|
||||
|
||||
public override DbSet<TEntity> 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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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<string> 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<Stream> 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>(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;
|
||||
}
|
||||
}
|
|
@ -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<string> 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 */}
|
||||
}
|
||||
}
|
|
@ -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<User> 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<User> userRepository,
|
||||
JwtService jwtService)
|
||||
{
|
||||
UserRepository = userRepository;
|
||||
JwtService = jwtService;
|
||||
}
|
||||
|
||||
// Transactions
|
||||
public Task<Transaction[]> GetTransactions()
|
||||
{
|
||||
if (CurrentUserNullable == null)
|
||||
return Task.FromResult(Array.Empty<Transaction>());
|
||||
|
||||
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<string> 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<string> 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();
|
||||
}
|
||||
}
|
|
@ -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<ConfigV1> ConfigService;
|
||||
private readonly string BasePath;
|
||||
|
||||
public MailService(ConfigService<ConfigV1> 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<string> 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<User> users, string title, string templateName, params object[] models)
|
||||
{
|
||||
foreach (var user in users)
|
||||
await Send(user, title, templateName, models);
|
||||
}
|
||||
}
|
|
@ -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<ConfigV1> 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<ThemeService>();
|
||||
|
||||
public MoonlightService(ConfigService<ConfigV1> 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<byte[]> 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<Repository<ServerNode>>();
|
||||
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<PluginService>();
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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<MoonlightPlugin> 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<MoonlightPlugin[]> 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<string>();
|
||||
|
||||
foreach (var file in Directory.GetFiles(dir))
|
||||
result.Add(file);
|
||||
|
||||
foreach (var directory in Directory.GetDirectories(dir))
|
||||
{
|
||||
result.AddRange(FindFiles(directory));
|
||||
}
|
||||
|
||||
return result.ToArray();
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
using MoonCore.Attributes;
|
||||
using Moonlight.Core.Models.Abstractions;
|
||||
|
||||
namespace Moonlight.Core.Services;
|
||||
|
||||
[Singleton]
|
||||
public class SessionService
|
||||
{
|
||||
private readonly List<Session> 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<User> UserRepository;
|
||||
private readonly JwtService JwtService;
|
||||
private readonly ConfigService<ConfigV1> ConfigService;
|
||||
private readonly MailService MailService;
|
||||
|
||||
public UserAuthService(
|
||||
Repository<User> userRepository,
|
||||
JwtService jwtService,
|
||||
ConfigService<ConfigV1> configService,
|
||||
MailService mailService)
|
||||
{
|
||||
UserRepository = userRepository;
|
||||
JwtService = jwtService;
|
||||
ConfigService = configService;
|
||||
MailService = mailService;
|
||||
}
|
||||
|
||||
public async Task<User> 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
|
||||
});
|
||||
}
|
||||
}
|
|
@ -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<Service> ServiceRepository;
|
||||
private readonly Repository<ServiceShare> ServiceShareRepository;
|
||||
private readonly Repository<Post> PostRepository;
|
||||
private readonly Repository<User> UserRepository;
|
||||
private readonly Repository<Transaction> TransactionRepository;
|
||||
private readonly Repository<CouponUse> CouponUseRepository;
|
||||
private readonly Repository<GiftCodeUse> GiftCodeUseRepository;
|
||||
private readonly Repository<Ticket> TicketRepository;
|
||||
private readonly Repository<TicketMessage> TicketMessageRepository;
|
||||
private readonly ServiceService ServiceService;
|
||||
private readonly PostService PostService;
|
||||
|
||||
public UserDeleteService(
|
||||
Repository<Service> serviceRepository,
|
||||
ServiceService serviceService,
|
||||
PostService postService,
|
||||
Repository<Post> postRepository,
|
||||
Repository<User> userRepository,
|
||||
Repository<GiftCodeUse> giftCodeUseRepository,
|
||||
Repository<CouponUse> couponUseRepository,
|
||||
Repository<Transaction> transactionRepository,
|
||||
Repository<Ticket> ticketRepository,
|
||||
Repository<TicketMessage> ticketMessageRepository,
|
||||
Repository<ServiceShare> 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);
|
||||
}
|
||||
}
|
|
@ -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<User> UserRepository;
|
||||
|
||||
public UserDetailsService(BucketService bucketService, Repository<User> 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);
|
||||
}
|
||||
}
|
|
@ -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<User> UserRepository;
|
||||
private readonly IServiceProvider ServiceProvider;
|
||||
|
||||
public UserAuthService Auth => ServiceProvider.GetRequiredService<UserAuthService>();
|
||||
public UserDetailsService Details => ServiceProvider.GetRequiredService<UserDetailsService>();
|
||||
public UserDeleteService Delete => ServiceProvider.GetRequiredService<UserDeleteService>();
|
||||
|
||||
public UserService(
|
||||
Repository<User> 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;
|
||||
}
|
||||
}
|
|
@ -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<ConfigV1> ConfigService;
|
||||
|
||||
public ConnectionService(IHttpContextAccessor contextAccessor, ConfigService<ConfigV1> configService)
|
||||
{
|
||||
ContextAccessor = contextAccessor;
|
||||
ConfigService = configService;
|
||||
}
|
||||
|
||||
public Task<string> 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)");
|
||||
}
|
||||
}
|
|
@ -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<ConfigV1> ConfigService;
|
||||
private readonly TimeSpan DefaultDuration = TimeSpan.FromDays(365 * 10);
|
||||
|
||||
public JwtService(ConfigService<ConfigV1> configService)
|
||||
{
|
||||
ConfigService = configService;
|
||||
}
|
||||
|
||||
public Task<string> Create(Action<Dictionary<string, string>> 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<string, string>();
|
||||
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<bool> 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<Dictionary<string, string>>(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<Dictionary<string, string>> Decode(string token)
|
||||
{
|
||||
try
|
||||
{
|
||||
var json = new JwtBuilder()
|
||||
.WithSecret(ConfigService.Get().Security.Token)
|
||||
.WithAlgorithm(new HMACSHA512Algorithm())
|
||||
.MustVerifySignature()
|
||||
.Decode(token);
|
||||
|
||||
var data = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
|
||||
|
||||
return Task.FromResult(data)!;
|
||||
}
|
||||
catch (SignatureVerificationException)
|
||||
{
|
||||
return Task.FromResult(new Dictionary<string, string>());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("An unknown error occured while processing token");
|
||||
Logger.Warn(e);
|
||||
return Task.FromResult<Dictionary<string, string>>(null!);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
<div class="d-flex flex-column flex-center text-center p-10">
|
||||
<div class="card card-flush w-lg-650px py-5">
|
||||
<div class="card-body py-15 py-lg-20">
|
||||
<div class="mb-5">
|
||||
<img src="/svg/nodata.svg" style="width: 10vh" alt="Not found illustration">
|
||||
</div>
|
||||
<h1 class="fw-bolder fs-2hx text-gray-900 mb-4">
|
||||
The requested resource was not found
|
||||
</h1>
|
||||
<div class="fw-semibold fs-6 text-gray-500 mb-7">
|
||||
<span class="fs-5">We were not able to find the requested resource. This can have following reasons</span>
|
||||
|
||||
<div class="mt-4 d-flex flex-column align-items-start">
|
||||
<li class="d-flex align-items-center py-2">
|
||||
<span class="bullet me-5"></span> The resource was deleted
|
||||
</li>
|
||||
<li class="d-flex align-items-center py-2">
|
||||
<span class="bullet me-5"></span> You have no permission to access this resource
|
||||
</li>
|
||||
<li class="d-flex align-items-center py-2">
|
||||
<span class="bullet me-5"></span> You may have entered invalid data
|
||||
</li>
|
||||
<li class="d-flex align-items-center py-2">
|
||||
<span class="bullet me-5"></span> A unknown bug occured
|
||||
</li>
|
||||
<li class="d-flex align-items-center py-2">
|
||||
<span class="bullet me-5"></span> An api was offline and not proper handled
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -1,16 +0,0 @@
|
|||
<div class="w-100">
|
||||
<div class="card-body">
|
||||
<div class="text-start mb-8">
|
||||
<h1 class="text-dark mb-3 fs-3x">
|
||||
Restarting
|
||||
</h1>
|
||||
<div class="text-gray-400 fw-semibold fs-6">
|
||||
The panel is restarting. This may take a moment
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-stack">
|
||||
<a href="javascript:location.reload()" class="btn btn-primary me-2 flex-shrink-0">Reconnect</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -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
|
||||
|
||||
<div class="w-100">
|
||||
<div class="card-body">
|
||||
<div class="text-start mb-8">
|
||||
<h1 class="text-dark mb-3 fs-3x">
|
||||
Change your password
|
||||
</h1>
|
||||
<div class="text-gray-400 fw-semibold fs-6">
|
||||
You need to change your password in order to continue
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SmartForm Model="Form" OnValidSubmit="OnValidSubmit">
|
||||
<div class="fv-row mb-7">
|
||||
<input @bind="Form.Password" type="password" placeholder="Password" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="fv-row mb-7">
|
||||
<input @bind="Form.RepeatedPassword" type="password" placeholder="Repeat password" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-stack">
|
||||
<button type="submit" class="btn btn-primary me-2 flex-shrink-0">Continue</button>
|
||||
</div>
|
||||
</SmartForm>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
<div class="w-100">
|
||||
<div class="card-body">
|
||||
<div class="text-start mb-8">
|
||||
<h1 class="text-dark mb-3 fs-3x">
|
||||
Sign In
|
||||
</h1>
|
||||
<div class="text-gray-400 fw-semibold fs-6">
|
||||
Change me
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SmartForm Model="Form" OnValidSubmit="OnValidSubmit">
|
||||
<div class="fv-row mb-8">
|
||||
<input @bind="Form.Email" type="text" placeholder="Email" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="fv-row mb-7">
|
||||
<input @bind="Form.Password" type="password" placeholder="Password" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-stack flex-wrap gap-3 fs-base fw-semibold mb-10">
|
||||
<a href="/password-reset" class="link-primary">
|
||||
Forgot Password ?
|
||||
</a>
|
||||
<a href="/register" class="link-primary">
|
||||
Need an account ?
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-stack">
|
||||
<button type="submit" class="btn btn-primary me-2 flex-shrink-0">Sign In</button>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="text-gray-400 fw-semibold fs-6 me-3 me-md-6">Or</div>
|
||||
@* OAuth2 Providers here *@
|
||||
</div>
|
||||
</div>
|
||||
</SmartForm>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@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("/");
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
@using Moonlight.Core.Services.Users
|
||||
@using Moonlight.Core.Services
|
||||
@inject UserService UserService
|
||||
@inject IdentityService IdentityService
|
||||
|
||||
<div class="w-100">
|
||||
<div class="card-body">
|
||||
@if (HasBeenSend)
|
||||
{
|
||||
<div class="text-start mb-8">
|
||||
<h1 class="text-dark mb-3 fs-3x">
|
||||
Email verification sent
|
||||
</h1>
|
||||
<div class="text-gray-400 fw-semibold fs-6">
|
||||
You should receive an email shortly. If you see no email in your inbox, look inside your spam folder
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-start mb-8">
|
||||
<h1 class="text-dark mb-3 fs-3x">
|
||||
Verify your email address
|
||||
</h1>
|
||||
<div class="text-gray-400 fw-semibold fs-6">
|
||||
We will sent you an email to verify your account
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<WButton OnClick="Send" Text="Send verification email" CssClasses="btn btn-primary me-2 flex-shrink-0" />
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private bool HasBeenSend = false;
|
||||
|
||||
private async Task Send()
|
||||
{
|
||||
await UserService.Auth.SendVerification(IdentityService.CurrentUser);
|
||||
HasBeenSend = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
<div class="w-100">
|
||||
<div class="card-body">
|
||||
@if (HasBeenSend)
|
||||
{
|
||||
<div class="text-start mb-8">
|
||||
<h1 class="text-dark mb-3 fs-3x">
|
||||
Password reset email sent
|
||||
</h1>
|
||||
<div class="text-gray-400 fw-semibold fs-6">
|
||||
You should receive the email shortly. If you see no email in your inbox, look inside your spam folder
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="text-start mb-8">
|
||||
<h1 class="text-dark mb-3 fs-3x">
|
||||
Reset your password
|
||||
</h1>
|
||||
<div class="text-gray-400 fw-semibold fs-6">
|
||||
We will sent you an email to reset your account password
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SmartForm Model="Form" OnValidSubmit="OnValidSubmit">
|
||||
<div class="fv-row mb-8">
|
||||
<input @bind="Form.Email" type="text" placeholder="Email" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-stack">
|
||||
<button type="submit" class="btn btn-primary me-2 flex-shrink-0">Continue</button>
|
||||
</div>
|
||||
</SmartForm>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private bool HasBeenSend = false;
|
||||
private ResetPasswordForm Form = new();
|
||||
|
||||
private async Task OnValidSubmit()
|
||||
{
|
||||
await UserService.Auth.SendResetPassword(Form.Email);
|
||||
HasBeenSend = true;
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
<div class="w-100">
|
||||
<div class="card-body">
|
||||
<div class="text-start mb-8">
|
||||
<h1 class="text-dark mb-3 fs-3x">
|
||||
Sign Up
|
||||
</h1>
|
||||
<div class="text-gray-400 fw-semibold fs-6">
|
||||
change me
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SmartForm Model="Form" OnValidSubmit="OnValidSubmit">
|
||||
<div class="fv-row mb-8">
|
||||
<input @bind="Form.Username" type="text" placeholder="Username" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="fv-row mb-8">
|
||||
<input @bind="Form.Email" type="text" placeholder="Email" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="fv-row mb-7">
|
||||
<input @bind="Form.Password" type="password" placeholder="Password" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="fv-row mb-7">
|
||||
<input @bind="Form.RepeatedPassword" type="password" placeholder="Repeat your password" class="form-control form-control-solid">
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-stack flex-wrap gap-3 fs-base fw-semibold mb-10">
|
||||
<div></div>
|
||||
<a href="/login" class="link-primary">
|
||||
Already have an account ?
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-stack">
|
||||
<button type="submit" class="btn btn-primary me-2 flex-shrink-0">Sign Up</button>
|
||||
<div class="d-flex align-items-center">
|
||||
<div class="text-gray-400 fw-semibold fs-6 me-3 me-md-6">Or</div>
|
||||
@* OAuth2 Providers here *@
|
||||
</div>
|
||||
</div>
|
||||
</SmartForm>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@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("/");
|
||||
}
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
@inject IJSRuntime JsRuntime
|
||||
@using Microsoft.AspNetCore.Components.Forms
|
||||
@using Ganss.Xss
|
||||
@using MoonCore.Helpers
|
||||
@using Moonlight.Core.Services
|
||||
@inherits InputBase<string>
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
|
||||
<style>
|
||||
:root {
|
||||
/*
|
||||
Fix from https://ckeditor.com/docs/ckeditor5/latest/installation/integrations/css.html
|
||||
to make the editor work with bootstrap
|
||||
*/
|
||||
--ck-z-default: 100;
|
||||
--ck-z-modal: calc( var(--ck-z-default) + 999 );
|
||||
|
||||
/* Overrides the border radius setting in the theme. */
|
||||
--ck-border-radius: 4px;
|
||||
|
||||
/* Overrides the default font size in the theme. */
|
||||
--ck-font-size-base: 14px;
|
||||
|
||||
/* Helper variables to avoid duplication in the colors. */
|
||||
--ck-custom-background: #1e1e2d;
|
||||
--ck-custom-foreground: hsl(255, 3%, 18%);
|
||||
--ck-custom-border: hsl(300, 1%, 22%);
|
||||
--ck-custom-white: hsl(0, 0%, 100%);
|
||||
|
||||
/* -- Overrides generic colors. ------------------------------------------------------------- */
|
||||
|
||||
--ck-color-base-foreground: var(--ck-custom-background);
|
||||
--ck-color-focus-border: hsl(208, 90%, 62%);
|
||||
--ck-color-text: hsl(0, 0%, 98%);
|
||||
--ck-color-shadow-drop: hsla(0, 0%, 0%, 0.2);
|
||||
--ck-color-shadow-inner: hsla(0, 0%, 0%, 0.1);
|
||||
|
||||
/* -- Overrides the default .ck-button class colors. ---------------------------------------- */
|
||||
|
||||
--ck-color-button-default-background: var(--ck-custom-background);
|
||||
--ck-color-button-default-hover-background: hsl(270, 1%, 22%);
|
||||
--ck-color-button-default-active-background: hsl(270, 2%, 20%);
|
||||
--ck-color-button-default-active-shadow: hsl(270, 2%, 23%);
|
||||
--ck-color-button-default-disabled-background: var(--ck-custom-background);
|
||||
|
||||
--ck-color-button-on-background: var(--ck-custom-foreground);
|
||||
--ck-color-button-on-hover-background: hsl(255, 4%, 16%);
|
||||
--ck-color-button-on-active-background: hsl(255, 4%, 14%);
|
||||
--ck-color-button-on-active-shadow: hsl(240, 3%, 19%);
|
||||
--ck-color-button-on-disabled-background: var(--ck-custom-foreground);
|
||||
|
||||
--ck-color-button-action-background: hsl(168, 76%, 42%);
|
||||
--ck-color-button-action-hover-background: hsl(168, 76%, 38%);
|
||||
--ck-color-button-action-active-background: hsl(168, 76%, 36%);
|
||||
--ck-color-button-action-active-shadow: hsl(168, 75%, 34%);
|
||||
--ck-color-button-action-disabled-background: hsl(168, 76%, 42%);
|
||||
--ck-color-button-action-text: var(--ck-custom-white);
|
||||
|
||||
/* -- Overrides the default .ck-dropdown class colors. -------------------------------------- */
|
||||
|
||||
--ck-color-dropdown-panel-background: var(--ck-custom-background);
|
||||
--ck-color-dropdown-panel-border: var(--ck-custom-foreground);
|
||||
|
||||
/* -- Overrides the default .ck-splitbutton class colors. ----------------------------------- */
|
||||
|
||||
--ck-color-split-button-hover-background: var(--ck-color-button-default-hover-background);
|
||||
--ck-color-split-button-hover-border: var(--ck-custom-foreground);
|
||||
|
||||
/* -- Overrides the default .ck-input class colors. ----------------------------------------- */
|
||||
|
||||
--ck-color-input-background: var(--ck-custom-background);
|
||||
--ck-color-input-border: hsl(257, 3%, 43%);
|
||||
--ck-color-input-text: hsl(0, 0%, 98%);
|
||||
--ck-color-input-disabled-background: hsl(255, 4%, 21%);
|
||||
--ck-color-input-disabled-border: hsl(250, 3%, 38%);
|
||||
--ck-color-input-disabled-text: hsl(0, 0%, 78%);
|
||||
|
||||
/* -- Overrides the default .ck-labeled-field-view class colors. ---------------------------- */
|
||||
|
||||
--ck-color-labeled-field-label-background: var(--ck-custom-background);
|
||||
|
||||
/* -- Overrides the default .ck-list class colors. ------------------------------------------ */
|
||||
|
||||
--ck-color-list-background: var(--ck-custom-background);
|
||||
--ck-color-list-button-hover-background: var(--ck-custom-foreground);
|
||||
--ck-color-list-button-on-background: hsl(208, 88%, 52%);
|
||||
--ck-color-list-button-on-text: var(--ck-custom-white);
|
||||
|
||||
/* -- Overrides the default .ck-balloon-panel class colors. --------------------------------- */
|
||||
|
||||
--ck-color-panel-background: var(--ck-custom-background);
|
||||
--ck-color-panel-border: var(--ck-custom-border);
|
||||
|
||||
/* -- Overrides the default .ck-toolbar class colors. --------------------------------------- */
|
||||
|
||||
--ck-color-toolbar-background: var(--ck-custom-background);
|
||||
--ck-color-toolbar-border: var(--ck-custom-border);
|
||||
|
||||
/* -- Overrides the default .ck-tooltip class colors. --------------------------------------- */
|
||||
|
||||
--ck-color-tooltip-background: hsl(252, 7%, 14%);
|
||||
--ck-color-tooltip-text: hsl(0, 0%, 93%);
|
||||
|
||||
/* -- Overrides the default colors used by the ckeditor5-image package. --------------------- */
|
||||
|
||||
--ck-color-image-caption-background: hsl(0, 0%, 97%);
|
||||
--ck-color-image-caption-text: hsl(0, 0%, 20%);
|
||||
|
||||
/* -- Overrides the default colors used by the ckeditor5-widget package. -------------------- */
|
||||
|
||||
--ck-color-widget-blurred-border: hsl(0, 0%, 87%);
|
||||
--ck-color-widget-hover-border: hsl(43, 100%, 68%);
|
||||
--ck-color-widget-editable-focus-background: var(--ck-custom-white);
|
||||
|
||||
/* -- Overrides the default colors used by the ckeditor5-link package. ---------------------- */
|
||||
|
||||
--ck-color-link-default: hsl(190, 100%, 75%);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div id="@Id" class="card card-body bg-black @(CssClasses)" @onfocusout="Callback" style="@(Styles)"></div>
|
||||
|
||||
@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<string>("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;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue