Added moonlight resources. Optimised moonlight legacy html rendering
This commit is contained in:
parent
8c67273d40
commit
764ff894af
117 changed files with 82725 additions and 1207 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -430,4 +430,5 @@ FodyWeavers.xsd
|
|||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
||||
*.sln.iml
|
||||
.idea/.idea.Moonlight/.idea/discord.xml
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="DiscordProjectSettings">
|
||||
<option name="show" value="ASK" />
|
||||
<option name="show" value="PROJECT_FILES" />
|
||||
<option name="description" value="" />
|
||||
</component>
|
||||
</project>
|
11
.idea/.idea.Moonlight/.idea/efCoreCommonOptions.xml
Normal file
11
.idea/.idea.Moonlight/.idea/efCoreCommonOptions.xml
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EfCoreCommonOptions">
|
||||
<option name="solutionLevelOptions">
|
||||
<map>
|
||||
<entry key="migrationsProject" value="16141d00-a997-4ba6-b0dc-af6f4712613a" />
|
||||
<entry key="startupProject" value="16141d00-a997-4ba6-b0dc-af6f4712613a" />
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
52
Moonlight/App/Database/DataContext.cs
Normal file
52
Moonlight/App/Database/DataContext.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Services;
|
||||
|
||||
namespace Moonlight.App.Database;
|
||||
|
||||
public class DataContext : DbContext
|
||||
{
|
||||
private readonly ConfigService ConfigService;
|
||||
|
||||
public DataContext(ConfigService configService)
|
||||
{
|
||||
ConfigService = configService;
|
||||
}
|
||||
|
||||
public DbSet<DockerImage> DockerImages { get; set; }
|
||||
public DbSet<Image> Images { get; set; }
|
||||
public DbSet<ImageTag> ImageTags { get; set; }
|
||||
public DbSet<ImageVariable> ImageVariables { get; set; }
|
||||
public DbSet<Node> Nodes { get; set; }
|
||||
public DbSet<NodeAllocation> NodeAllocations { get; set; }
|
||||
public DbSet<Server> Servers { get; set; }
|
||||
public DbSet<ServerBackup> ServerBackups { get; set; }
|
||||
public DbSet<ServerVariable> ServerVariables { get; set; }
|
||||
public DbSet<User> Users { get; set; }
|
||||
public DbSet<LoadingMessage> LoadingMessages { get; set; }
|
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
if (!optionsBuilder.IsConfigured)
|
||||
{
|
||||
var config = ConfigService
|
||||
.GetSection("Moonlight")
|
||||
.GetSection("Database");
|
||||
|
||||
var connectionString = $"host={config.GetValue<string>("Host")};" +
|
||||
$"port={config.GetValue<int>("Port")};" +
|
||||
$"database={config.GetValue<string>("Database")};" +
|
||||
$"uid={config.GetValue<string>("Username")};" +
|
||||
$"pwd={config.GetValue<string>("Password")}";
|
||||
|
||||
optionsBuilder.UseMySql(
|
||||
connectionString,
|
||||
ServerVersion.Parse("5.7.37-mysql"),
|
||||
builder =>
|
||||
{
|
||||
builder.EnableRetryOnFailure(5);
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
8
Moonlight/App/Database/Entities/DockerImage.cs
Normal file
8
Moonlight/App/Database/Entities/DockerImage.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class DockerImage
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public bool Default { get; set; } = false;
|
||||
public string Name { get; set; } = "";
|
||||
}
|
20
Moonlight/App/Database/Entities/Image.cs
Normal file
20
Moonlight/App/Database/Entities/Image.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class Image
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public Guid Uuid { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public string Description { get; set; } = "";
|
||||
public string ConfigFiles { get; set; } = "{}";
|
||||
public string StopCommand { get; set; } = "";
|
||||
public string StartupDetection { get; set; } = "";
|
||||
public string InstallScript { get; set; } = "";
|
||||
public string InstallDockerImage { get; set; } = "";
|
||||
public string InstallEntrypoint { get; set; } = "";
|
||||
public string Startup { get; set; } = "";
|
||||
|
||||
public List<DockerImage> DockerImages { get; set; } = new();
|
||||
public List<ImageVariable> Variables { get; set; } = new();
|
||||
public List<ImageTag> Tags { get; set; } = new();
|
||||
}
|
7
Moonlight/App/Database/Entities/ImageTag.cs
Normal file
7
Moonlight/App/Database/Entities/ImageTag.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class ImageTag
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
}
|
8
Moonlight/App/Database/Entities/ImageVariable.cs
Normal file
8
Moonlight/App/Database/Entities/ImageVariable.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class ImageVariable
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Key { get; set; } = "";
|
||||
public string DefaultValue { get; set; } = "";
|
||||
}
|
7
Moonlight/App/Database/Entities/LoadingMessage.cs
Normal file
7
Moonlight/App/Database/Entities/LoadingMessage.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class LoadingMessage
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Message { get; set; } = "";
|
||||
}
|
14
Moonlight/App/Database/Entities/Node.cs
Normal file
14
Moonlight/App/Database/Entities/Node.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class Node
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public string Fqdn { get; set; } = "";
|
||||
public string TokenId { get; set; } = "";
|
||||
public string Token { get; set; } = "";
|
||||
public int SftpPort { get; set; }
|
||||
public int HttpPort { get; set; }
|
||||
public int MoonlightDaemonPort { get; set; }
|
||||
public List<NodeAllocation> Allocations { get; set; } = new();
|
||||
}
|
7
Moonlight/App/Database/Entities/NodeAllocation.cs
Normal file
7
Moonlight/App/Database/Entities/NodeAllocation.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class NodeAllocation
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int Port { get; set; }
|
||||
}
|
23
Moonlight/App/Database/Entities/Server.cs
Normal file
23
Moonlight/App/Database/Entities/Server.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class Server
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public Guid Uuid { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public int Cpu { get; set; }
|
||||
public long Memory { get; set; }
|
||||
public long Disk { get; set; }
|
||||
public Image Image { get; set; } = null!;
|
||||
public int DockerImageIndex { get; set; } = 0;
|
||||
public string OverrideStartup { get; set; } = "";
|
||||
public bool Installing { get; set; } = false;
|
||||
public bool Suspended { get; set; } = false;
|
||||
|
||||
public List<ServerVariable> Variables { get; set; } = new();
|
||||
public List<ServerBackup> Backups { get; set; } = new();
|
||||
public List<NodeAllocation> Allocations { get; set; } = new();
|
||||
public NodeAllocation MainAllocation { get; set; } = null!;
|
||||
public Node Node { get; set; } = null!;
|
||||
public User Owner { get; set; } = null!;
|
||||
}
|
11
Moonlight/App/Database/Entities/ServerBackup.cs
Normal file
11
Moonlight/App/Database/Entities/ServerBackup.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class ServerBackup
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; } = "";
|
||||
public Guid Uuid { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public bool Created { get; set; } = false;
|
||||
public long Bytes { get; set; }
|
||||
}
|
8
Moonlight/App/Database/Entities/ServerVariable.cs
Normal file
8
Moonlight/App/Database/Entities/ServerVariable.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class ServerVariable
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Key { get; set; } = "";
|
||||
public string Value { get; set; } = "";
|
||||
}
|
26
Moonlight/App/Database/Entities/User.cs
Normal file
26
Moonlight/App/Database/Entities/User.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using Moonlight.App.Models.Misc;
|
||||
|
||||
namespace Moonlight.App.Database.Entities;
|
||||
|
||||
public class User
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string FirstName { get; set; } = "";
|
||||
public string LastName { get; set; } = "";
|
||||
public string Email { get; set; } = "";
|
||||
public string Password { get; set; } = "";
|
||||
public string Address { get; set; } = "";
|
||||
public string City { get; set; } = "";
|
||||
public string State { get; set; } = "";
|
||||
public string Country { get; set; } = "";
|
||||
public UserStatus Status { get; set; } = UserStatus.Unverified;
|
||||
public bool TotpEnabled { get; set; }
|
||||
public string TotpSecret { get; set; } = "";
|
||||
public DateTime TokenValidTime { get; set; } = DateTime.Now;
|
||||
public long DiscordId { get; set; }
|
||||
public string DiscordUsername { get; set; } = "";
|
||||
public string DiscordDiscriminator { get; set; } = "";
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public bool Admin { get; set; }
|
||||
}
|
515
Moonlight/App/Database/Migrations/20230215200722_InitialCreate.Designer.cs
generated
Normal file
515
Moonlight/App/Database/Migrations/20230215200722_InitialCreate.Designer.cs
generated
Normal file
|
@ -0,0 +1,515 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Moonlight.App.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.App.Database.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
[Migration("20230215200722_InitialCreate")]
|
||||
partial class InitialCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Default")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("DockerImages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConfigFiles")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallDockerImage")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallEntrypoint")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallScript")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Startup")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StartupDetection")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StopCommand")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Images");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("ImageTags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DefaultValue")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("ImageVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.LoadingMessage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LoadingMessages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Fqdn")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("HttpPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("MoonlightDaemonPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("SftpPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("TokenId")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Nodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("NodeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Port")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NodeId");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("NodeAllocations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Cpu")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Disk")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("DockerImageIndex")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Installing")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int>("MainAllocationId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Memory")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("NodeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("OverrideStartup")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Suspended")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.HasIndex("MainAllocationId");
|
||||
|
||||
b.HasIndex("NodeId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Servers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Bytes")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<bool>("Created")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("ServerBackups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("ServerVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("Admin")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("City")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Country")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("DiscordDiscriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<long>("DiscordId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("DiscordUsername")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("State")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("TokenValidTime")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("TotpEnabled")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("TotpSecret")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("DockerImages")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("Tags")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("Variables")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Node", null)
|
||||
.WithMany("Allocations")
|
||||
.HasForeignKey("NodeId");
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Allocations")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", "Image")
|
||||
.WithMany()
|
||||
.HasForeignKey("ImageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.NodeAllocation", "MainAllocation")
|
||||
.WithMany()
|
||||
.HasForeignKey("MainAllocationId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.Node", "Node")
|
||||
.WithMany()
|
||||
.HasForeignKey("NodeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Image");
|
||||
|
||||
b.Navigation("MainAllocation");
|
||||
|
||||
b.Navigation("Node");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Backups")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Variables")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
|
||||
{
|
||||
b.Navigation("DockerImages");
|
||||
|
||||
b.Navigation("Tags");
|
||||
|
||||
b.Navigation("Variables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
|
||||
{
|
||||
b.Navigation("Allocations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.Navigation("Allocations");
|
||||
|
||||
b.Navigation("Backups");
|
||||
|
||||
b.Navigation("Variables");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,434 @@
|
|||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Metadata;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.App.Database.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterDatabase()
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Images",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Uuid = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Description = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ConfigFiles = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
StopCommand = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
StartupDetection = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
InstallScript = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
InstallDockerImage = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
InstallEntrypoint = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Startup = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Images", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "LoadingMessages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Message = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_LoadingMessages", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Nodes",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Fqdn = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
TokenId = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Token = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
SftpPort = table.Column<int>(type: "int", nullable: false),
|
||||
HttpPort = table.Column<int>(type: "int", nullable: false),
|
||||
MoonlightDaemonPort = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Nodes", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Users",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
FirstName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
LastName = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Email = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Password = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Address = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
City = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
State = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Country = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Status = table.Column<int>(type: "int", nullable: false),
|
||||
TotpEnabled = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
TotpSecret = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
TokenValidTime = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
DiscordId = table.Column<long>(type: "bigint", nullable: false),
|
||||
DiscordUsername = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
DiscordDiscriminator = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
UpdatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
Admin = table.Column<bool>(type: "tinyint(1)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Users", x => x.Id);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "DockerImages",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Default = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ImageId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_DockerImages", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_DockerImages_Images_ImageId",
|
||||
column: x => x.ImageId,
|
||||
principalTable: "Images",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ImageTags",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ImageId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ImageTags", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ImageTags_Images_ImageId",
|
||||
column: x => x.ImageId,
|
||||
principalTable: "Images",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ImageVariables",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Key = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
DefaultValue = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ImageId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ImageVariables", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ImageVariables_Images_ImageId",
|
||||
column: x => x.ImageId,
|
||||
principalTable: "Images",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "NodeAllocations",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Port = table.Column<int>(type: "int", nullable: false),
|
||||
NodeId = table.Column<int>(type: "int", nullable: true),
|
||||
ServerId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_NodeAllocations", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_NodeAllocations_Nodes_NodeId",
|
||||
column: x => x.NodeId,
|
||||
principalTable: "Nodes",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Servers",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Uuid = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Cpu = table.Column<int>(type: "int", nullable: false),
|
||||
Memory = table.Column<long>(type: "bigint", nullable: false),
|
||||
Disk = table.Column<long>(type: "bigint", nullable: false),
|
||||
ImageId = table.Column<int>(type: "int", nullable: false),
|
||||
DockerImageIndex = table.Column<int>(type: "int", nullable: false),
|
||||
OverrideStartup = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Installing = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
Suspended = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
MainAllocationId = table.Column<int>(type: "int", nullable: false),
|
||||
NodeId = table.Column<int>(type: "int", nullable: false),
|
||||
OwnerId = table.Column<int>(type: "int", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Servers", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Servers_Images_ImageId",
|
||||
column: x => x.ImageId,
|
||||
principalTable: "Images",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Servers_NodeAllocations_MainAllocationId",
|
||||
column: x => x.MainAllocationId,
|
||||
principalTable: "NodeAllocations",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Servers_Nodes_NodeId",
|
||||
column: x => x.NodeId,
|
||||
principalTable: "Nodes",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_Servers_Users_OwnerId",
|
||||
column: x => x.OwnerId,
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerBackups",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Name = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Uuid = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
|
||||
CreatedAt = table.Column<DateTime>(type: "datetime(6)", nullable: false),
|
||||
Created = table.Column<bool>(type: "tinyint(1)", nullable: false),
|
||||
Bytes = table.Column<long>(type: "bigint", nullable: false),
|
||||
ServerId = table.Column<int>(type: "int", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ServerBackups", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_ServerBackups_Servers_ServerId",
|
||||
column: x => x.ServerId,
|
||||
principalTable: "Servers",
|
||||
principalColumn: "Id");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerVariables",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "int", nullable: false)
|
||||
.Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
|
||||
Key = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
Value = table.Column<string>(type: "longtext", nullable: false)
|
||||
.Annotation("MySql:CharSet", "utf8mb4"),
|
||||
ServerId = table.Column<int>(type: "int", 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");
|
||||
})
|
||||
.Annotation("MySql:CharSet", "utf8mb4");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_DockerImages_ImageId",
|
||||
table: "DockerImages",
|
||||
column: "ImageId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ImageTags_ImageId",
|
||||
table: "ImageTags",
|
||||
column: "ImageId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ImageVariables_ImageId",
|
||||
table: "ImageVariables",
|
||||
column: "ImageId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_NodeAllocations_NodeId",
|
||||
table: "NodeAllocations",
|
||||
column: "NodeId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_NodeAllocations_ServerId",
|
||||
table: "NodeAllocations",
|
||||
column: "ServerId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServerBackups_ServerId",
|
||||
table: "ServerBackups",
|
||||
column: "ServerId");
|
||||
|
||||
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_OwnerId",
|
||||
table: "Servers",
|
||||
column: "OwnerId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_ServerVariables_ServerId",
|
||||
table: "ServerVariables",
|
||||
column: "ServerId");
|
||||
|
||||
migrationBuilder.AddForeignKey(
|
||||
name: "FK_NodeAllocations_Servers_ServerId",
|
||||
table: "NodeAllocations",
|
||||
column: "ServerId",
|
||||
principalTable: "Servers",
|
||||
principalColumn: "Id");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Servers_Images_ImageId",
|
||||
table: "Servers");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NodeAllocations_Nodes_NodeId",
|
||||
table: "NodeAllocations");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_Servers_Nodes_NodeId",
|
||||
table: "Servers");
|
||||
|
||||
migrationBuilder.DropForeignKey(
|
||||
name: "FK_NodeAllocations_Servers_ServerId",
|
||||
table: "NodeAllocations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "DockerImages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ImageTags");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ImageVariables");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "LoadingMessages");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ServerBackups");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ServerVariables");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Images");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Nodes");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Servers");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "NodeAllocations");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Users");
|
||||
}
|
||||
}
|
||||
}
|
512
Moonlight/App/Database/Migrations/DataContextModelSnapshot.cs
Normal file
512
Moonlight/App/Database/Migrations/DataContextModelSnapshot.cs
Normal file
|
@ -0,0 +1,512 @@
|
|||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Moonlight.App.Database;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Moonlight.App.Database.Migrations
|
||||
{
|
||||
[DbContext(typeof(DataContext))]
|
||||
partial class DataContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "7.0.3")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Default")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("DockerImages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("ConfigFiles")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallDockerImage")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallEntrypoint")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("InstallScript")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Startup")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StartupDetection")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("StopCommand")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Images");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("ImageTags");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("DefaultValue")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.ToTable("ImageVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.LoadingMessage", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Message")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("LoadingMessages");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Fqdn")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("HttpPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("MoonlightDaemonPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("SftpPort")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Token")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("TokenId")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Nodes");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("NodeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Port")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NodeId");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("NodeAllocations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("Cpu")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Disk")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<int>("DockerImageIndex")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<int>("ImageId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Installing")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<int>("MainAllocationId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Memory")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("NodeId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("OverrideStartup")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("OwnerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<bool>("Suspended")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ImageId");
|
||||
|
||||
b.HasIndex("MainAllocationId");
|
||||
|
||||
b.HasIndex("NodeId");
|
||||
|
||||
b.HasIndex("OwnerId");
|
||||
|
||||
b.ToTable("Servers");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<long>("Bytes")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<bool>("Created")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<Guid>("Uuid")
|
||||
.HasColumnType("char(36)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("ServerBackups");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Key")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int?>("ServerId")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("ServerId");
|
||||
|
||||
b.ToTable("ServerVariables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.User", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<string>("Address")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<bool>("Admin")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("City")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Country")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("CreatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<string>("DiscordDiscriminator")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<long>("DiscordId")
|
||||
.HasColumnType("bigint");
|
||||
|
||||
b.Property<string>("DiscordUsername")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("FirstName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("LastName")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("Password")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<string>("State")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int");
|
||||
|
||||
b.Property<DateTime>("TokenValidTime")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.Property<bool>("TotpEnabled")
|
||||
.HasColumnType("tinyint(1)");
|
||||
|
||||
b.Property<string>("TotpSecret")
|
||||
.IsRequired()
|
||||
.HasColumnType("longtext");
|
||||
|
||||
b.Property<DateTime>("UpdatedAt")
|
||||
.HasColumnType("datetime(6)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Users");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.DockerImage", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("DockerImages")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageTag", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("Tags")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ImageVariable", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", null)
|
||||
.WithMany("Variables")
|
||||
.HasForeignKey("ImageId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.NodeAllocation", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Node", null)
|
||||
.WithMany("Allocations")
|
||||
.HasForeignKey("NodeId");
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Allocations")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Image", "Image")
|
||||
.WithMany()
|
||||
.HasForeignKey("ImageId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.NodeAllocation", "MainAllocation")
|
||||
.WithMany()
|
||||
.HasForeignKey("MainAllocationId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.Node", "Node")
|
||||
.WithMany()
|
||||
.HasForeignKey("NodeId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Moonlight.App.Database.Entities.User", "Owner")
|
||||
.WithMany()
|
||||
.HasForeignKey("OwnerId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Image");
|
||||
|
||||
b.Navigation("MainAllocation");
|
||||
|
||||
b.Navigation("Node");
|
||||
|
||||
b.Navigation("Owner");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerBackup", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Backups")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.ServerVariable", b =>
|
||||
{
|
||||
b.HasOne("Moonlight.App.Database.Entities.Server", null)
|
||||
.WithMany("Variables")
|
||||
.HasForeignKey("ServerId");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Image", b =>
|
||||
{
|
||||
b.Navigation("DockerImages");
|
||||
|
||||
b.Navigation("Tags");
|
||||
|
||||
b.Navigation("Variables");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Node", b =>
|
||||
{
|
||||
b.Navigation("Allocations");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Moonlight.App.Database.Entities.Server", b =>
|
||||
{
|
||||
b.Navigation("Allocations");
|
||||
|
||||
b.Navigation("Backups");
|
||||
|
||||
b.Navigation("Variables");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
58
Moonlight/App/Helpers/TranslationHelper.cs
Normal file
58
Moonlight/App/Helpers/TranslationHelper.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
using Logging.Net;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Moonlight.App.Helpers
|
||||
{
|
||||
public class TranslationHelper
|
||||
{
|
||||
private readonly Dictionary<string, IConfiguration> Languages;
|
||||
|
||||
public TranslationHelper()
|
||||
{
|
||||
Languages = new();
|
||||
|
||||
foreach (var file in Directory.GetFiles("resources/lang"))
|
||||
{
|
||||
var langKey = Path.GetFileName(file)
|
||||
.Replace(Path.GetExtension(file), "");
|
||||
|
||||
Languages.Add(langKey, new ConfigurationBuilder()
|
||||
.AddJsonFile(file)
|
||||
.Build());
|
||||
}
|
||||
}
|
||||
|
||||
public string? Get(string langKey, string key)
|
||||
{
|
||||
if (Languages.ContainsKey(langKey))
|
||||
{
|
||||
var parts = key.Split(".");
|
||||
|
||||
IConfigurationSection? section = null;
|
||||
foreach (var part in parts)
|
||||
{
|
||||
if (part == parts.Last())
|
||||
{
|
||||
if (section == null)
|
||||
return Languages[langKey].GetValue<string>(part);
|
||||
else
|
||||
return section.GetValue<string>(part);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (section == null)
|
||||
section = Languages[langKey].GetSection(part);
|
||||
else
|
||||
section = section.GetSection(part);
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "Invalid lang key";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
48
Moonlight/App/Models/IpLocate/Resources/IpLocate.cs
Normal file
48
Moonlight/App/Models/IpLocate/Resources/IpLocate.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
using Newtonsoft.Json;
|
||||
|
||||
namespace Moonlight.App.Models.IpLocate.Resources;
|
||||
|
||||
public class IpLocate
|
||||
{
|
||||
[JsonProperty("query")]
|
||||
public string Query { get; set; }
|
||||
|
||||
[JsonProperty("status")]
|
||||
public string Status { get; set; }
|
||||
|
||||
[JsonProperty("country")]
|
||||
public string Country { get; set; }
|
||||
|
||||
[JsonProperty("countryCode")]
|
||||
public string CountryCode { get; set; }
|
||||
|
||||
[JsonProperty("region")]
|
||||
public string Region { get; set; }
|
||||
|
||||
[JsonProperty("regionName")]
|
||||
public string RegionName { get; set; }
|
||||
|
||||
[JsonProperty("city")]
|
||||
public string City { get; set; }
|
||||
|
||||
[JsonProperty("zip")]
|
||||
public string Zip { get; set; }
|
||||
|
||||
[JsonProperty("lat")]
|
||||
public double Lat { get; set; }
|
||||
|
||||
[JsonProperty("lon")]
|
||||
public double Lon { get; set; }
|
||||
|
||||
[JsonProperty("timezone")]
|
||||
public string Timezone { get; set; }
|
||||
|
||||
[JsonProperty("isp")]
|
||||
public string Isp { get; set; }
|
||||
|
||||
[JsonProperty("org")]
|
||||
public string Org { get; set; }
|
||||
|
||||
[JsonProperty("as")]
|
||||
public string As { get; set; }
|
||||
}
|
15
Moonlight/App/Models/Misc/Session.cs
Normal file
15
Moonlight/App/Models/Misc/Session.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Moonlight.App.Services.Interop;
|
||||
|
||||
namespace Moonlight.App.Models.Misc;
|
||||
|
||||
public class Session
|
||||
{
|
||||
public string Ip { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Device { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public NavigationManager Navigation { get; set; }
|
||||
public AlertService AlertService { get; set; }
|
||||
}
|
12
Moonlight/App/Models/Misc/UserStatus.cs
Normal file
12
Moonlight/App/Models/Misc/UserStatus.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace Moonlight.App.Models.Misc;
|
||||
|
||||
public enum UserStatus
|
||||
{
|
||||
Unverified,
|
||||
Verified,
|
||||
VerifyPending,
|
||||
VerifyFailed,
|
||||
Warned,
|
||||
Banned,
|
||||
Disabled
|
||||
}
|
44
Moonlight/App/Repositories/NodeRepository.cs
Normal file
44
Moonlight/App/Repositories/NodeRepository.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories;
|
||||
|
||||
public class NodeRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public NodeRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<Node> Get()
|
||||
{
|
||||
return DataContext.Nodes;
|
||||
}
|
||||
|
||||
public Node Add(Node node)
|
||||
{
|
||||
var x = DataContext.Nodes.Add(node);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(Node node)
|
||||
{
|
||||
DataContext.Nodes.Update(node);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(Node node)
|
||||
{
|
||||
DataContext.Nodes.Remove(node);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
44
Moonlight/App/Repositories/Servers/ServerBackupRepository.cs
Normal file
44
Moonlight/App/Repositories/Servers/ServerBackupRepository.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories.Servers;
|
||||
|
||||
public class ServerBackupRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public ServerBackupRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<ServerBackup> Get()
|
||||
{
|
||||
return DataContext.ServerBackups;
|
||||
}
|
||||
|
||||
public ServerBackup Add(ServerBackup serverBackup)
|
||||
{
|
||||
var x = DataContext.ServerBackups.Add(serverBackup);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(ServerBackup serverBackup)
|
||||
{
|
||||
DataContext.ServerBackups.Update(serverBackup);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(ServerBackup serverBackup)
|
||||
{
|
||||
DataContext.ServerBackups.Remove(serverBackup);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
44
Moonlight/App/Repositories/Servers/ServerRepository.cs
Normal file
44
Moonlight/App/Repositories/Servers/ServerRepository.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories.Servers;
|
||||
|
||||
public class ServerRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public ServerRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<Server> Get()
|
||||
{
|
||||
return DataContext.Servers;
|
||||
}
|
||||
|
||||
public Server Add(Server server)
|
||||
{
|
||||
var x = DataContext.Servers.Add(server);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(Server server)
|
||||
{
|
||||
DataContext.Servers.Update(server);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(Server server)
|
||||
{
|
||||
DataContext.Servers.Remove(server);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
37
Moonlight/App/Repositories/SessionRepository.cs
Normal file
37
Moonlight/App/Repositories/SessionRepository.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using Moonlight.App.Models.Misc;
|
||||
|
||||
namespace Moonlight.App.Repositories;
|
||||
|
||||
public class SessionRepository
|
||||
{
|
||||
private readonly List<Session> Sessions;
|
||||
|
||||
public SessionRepository()
|
||||
{
|
||||
Sessions = new();
|
||||
}
|
||||
|
||||
public Session[] Get()
|
||||
{
|
||||
lock (Sessions)
|
||||
{
|
||||
return Sessions.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(Session session)
|
||||
{
|
||||
lock (Sessions)
|
||||
{
|
||||
Sessions.Add(session);
|
||||
}
|
||||
}
|
||||
|
||||
public void Delete(Session session)
|
||||
{
|
||||
lock (Sessions)
|
||||
{
|
||||
Sessions.Remove(session);
|
||||
}
|
||||
}
|
||||
}
|
44
Moonlight/App/Repositories/UserRepository.cs
Normal file
44
Moonlight/App/Repositories/UserRepository.cs
Normal file
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.EntityFrameworkCore;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Database.Entities;
|
||||
|
||||
namespace Moonlight.App.Repositories;
|
||||
|
||||
public class UserRepository : IDisposable
|
||||
{
|
||||
private readonly DataContext DataContext;
|
||||
|
||||
public UserRepository(DataContext dataContext)
|
||||
{
|
||||
DataContext = dataContext;
|
||||
}
|
||||
|
||||
public DbSet<User> Get()
|
||||
{
|
||||
return DataContext.Users;
|
||||
}
|
||||
|
||||
public User Add(User user)
|
||||
{
|
||||
var x = DataContext.Users.Add(user);
|
||||
DataContext.SaveChanges();
|
||||
return x.Entity;
|
||||
}
|
||||
|
||||
public void Update(User user)
|
||||
{
|
||||
DataContext.Users.Update(user);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Delete(User user)
|
||||
{
|
||||
DataContext.Users.Remove(user);
|
||||
DataContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DataContext.Dispose();
|
||||
}
|
||||
}
|
46
Moonlight/App/Services/ConfigService.cs
Normal file
46
Moonlight/App/Services/ConfigService.cs
Normal file
|
@ -0,0 +1,46 @@
|
|||
using System.Text;
|
||||
using Logging.Net;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
|
||||
namespace Moonlight.App.Services;
|
||||
|
||||
public class ConfigService : IConfiguration
|
||||
{
|
||||
private IConfiguration Configuration;
|
||||
|
||||
public bool DebugMode { get; private set; } = false;
|
||||
|
||||
public ConfigService()
|
||||
{
|
||||
Configuration = new ConfigurationBuilder().AddJsonStream(
|
||||
new MemoryStream(Encoding.ASCII.GetBytes(File.ReadAllText("..\\..\\appsettings.json")))
|
||||
).Build();
|
||||
|
||||
// Env vars
|
||||
var debugVar = Environment.GetEnvironmentVariable("ML_DEBUG");
|
||||
|
||||
if (debugVar != null)
|
||||
DebugMode = bool.Parse(debugVar);
|
||||
}
|
||||
|
||||
public IEnumerable<IConfigurationSection> GetChildren()
|
||||
{
|
||||
return Configuration.GetChildren();
|
||||
}
|
||||
|
||||
public IChangeToken GetReloadToken()
|
||||
{
|
||||
return Configuration.GetReloadToken();
|
||||
}
|
||||
|
||||
public IConfigurationSection GetSection(string key)
|
||||
{
|
||||
return Configuration.GetSection(key);
|
||||
}
|
||||
|
||||
public string this[string key]
|
||||
{
|
||||
get => Configuration[key];
|
||||
set => Configuration[key] = value;
|
||||
}
|
||||
}
|
82
Moonlight/App/Services/Interop/AlertService.cs
Normal file
82
Moonlight/App/Services/Interop/AlertService.cs
Normal file
|
@ -0,0 +1,82 @@
|
|||
using CurrieTechnologies.Razor.SweetAlert2;
|
||||
|
||||
namespace Moonlight.App.Services.Interop;
|
||||
|
||||
public class AlertService
|
||||
{
|
||||
private readonly SweetAlertService SweetAlertService;
|
||||
|
||||
public AlertService(SweetAlertService service)
|
||||
{
|
||||
SweetAlertService = service;
|
||||
}
|
||||
|
||||
public async Task Info(string title, string desciption)
|
||||
{
|
||||
await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Icon = SweetAlertIcon.Info
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Success(string title, string desciption)
|
||||
{
|
||||
await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Icon = SweetAlertIcon.Success
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Warning(string title, string desciption)
|
||||
{
|
||||
await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Icon = SweetAlertIcon.Warning
|
||||
});
|
||||
}
|
||||
|
||||
public async Task Error(string title, string desciption)
|
||||
{
|
||||
await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Icon = SweetAlertIcon.Error
|
||||
});
|
||||
}
|
||||
|
||||
public async Task<bool> YesNo(string title, string desciption, string yesText, string noText)
|
||||
{
|
||||
var result = await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
ShowCancelButton = false,
|
||||
ShowDenyButton = true,
|
||||
ShowConfirmButton = true,
|
||||
ConfirmButtonText = yesText,
|
||||
DenyButtonText = noText
|
||||
});
|
||||
|
||||
return result.IsConfirmed;
|
||||
}
|
||||
|
||||
public async Task<string> Text(string title, string desciption, string setValue)
|
||||
{
|
||||
var result = await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
Title = title,
|
||||
Text = desciption,
|
||||
Input = SweetAlertInputType.Text,
|
||||
InputValue = setValue
|
||||
});
|
||||
|
||||
return result.Value;
|
||||
}
|
||||
}
|
18
Moonlight/App/Services/Interop/ClipboardService.cs
Normal file
18
Moonlight/App/Services/Interop/ClipboardService.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Moonlight.App.Services.Interop;
|
||||
|
||||
public class ClipboardService
|
||||
{
|
||||
private readonly IJSRuntime JsRuntime;
|
||||
|
||||
public ClipboardService(IJSRuntime jsRuntime)
|
||||
{
|
||||
JsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
public async Task CopyToClipboard(string data)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("copyTextToClipboard", data);
|
||||
}
|
||||
}
|
33
Moonlight/App/Services/Interop/ToastService.cs
Normal file
33
Moonlight/App/Services/Interop/ToastService.cs
Normal file
|
@ -0,0 +1,33 @@
|
|||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Moonlight.App.Services.Interop;
|
||||
|
||||
public class ToastService
|
||||
{
|
||||
private readonly IJSRuntime JsRuntime;
|
||||
|
||||
public ToastService(IJSRuntime jsRuntime)
|
||||
{
|
||||
JsRuntime = jsRuntime;
|
||||
}
|
||||
|
||||
public async Task Info(string message)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("showInfoToast", message);
|
||||
}
|
||||
|
||||
public async Task Error(string message)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("showErrorToast", message);
|
||||
}
|
||||
|
||||
public async Task Warning(string message)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("showWarningToast", message);
|
||||
}
|
||||
|
||||
public async Task Success(string message)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("showSuccessToast", message);
|
||||
}
|
||||
}
|
51
Moonlight/App/Services/Sessions/CookieService.cs
Normal file
51
Moonlight/App/Services/Sessions/CookieService.cs
Normal file
|
@ -0,0 +1,51 @@
|
|||
using Microsoft.JSInterop;
|
||||
|
||||
namespace Moonlight.App.Services.Sessions;
|
||||
|
||||
public class CookieService
|
||||
{
|
||||
private readonly IJSRuntime JsRuntime;
|
||||
private string Expires = "";
|
||||
|
||||
public CookieService(IJSRuntime jsRuntime)
|
||||
{
|
||||
JsRuntime = jsRuntime;
|
||||
ExpireDays = 300;
|
||||
}
|
||||
|
||||
public async Task SetValue(string key, string value, int? days = null)
|
||||
{
|
||||
var curExp = (days != null) ? (days > 0 ? DateToUTC(days.Value) : "") : Expires;
|
||||
await SetCookie($"{key}={value}; expires={curExp}; path=/");
|
||||
}
|
||||
|
||||
public async Task<string> GetValue(string key, string def = "")
|
||||
{
|
||||
var cValue = await GetCookie();
|
||||
if (string.IsNullOrEmpty(cValue)) return def;
|
||||
|
||||
var vals = cValue.Split(';');
|
||||
foreach (var val in vals)
|
||||
if(!string.IsNullOrEmpty(val) && val.IndexOf('=') > 0)
|
||||
if(val.Substring(1, val.IndexOf('=') - 1).Trim().Equals(key, StringComparison.OrdinalIgnoreCase))
|
||||
return val.Substring(val.IndexOf('=') + 1);
|
||||
return def;
|
||||
}
|
||||
|
||||
private async Task SetCookie(string value)
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("eval", $"document.cookie = \"{value}\"");
|
||||
}
|
||||
|
||||
private async Task<string> GetCookie()
|
||||
{
|
||||
return await JsRuntime.InvokeAsync<string>("eval", $"document.cookie");
|
||||
}
|
||||
|
||||
private int ExpireDays
|
||||
{
|
||||
set => Expires = DateToUTC(value);
|
||||
}
|
||||
|
||||
private static string DateToUTC(int days) => DateTime.Now.AddDays(days).ToUniversalTime().ToString("R");
|
||||
}
|
167
Moonlight/App/Services/Sessions/IdentityService.cs
Normal file
167
Moonlight/App/Services/Sessions/IdentityService.cs
Normal file
|
@ -0,0 +1,167 @@
|
|||
using System.Text;
|
||||
using JWT.Algorithms;
|
||||
using JWT.Builder;
|
||||
using JWT.Exceptions;
|
||||
using Logging.Net;
|
||||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Repositories;
|
||||
using UAParser;
|
||||
|
||||
namespace Moonlight.App.Services.Sessions;
|
||||
|
||||
public class IdentityService
|
||||
{
|
||||
private readonly UserRepository UserRepository;
|
||||
private readonly CookieService CookieService;
|
||||
private readonly IHttpContextAccessor HttpContextAccessor;
|
||||
private readonly string Secret;
|
||||
|
||||
private User? UserCache;
|
||||
|
||||
public IdentityService(
|
||||
CookieService cookieService,
|
||||
UserRepository userRepository,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
ConfigService configService)
|
||||
{
|
||||
CookieService = cookieService;
|
||||
UserRepository = userRepository;
|
||||
HttpContextAccessor = httpContextAccessor;
|
||||
|
||||
Secret = configService
|
||||
.GetSection("Moonlight")
|
||||
.GetSection("Security")
|
||||
.GetValue<string>("Token");
|
||||
}
|
||||
|
||||
public async Task<User?> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (UserCache != null)
|
||||
return UserCache;
|
||||
|
||||
var token = "none";
|
||||
|
||||
// Load token via http context if available
|
||||
if (HttpContextAccessor.HttpContext != null)
|
||||
{
|
||||
var request = HttpContextAccessor.HttpContext.Request;
|
||||
|
||||
if (request.Cookies.ContainsKey("token"))
|
||||
{
|
||||
token = request.Cookies["token"];
|
||||
}
|
||||
}
|
||||
else // if not we check the cookies manually via js. this may not often work
|
||||
{
|
||||
token = await CookieService.GetValue("token", "none");
|
||||
}
|
||||
|
||||
if (token == "none")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(token))
|
||||
return null;
|
||||
|
||||
var json = "";
|
||||
|
||||
try
|
||||
{
|
||||
json = JwtBuilder.Create()
|
||||
.WithAlgorithm(new HMACSHA256Algorithm())
|
||||
.WithSecret(Secret)
|
||||
.Decode(token);
|
||||
}
|
||||
catch (TokenExpiredException)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch (SignatureVerificationException)
|
||||
{
|
||||
//TODO: Heavy warn and write it to the logs
|
||||
Logger.Warn("Someone tried to modify his data: " + token);
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("Error parsing and validating token");
|
||||
Logger.Warn(e);
|
||||
return null;
|
||||
}
|
||||
|
||||
// To make it easier to use the json data
|
||||
var data = new ConfigurationBuilder().AddJsonStream(
|
||||
new MemoryStream(Encoding.ASCII.GetBytes(json))
|
||||
).Build();
|
||||
|
||||
var userid = data.GetValue<int>("userid");
|
||||
var user = UserRepository.Get().FirstOrDefault(y => y.Id == userid);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
Logger.Warn($"Cannot find user with the id '{userid}' in the database. Maybe the user has been deleted or a token has been successfully faked by a hacker");
|
||||
return null;
|
||||
}
|
||||
|
||||
var iat = data.GetValue<long>("iat", -1);
|
||||
|
||||
if (iat == -1)
|
||||
{
|
||||
Logger.Debug("Legacy token found (without the time the token has been issued at)");
|
||||
return null;
|
||||
}
|
||||
|
||||
var issuedAt = DateTimeOffset.FromUnixTimeSeconds(iat).DateTime;
|
||||
|
||||
if (issuedAt < user.TokenValidTime.ToUniversalTime())
|
||||
{
|
||||
//TODO: Remove at publish
|
||||
//Logger.Debug($"Old token found: {issuedAt.ToShortDateString()} {issuedAt.ToShortTimeString()} Current valid token time {userData.TokenValidTime.ToUniversalTime().ToShortDateString()} {userData.TokenValidTime.ToUniversalTime().ToShortTimeString()}");
|
||||
return null;
|
||||
}
|
||||
|
||||
UserCache = user;
|
||||
return UserCache;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("Error loading user");
|
||||
Logger.Warn(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public string GetIp()
|
||||
{
|
||||
if (HttpContextAccessor.HttpContext == null)
|
||||
return "N/A";
|
||||
|
||||
if(HttpContextAccessor.HttpContext.Request.Headers.ContainsKey("X-Real-IP"))
|
||||
{
|
||||
return HttpContextAccessor.HttpContext.Request.Headers["X-Real-IP"]!;
|
||||
}
|
||||
|
||||
return HttpContextAccessor.HttpContext.Connection.RemoteIpAddress!.ToString();
|
||||
}
|
||||
|
||||
public string GetDevice()
|
||||
{
|
||||
if (HttpContextAccessor.HttpContext == null)
|
||||
return "N/A";
|
||||
|
||||
try
|
||||
{
|
||||
var uaParser = Parser.GetDefault();
|
||||
var info = uaParser.Parse(HttpContextAccessor.HttpContext.Request.Headers.UserAgent);
|
||||
|
||||
return $"{info.OS} - {info.Device}";
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return "UserAgent not present";
|
||||
}
|
||||
}
|
||||
}
|
37
Moonlight/App/Services/Sessions/IpLocateService.cs
Normal file
37
Moonlight/App/Services/Sessions/IpLocateService.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System.Net;
|
||||
using Moonlight.App.Models.IpLocate.Resources;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Moonlight.App.Services.Sessions;
|
||||
|
||||
public class IpLocateService
|
||||
{
|
||||
private readonly IdentityService IdentityService;
|
||||
|
||||
public IpLocateService(IdentityService identityService)
|
||||
{
|
||||
IdentityService = identityService;
|
||||
}
|
||||
|
||||
public async Task<string> GetLocation()
|
||||
{
|
||||
var ip = IdentityService.GetIp();
|
||||
var location = "N/A";
|
||||
|
||||
if (ip != "N/A")
|
||||
{
|
||||
using (var wc = new WebClient())
|
||||
{
|
||||
var res = JsonConvert.DeserializeObject<IpLocate>(
|
||||
await wc.DownloadStringTaskAsync(
|
||||
$"http://ip-api.com/json/{ip}"
|
||||
)
|
||||
);
|
||||
|
||||
location = $"{res.Country} - {res.RegionName} - {res.City} ({res.Org})";
|
||||
}
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
}
|
77
Moonlight/App/Services/Sessions/SessionService.cs
Normal file
77
Moonlight/App/Services/Sessions/SessionService.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Models.Misc;
|
||||
using Moonlight.App.Repositories;
|
||||
using Moonlight.App.Services.Interop;
|
||||
|
||||
namespace Moonlight.App.Services.Sessions;
|
||||
|
||||
public class SessionService
|
||||
{
|
||||
private readonly SessionRepository SessionRepository;
|
||||
private readonly IdentityService IdentityService;
|
||||
private readonly NavigationManager NavigationManager;
|
||||
private readonly AlertService AlertService;
|
||||
|
||||
private Session OwnSession;
|
||||
|
||||
public SessionService(
|
||||
SessionRepository sessionRepository,
|
||||
IdentityService identityService,
|
||||
NavigationManager navigationManager,
|
||||
AlertService alertService)
|
||||
{
|
||||
SessionRepository = sessionRepository;
|
||||
IdentityService = identityService;
|
||||
NavigationManager = navigationManager;
|
||||
AlertService = alertService;
|
||||
}
|
||||
|
||||
public async Task Register()
|
||||
{
|
||||
var user = await IdentityService.Get();
|
||||
var userId = -1;
|
||||
|
||||
if (user != null)
|
||||
userId = user.Id;
|
||||
|
||||
OwnSession = new Session()
|
||||
{
|
||||
Ip = IdentityService.GetIp(),
|
||||
Url = NavigationManager.Uri,
|
||||
Device = IdentityService.GetDevice(),
|
||||
CreatedAt = DateTime.Now,
|
||||
UserId = userId,
|
||||
Navigation = NavigationManager,
|
||||
AlertService = AlertService
|
||||
};
|
||||
|
||||
SessionRepository.Add(OwnSession);
|
||||
}
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
OwnSession.Url = NavigationManager.Uri;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
SessionRepository.Delete(OwnSession);
|
||||
}
|
||||
|
||||
public Session[] GetAll()
|
||||
{
|
||||
return SessionRepository.Get();
|
||||
}
|
||||
|
||||
public void ReloadUserSessions(User user)
|
||||
{
|
||||
foreach (var session in SessionRepository.Get())
|
||||
{
|
||||
if (session.UserId == user.Id)
|
||||
{
|
||||
session.Navigation.NavigateTo(session.Navigation.Uri, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
98
Moonlight/App/Services/TranslationService.cs
Normal file
98
Moonlight/App/Services/TranslationService.cs
Normal file
|
@ -0,0 +1,98 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Moonlight.App.Helpers;
|
||||
|
||||
namespace Moonlight.App.Services
|
||||
{
|
||||
public class TranslationService
|
||||
{
|
||||
private string LanguageCode { get; set; } = "en_us";
|
||||
private readonly string FallbackLanguage = "en_us";
|
||||
|
||||
private TranslationHelper Helper { get; }
|
||||
private HttpContext HttpContext { get; }
|
||||
|
||||
public TranslationService(TranslationHelper helper, IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
Helper = helper;
|
||||
HttpContext = httpContextAccessor.HttpContext!;
|
||||
|
||||
LanguageCode = FallbackLanguage;
|
||||
|
||||
try
|
||||
{
|
||||
var langHeader = HttpContext.Request.Headers["Accept-Language"].ToString();
|
||||
var important = langHeader.Split(";").First().ToLower().Split(",");
|
||||
|
||||
foreach (var v in important)
|
||||
{
|
||||
if (v.Contains("de"))
|
||||
{
|
||||
LanguageCode = "de_de";
|
||||
break;
|
||||
}
|
||||
else if (v.Contains("en"))
|
||||
{
|
||||
LanguageCode = "en_us";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var cookies = HttpContext.Request.Headers["Cookie"].ToString().Split(new string[] { ",", ";" }, StringSplitOptions.TrimEntries);
|
||||
|
||||
foreach (var cookie in cookies)
|
||||
{
|
||||
var name = cookie.Split("=").First().Trim();
|
||||
var value = cookie.Split("=").Last().Trim();
|
||||
|
||||
if (name == "lang")
|
||||
{
|
||||
if (value.Contains("de"))
|
||||
{
|
||||
LanguageCode = "de_de";
|
||||
break;
|
||||
}
|
||||
else if (value.Contains("en"))
|
||||
{
|
||||
LanguageCode = "en_us";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public string Translate(string key, params object[] parameters)
|
||||
{
|
||||
try
|
||||
{
|
||||
var text = Helper.Get(LanguageCode, key);
|
||||
|
||||
if (text == null)
|
||||
return key;
|
||||
|
||||
int i = 0;
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
text = text.Replace($"{{{i}}}", param.ToString());
|
||||
i++;
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logging.Net.Logger.Error(ex);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
public MarkupString TranslateMarkup(string key, params object[] parameters)
|
||||
{
|
||||
return new MarkupString(Translate(key, parameters));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
<Router AppAssembly="@typeof(App).Assembly">
|
||||
@using Moonlight.Shared.Layouts
|
||||
|
||||
<Router AppAssembly="@typeof(BlazorApp).Assembly">
|
||||
<Found Context="routeData">
|
||||
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
|
||||
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
|
|
@ -1,13 +0,0 @@
|
|||
namespace Moonlight.Data
|
||||
{
|
||||
public class WeatherForecast
|
||||
{
|
||||
public DateTime Date { get; set; }
|
||||
|
||||
public int TemperatureC { get; set; }
|
||||
|
||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
||||
|
||||
public string? Summary { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
namespace Moonlight.Data
|
||||
{
|
||||
public class WeatherForecastService
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
|
||||
{
|
||||
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = startDate.AddDays(index),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
}).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,7 +9,56 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="aaPanelSharp" Version="1.0.0" />
|
||||
<PackageReference Include="BCrypt.Net-Next" Version="4.0.3" />
|
||||
<PackageReference Include="Ben.Demystifier" Version="0.4.1" />
|
||||
<PackageReference Include="Blazor.ContextMenu" Version="1.15.0" />
|
||||
<PackageReference Include="BlazorMonaco" Version="3.0.0" />
|
||||
<PackageReference Include="BlazorTable" Version="1.17.0" />
|
||||
<PackageReference Include="CurrieTechnologies.Razor.SweetAlert2" Version="5.4.0" />
|
||||
<PackageReference Include="Discord.Net" Version="3.9.0" />
|
||||
<PackageReference Include="GravatarSharp.Core" Version="0.9.0.2" />
|
||||
<PackageReference Include="JWT" Version="10.0.2" />
|
||||
<PackageReference Include="Logging.Net" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.15.1" />
|
||||
<PackageReference Include="MineStat" Version="3.1.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3-beta1" />
|
||||
<PackageReference Include="Otp.NET" Version="1.3.0" />
|
||||
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="7.0.0" />
|
||||
<PackageReference Include="PteroConsole.NET" Version="1.0.4" />
|
||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
||||
<PackageReference Include="RestSharp" Version="109.0.0-preview.1" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="XtermBlazor" Version="1.6.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\bootstrap\bootstrap.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\bootstrap\bootstrap.min.css.map" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\FONT-LICENSE" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\css\open-iconic-bootstrap.min.css" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.eot" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.otf" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.svg" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.ttf" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\font\fonts\open-iconic.woff" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\ICON-LICENSE" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\README.md" />
|
||||
<_ContentIncludedByDefault Remove="wwwroot\css\site.css" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="App\Database\Migrations" />
|
||||
<Folder Include="App\Exceptions" />
|
||||
<Folder Include="App\Http\Controllers" />
|
||||
<Folder Include="App\Http\Middleware" />
|
||||
<Folder Include="App\Http\Requests" />
|
||||
<Folder Include="App\Http\Resources" />
|
||||
<Folder Include="wwwroot\assets\media" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
@page "/counter"
|
||||
|
||||
<PageTitle>Counter</PageTitle>
|
||||
|
||||
<h1>Counter</h1>
|
||||
|
||||
<p role="status">Current count: @currentCount</p>
|
||||
|
||||
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
|
||||
|
||||
@code {
|
||||
private int currentCount = 0;
|
||||
|
||||
private void IncrementCount()
|
||||
{
|
||||
currentCount++;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
@page "/fetchdata"
|
||||
|
||||
<PageTitle>Weather forecast</PageTitle>
|
||||
|
||||
@using Moonlight.Data
|
||||
@inject WeatherForecastService ForecastService
|
||||
|
||||
<h1>Weather forecast</h1>
|
||||
|
||||
<p>This component demonstrates fetching data from a service.</p>
|
||||
|
||||
@if (forecasts == null)
|
||||
{
|
||||
<p><em>Loading...</em></p>
|
||||
}
|
||||
else
|
||||
{
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Date</th>
|
||||
<th>Temp. (C)</th>
|
||||
<th>Temp. (F)</th>
|
||||
<th>Summary</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach (var forecast in forecasts)
|
||||
{
|
||||
<tr>
|
||||
<td>@forecast.Date.ToShortDateString()</td>
|
||||
<td>@forecast.TemperatureC</td>
|
||||
<td>@forecast.TemperatureF</td>
|
||||
<td>@forecast.Summary</td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
@code {
|
||||
private WeatherForecast[]? forecasts;
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
@page "/"
|
||||
|
||||
<PageTitle>Index</PageTitle>
|
||||
|
||||
<h1>Hello, world!</h1>
|
||||
|
||||
Welcome to your new app.
|
||||
|
||||
<SurveyPrompt Title="How is Blazor working for you?" />
|
|
@ -5,4 +5,25 @@
|
|||
Layout = "_Layout";
|
||||
}
|
||||
|
||||
<component type="typeof(App)" render-mode="ServerPrerendered" />
|
||||
<component type="typeof(BlazorApp)" render-mode="ServerPrerendered" />
|
||||
|
||||
<div id="components-reconnect-modal" class="my-reconnect-modal components-reconnect-hide">
|
||||
<div class="show">
|
||||
<p>
|
||||
<br/>
|
||||
Connecting to moonlight servers
|
||||
</p>
|
||||
</div>
|
||||
<div class="failed">
|
||||
<p>
|
||||
<br />
|
||||
Connection to moonlight servers failed
|
||||
</p>
|
||||
</div>
|
||||
<div class="rejected">
|
||||
<p>
|
||||
<br />
|
||||
Connection to moonlight servers rejected
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,32 +1,111 @@
|
|||
@using Microsoft.AspNetCore.Components.Web
|
||||
@using Moonlight.App.Services
|
||||
@namespace Moonlight.Pages
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var headerConfig = ConfigService
|
||||
.GetSection("Moonlight")
|
||||
.GetSection("Html")
|
||||
.GetSection("Headers");
|
||||
|
||||
var moonlightConfig = ConfigService
|
||||
.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" data-theme="dark">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<base href="~/" />
|
||||
<link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
|
||||
<link href="css/site.css" rel="stylesheet" />
|
||||
<link href="Moonlight.styles.css" rel="stylesheet" />
|
||||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered" />
|
||||
<meta charset="utf-8"/>
|
||||
|
||||
<meta property="og:locale" content="de_DE"/>
|
||||
<meta property="og:type" content="article"/>
|
||||
<meta content="@(headerConfig.GetValue<string>("Title"))" property="og:title"/>
|
||||
<meta content="@(headerConfig.GetValue<string>("Description"))" property="og:description"/>
|
||||
<meta content="@(moonlightConfig.GetValue<string>("AppUrl"))" property="og:url"/>
|
||||
<meta content="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logofull.png" property="og:image"/>
|
||||
<meta content="@(headerConfig.GetValue<string>("Color"))" data-react-helmet="true" name="theme-color"/>
|
||||
|
||||
<meta content="@(headerConfig.GetValue<string>("Description"))" name="description"/>
|
||||
<meta content="@(headerConfig.GetValue<string>("Keywords"))" name="keywords"/>
|
||||
|
||||
<link rel="shortcut icon" href="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg"/>
|
||||
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700"/>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/style.bundle.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/flashbang.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/snow.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/invisiblea.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/boxicons.min.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/assets/css/blazor.css"/>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/_content/XtermBlazor/XtermBlazor.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="/_content/Blazor.ContextMenu/blazorContextMenu.min.css"/>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<base href="~/"/>
|
||||
<component type="typeof(HeadOutlet)" render-mode="ServerPrerendered"/>
|
||||
|
||||
<title>Loading</title>
|
||||
</head>
|
||||
<body>
|
||||
@RenderBody()
|
||||
<body
|
||||
class="app-default"
|
||||
cz-shortcut-listen="true"
|
||||
data-kt-app-layout="dark-sidebar"
|
||||
data-kt-app-header-fixed="true"
|
||||
data-kt-app-sidebar-fixed="true"
|
||||
data-kt-app-sidebar-hoverable="true"
|
||||
data-kt-app-sidebar-push-header="true"
|
||||
data-kt-app-sidebar-push-toolbar="true"
|
||||
data-kt-app-sidebar-push-footer="true"
|
||||
data-kt-app-toolbar-enabled="true">
|
||||
|
||||
<div id="blazor-error-ui">
|
||||
<environment include="Staging,Production">
|
||||
An error has occurred. This application may no longer respond until reloaded.
|
||||
</environment>
|
||||
<environment include="Development">
|
||||
An unhandled exception has occurred. See browser dev tools for details.
|
||||
</environment>
|
||||
<a href="" class="reload">Reload</a>
|
||||
<a class="dismiss">🗙</a>
|
||||
@RenderBody()
|
||||
|
||||
<div id="flashbang" class="flashbanglight"></div>
|
||||
|
||||
<div class="app-page-loader flex-column">
|
||||
<img alt="Logo" src="/api/moonlight/resources/images/logo.svg" class="h-25px"/>
|
||||
|
||||
<div class="d-flex align-items-center mt-5">
|
||||
<span class="spinner-border text-primary" role="status"></span>
|
||||
<span class="text-muted fs-6 fw-semibold ms-5">CHANGEME</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="_framework/blazor.server.js"></script>
|
||||
<script src="/_framework/blazor.server.js"></script>
|
||||
|
||||
<script src="/_content/XtermBlazor/XtermBlazor.min.js"></script>
|
||||
<script src="/_content/BlazorTable/BlazorTable.min.js"></script>
|
||||
<script src="/_content/BlazorInputFile/inputfile.js"></script>
|
||||
<script src="/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
|
||||
<script src="/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
|
||||
<script src="/_content/BlazorMonaco/jsInterop.js"></script>
|
||||
<script src="/_content/CurrieTechnologies.Razor.SweetAlert2/sweetAlert2.min.js"></script>
|
||||
<script src="/_content/Blazor-ApexCharts/js/blazor-apex-charts.js"></script>
|
||||
<script src="/_content/Blazor.ContextMenu/blazorContextMenu.min.js"></script>
|
||||
|
||||
<script src="https://www.google.com/recaptcha/api.js"></script>
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-search@0.8.2/lib/xterm-addon-search.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/xterm-addon-web-links@0.5.0/lib/xterm-addon-web-links.min.js"></script>
|
||||
|
||||
<script src="/assets/js/scripts.bundle.js"></script>
|
||||
<script src="/assets/js/flashbang.js"></script>
|
||||
<script src="/assets/js/cookieUtils.js"></script>
|
||||
<script src="/assets/js/clipboard.js"></script>
|
||||
<script src="/assets/js/toastUtils.js"></script>
|
||||
<script src="/assets/js/alertUtils.js"></script>
|
||||
<script src="/assets/js/utils.js"></script>
|
||||
<script src="/assets/js/loggingUtils.js"></script>
|
||||
<script src="/assets/js/snow.js"></script>
|
||||
<script src="/assets/js/recaptcha.js"></script>
|
||||
<script src="/assets/js/xtermAddons.js"></script>
|
||||
<script src="/assets/js/monaco.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
|
@ -1,9 +1,14 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Microsoft.AspNetCore.Components.Web;
|
||||
using BlazorTable;
|
||||
using CurrieTechnologies.Razor.SweetAlert2;
|
||||
using Moonlight.App.Database;
|
||||
using Moonlight.App.Helpers;
|
||||
using Moonlight.App.Repositories;
|
||||
using Moonlight.App.Repositories.Servers;
|
||||
using Moonlight.App.Services;
|
||||
using Moonlight.App.Services.Interop;
|
||||
using Moonlight.App.Services.Sessions;
|
||||
|
||||
using Moonlight.Data;
|
||||
|
||||
namespace Company.WebApplication1
|
||||
namespace Moonlight
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
|
@ -14,7 +19,36 @@ namespace Company.WebApplication1
|
|||
// Add services to the container.
|
||||
builder.Services.AddRazorPages();
|
||||
builder.Services.AddServerSideBlazor();
|
||||
builder.Services.AddSingleton<WeatherForecastService>();
|
||||
builder.Services.AddHttpContextAccessor();
|
||||
|
||||
// Databases
|
||||
builder.Services.AddDbContext<DataContext>();
|
||||
|
||||
// Repositories
|
||||
builder.Services.AddSingleton<SessionRepository>();
|
||||
builder.Services.AddScoped<UserRepository>();
|
||||
builder.Services.AddScoped<NodeRepository>();
|
||||
builder.Services.AddScoped<ServerRepository>();
|
||||
builder.Services.AddScoped<ServerBackupRepository>();
|
||||
|
||||
// Services
|
||||
builder.Services.AddScoped<TranslationService>();
|
||||
builder.Services.AddSingleton<ConfigService>();
|
||||
builder.Services.AddScoped<CookieService>();
|
||||
builder.Services.AddScoped<IdentityService>();
|
||||
builder.Services.AddScoped<IpLocateService>();
|
||||
builder.Services.AddScoped<SessionService>();
|
||||
builder.Services.AddScoped<TranslationService>();
|
||||
builder.Services.AddScoped<AlertService>();
|
||||
|
||||
// Helpers
|
||||
builder.Services.AddSingleton<TranslationHelper>();
|
||||
|
||||
// Third party services
|
||||
|
||||
builder.Services.AddBlazorTable();
|
||||
builder.Services.AddSweetAlert2(options => { options.Theme = SweetAlertTheme.Dark; });
|
||||
builder.Services.AddBlazorContextMenu();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
|
21
Moonlight/Shared/Components/Alerts/BannedAlert.razor
Normal file
21
Moonlight/Shared/Components/Alerts/BannedAlert.razor
Normal file
|
@ -0,0 +1,21 @@
|
|||
@using Moonlight.App.Services
|
||||
|
||||
@inject TranslationService TranslationService
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var moonlightConfig = ConfigService
|
||||
.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<div class="card card-flush w-lg-650px py-5">
|
||||
<div class="card-body py-15 py-lg-20">
|
||||
<div class="mb-14">
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logofull.png" class="h-40px">
|
||||
</div>
|
||||
<h1 class="fw-bolder text-gray-900 mb-5">@(TranslationService.Translate("Alerts.Banned.Title"))</h1>
|
||||
<div class="fw-semibold fs-6 text-gray-500 mb-8">
|
||||
@(TranslationService.Translate("Alerts.Banned.Details"))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
21
Moonlight/Shared/Components/Alerts/DisabledAlert.razor
Normal file
21
Moonlight/Shared/Components/Alerts/DisabledAlert.razor
Normal file
|
@ -0,0 +1,21 @@
|
|||
@using Moonlight.App.Services
|
||||
|
||||
@inject TranslationService TranslationService
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var moonlightConfig = ConfigService
|
||||
.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<div class="card card-flush w-lg-650px py-5">
|
||||
<div class="card-body py-15 py-lg-20">
|
||||
<div class="mb-14">
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logofull.png" class="h-40px">
|
||||
</div>
|
||||
<h1 class="fw-bolder text-gray-900 mb-5">@(TranslationService.Translate("Alerts.Disabled.Title"))</h1>
|
||||
<div class="fw-semibold fs-6 text-gray-500 mb-8">
|
||||
@(TranslationService.Translate("Alerts.Disabled.Details"))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,73 @@
|
|||
@using Moonlight.App.Services
|
||||
@using Logging.Net
|
||||
@using Moonlight.App.Services.Sessions
|
||||
|
||||
@inherits ErrorBoundary
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject TranslationService TranslationService
|
||||
|
||||
@if (CurrentException is null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else if (ErrorContent is not null)
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Component.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Component.Details")
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Component.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Component.Details")
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
List<Exception> receivedExceptions = new();
|
||||
|
||||
protected override async Task OnErrorAsync(Exception exception)
|
||||
{
|
||||
receivedExceptions.Add(exception);
|
||||
|
||||
var user = await IdentityService.Get();
|
||||
var id = user == null ? -1 : user.Id;
|
||||
|
||||
Logger.Error($"[{id}] An unhanded exception occured:");
|
||||
Logger.Error(exception);
|
||||
|
||||
//TODO: Create error report
|
||||
|
||||
await base.OnErrorAsync(exception);
|
||||
}
|
||||
|
||||
public new void Recover()
|
||||
{
|
||||
receivedExceptions.Clear();
|
||||
base.Recover();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
@using Moonlight.App.Services
|
||||
@using Logging.Net
|
||||
@using Moonlight.App.Services.Sessions
|
||||
|
||||
@inherits ErrorBoundary
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject TranslationService TranslationService
|
||||
|
||||
@if (CurrentException is null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else if (ErrorContent is not null)
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@(TranslationService.Translate("Crashes.Global.Title"))
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@(TranslationService.Translate("Crashes.Global.Details"))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Global.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Global.Details")
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
List<Exception> receivedExceptions = new();
|
||||
|
||||
protected override async Task OnErrorAsync(Exception exception)
|
||||
{
|
||||
receivedExceptions.Add(exception);
|
||||
|
||||
var user = await IdentityService.Get();
|
||||
var id = user == null ? -1 : user.Id;
|
||||
|
||||
Logger.Error($"[{id}] An unhanded exception occured:");
|
||||
Logger.Error(exception);
|
||||
|
||||
await base.OnErrorAsync(exception);
|
||||
}
|
||||
|
||||
public new void Recover()
|
||||
{
|
||||
receivedExceptions.Clear();
|
||||
base.Recover();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
@using Logging.Net
|
||||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Services.Sessions
|
||||
|
||||
@inherits ErrorBoundary
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject TranslationService TranslationService
|
||||
|
||||
@if (CurrentException is null)
|
||||
{
|
||||
@ChildContent
|
||||
}
|
||||
else if (ErrorContent is not null)
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Page.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Page.Details")
|
||||
</div>
|
||||
</div>
|
||||
<img class="mx-auto h-150px h-lg-200px" src="/assets/media/svg/illustrations/broken-cable.svg" alt="Broken cable">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="card card-flush h-md-100">
|
||||
<div class="card-body d-flex flex-column justify-content-between mt-9 bgi-no-repeat bgi-size-cover bgi-position-x-center pb-0">
|
||||
<div class="mb-10">
|
||||
<div class="fs-2hx fw-bold text-gray-800 text-center mb-13">
|
||||
<span class="me-2">
|
||||
@TranslationService.Translate("Crashes.Page.Title")
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-center">
|
||||
@TranslationService.Translate("Crashes.Page.Details")
|
||||
</div>
|
||||
</div>
|
||||
<img class="mx-auto h-150px h-lg-200px" src="/assets/media/svg/illustrations/broken-cable.svg" alt="Broken cable">
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@code
|
||||
{
|
||||
List<Exception> receivedExceptions = new();
|
||||
|
||||
protected override async Task OnErrorAsync(Exception exception)
|
||||
{
|
||||
receivedExceptions.Add(exception);
|
||||
|
||||
var user = await IdentityService.Get();
|
||||
var id = user == null ? -1 : user.Id;
|
||||
|
||||
Logger.Error($"[{id}] An unhanded exception occured:");
|
||||
Logger.Error(exception);
|
||||
|
||||
await base.OnErrorAsync(exception);
|
||||
}
|
||||
|
||||
public new void Recover()
|
||||
{
|
||||
receivedExceptions.Clear();
|
||||
base.Recover();
|
||||
}
|
||||
}
|
38
Moonlight/Shared/Components/Partials/Footer.razor
Normal file
38
Moonlight/Shared/Components/Partials/Footer.razor
Normal file
|
@ -0,0 +1,38 @@
|
|||
@using Moonlight.App.Services
|
||||
|
||||
@inject TranslationService TranslationService
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var marketingConfig = ConfigService
|
||||
.GetSection("Moonlight")
|
||||
.GetSection("Marketing");
|
||||
}
|
||||
|
||||
<div id="kt_app_footer" class="app-footer">
|
||||
<div class="app-container container-fluid d-flex flex-column flex-md-row flex-center flex-md-stack py-3">
|
||||
<div class="text-dark order-2 order-md-1">
|
||||
<span class="text-muted fw-semibold me-1">2022 - @DateTime.Now.Year©</span>
|
||||
<a href="@(marketingConfig.GetValue<string>("Website"))" target="_blank" class="text-gray-800 text-hover-primary">
|
||||
@(marketingConfig.GetValue<string>("BrandName"))
|
||||
</a>
|
||||
</div>
|
||||
<ul class="menu menu-gray-600 menu-hover-primary fw-semibold order-1">
|
||||
<li class="menu-item">
|
||||
<a href="@(marketingConfig.GetValue<string>("About"))" target="_blank" class="menu-link px-2">
|
||||
@(TranslationService.Translate("Footer.AboutUs"))
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a href="@(marketingConfig.GetValue<string>("Imprint"))" target="_blank" class="menu-link px-2">
|
||||
@(TranslationService.Translate("Footer.Imprint"))
|
||||
</a>
|
||||
</li>
|
||||
<li class="menu-item">
|
||||
<a href="@(marketingConfig.GetValue<string>("Privacy"))" target="_blank" class="menu-link px-2">
|
||||
@(TranslationService.Translate("Footer.Privacy"))
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
90
Moonlight/Shared/Components/Partials/Navbar.razor
Normal file
90
Moonlight/Shared/Components/Partials/Navbar.razor
Normal file
|
@ -0,0 +1,90 @@
|
|||
@using Moonlight.App.Helpers
|
||||
@using Moonlight.App.Repositories
|
||||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Services.Sessions
|
||||
@using Moonlight.App.Database.Entities
|
||||
@using Task = System.Threading.Tasks.Task
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject NavigationManager NavigationManager
|
||||
@inject CookieService CookieService
|
||||
@inject TranslationService TranslationService
|
||||
|
||||
<div class="app-navbar flex-shrink-0">
|
||||
<div class="app-navbar-item ms-1 ms-lg-3">
|
||||
<ThemeSwitcher
|
||||
ToggleBtnClass="btn btn-icon btn-custom btn-icon-muted btn-active-light btn-active-color-primary w-35px h-35px w-md-40px h-md-40px"
|
||||
ToggleBtnIconClass="svg-icon svg-icon-2">
|
||||
</ThemeSwitcher>
|
||||
</div>
|
||||
|
||||
@if (User != null)
|
||||
{
|
||||
<div class="app-navbar-item ms-1 ms-lg-3">
|
||||
<div class="btn btn-icon btn-custom btn-icon-muted btn-active-light btn-active-color-primary w-35px h-35px w-md-40px h-md-40px position-relative" id="support_ticket_toggle">
|
||||
<span class="svg-icon svg-icon-1">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.3" d="M20 3H4C2.89543 3 2 3.89543 2 5V16C2 17.1046 2.89543 18 4 18H4.5C5.05228 18 5.5 18.4477 5.5 19V21.5052C5.5 22.1441 6.21212 22.5253 6.74376 22.1708L11.4885 19.0077C12.4741 18.3506 13.6321 18 14.8167 18H20C21.1046 18 22 17.1046 22 16V5C22 3.89543 21.1046 3 20 3Z" fill="currentColor"></path>
|
||||
<rect x="6" y="12" width="7" height="2" rx="1" fill="currentColor"></rect>
|
||||
<rect x="6" y="7" width="12" height="2" rx="1" fill="currentColor"></rect>
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app-navbar-item ms-1 ms-lg-3" id="kt_header_user_menu_toggle">
|
||||
<div class="cursor-pointer symbol symbol-35px symbol-md-40px" data-kt-menu-trigger="click" data-kt-menu-attach="parent" data-kt-menu-placement="bottom-end">
|
||||
<img alt="Avatar" src="/api/moonlight/avatar/@(User.Id)"/>
|
||||
</div>
|
||||
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-gray-800 menu-state-bg menu-state-primary fw-semibold py-4 fs-6 w-275px" data-kt-menu="true">
|
||||
<div class="menu-item px-3">
|
||||
<div class="menu-content d-flex align-items-center px-3">
|
||||
<div class="symbol symbol-50px me-5">
|
||||
<img alt="Avatar" src="/api/moonlight/avatar/@(User.Id)"/>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<div class="fw-bold d-flex align-items-center fs-5">
|
||||
@(User.FirstName) @(User.LastName)
|
||||
|
||||
@if (User.Admin)
|
||||
{
|
||||
<span class="badge badge-light-success fw-bold fs-8 px-2 py-1 ms-2">Admin</span>
|
||||
}
|
||||
</div>
|
||||
<a class="fw-semibold text-muted text-hover-primary fs-7">@(User.Email)</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="separator my-2"></div>
|
||||
<div class="menu-item px-5 my-1">
|
||||
<a href="/settings" class="menu-link px-5">@TranslationService.Translate("Navbar.Account.Settings")</a>
|
||||
</div>
|
||||
<div class="menu-item px-5">
|
||||
<a @onclick="Logout" class="menu-link px-5">@TranslationService.Translate("Navbar.Logout")</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private User? User;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
User = await IdentityService.Get();
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
|
||||
private async void Logout()
|
||||
{
|
||||
await CookieService.SetValue("token", "", 1);
|
||||
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
||||
}
|
||||
}
|
29
Moonlight/Shared/Components/Partials/PageHeader.razor
Normal file
29
Moonlight/Shared/Components/Partials/PageHeader.razor
Normal file
|
@ -0,0 +1,29 @@
|
|||
@using Moonlight.App.Services
|
||||
|
||||
@inject ConfigService ConfigService
|
||||
|
||||
@{
|
||||
var moonlightConfig = ConfigService.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<div id="kt_app_header" class="app-header">
|
||||
<div class="app-container container-fluid d-flex align-items-stretch justify-content-between">
|
||||
<div class="d-flex align-items-center d-lg-none ms-n2 me-2" title="Show sidebar menu">
|
||||
<div class="btn btn-icon btn-active-color-primary w-35px h-35px" id="kt_app_sidebar_mobile_toggle">
|
||||
<i class="bx bx-menu bx-md"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-items-center flex-grow-1 flex-lg-grow-0">
|
||||
<a href="/" class="d-lg-none">
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg" class="h-30px"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="d-flex align-items-stretch justify-content-between flex-lg-grow-1" id="kt_app_header_wrapper">
|
||||
<div class="app-header-menu app-header-mobile-drawer align-items-stretch" data-kt-drawer="true" data-kt-drawer-name="app-header-menu" data-kt-drawer-activate="{default: true, lg: false}" data-kt-drawer-overlay="true" data-kt-drawer-width="225px" data-kt-drawer-direction="end" data-kt-drawer-toggle="#kt_app_header_menu_toggle" data-kt-swapper="true" data-kt-swapper-mode="{default: 'append', lg: 'prepend'}" data-kt-swapper-parent="{default: '#kt_app_body', lg: '#kt_app_header_wrapper'}">
|
||||
<div class="menu menu-rounded menu-column menu-lg-row my-5 my-lg-0 align-items-stretch fw-semibold px-2 px-lg-0" id="kt_app_header_menu" data-kt-menu="true">
|
||||
</div>
|
||||
</div>
|
||||
<Navbar></Navbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
63
Moonlight/Shared/Components/Partials/Sidebar.razor
Normal file
63
Moonlight/Shared/Components/Partials/Sidebar.razor
Normal file
|
@ -0,0 +1,63 @@
|
|||
@using Moonlight.App.Services.Sessions
|
||||
@using Moonlight.App.Database.Entities
|
||||
@using Moonlight.App.Services
|
||||
|
||||
@inject IdentityService IdentityService
|
||||
@inject TranslationService TranslationService
|
||||
@inject ConfigService ConfigService
|
||||
@inject IJSRuntime JsRuntime
|
||||
|
||||
@{
|
||||
var moonlightConfig = ConfigService
|
||||
.GetSection("Moonlight");
|
||||
}
|
||||
|
||||
<div id="kt_app_sidebar" class="app-sidebar flex-column" data-kt-drawer="true" data-kt-drawer-name="app-sidebar" data-kt-drawer-activate="{default: true, lg: false}" data-kt-drawer-overlay="true" data-kt-drawer-width="225px" data-kt-drawer-direction="start" data-kt-drawer-toggle="#kt_app_sidebar_mobile_toggle">
|
||||
<div class="app-sidebar-logo px-6" id="kt_app_sidebar_logo">
|
||||
<a href="@(User != null ? "/" : "/login")">
|
||||
@if (sidebar == "dark-sidebar")
|
||||
{
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logofull.png" class="h-45px app-sidebar-logo-default"/>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sidebar == "light-sidebar")
|
||||
{
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg" class="theme-light-show h-20px app-sidebar-logo-default"/>
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg" class="theme-dark-show h-20px app-sidebar-logo-default"/>
|
||||
}
|
||||
}
|
||||
<img alt="Logo" src="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg" class="h-20px app-sidebar-logo-minimize"/>
|
||||
</a>
|
||||
|
||||
<div id="kt_app_sidebar_toggle" class="app-sidebar-toggle btn btn-icon btn-shadow btn-sm btn-color-muted btn-active-color-primary body-bg h-30px w-30px position-absolute top-50 start-100 translate-middle rotate" data-kt-toggle="true" data-kt-toggle-state="active" data-kt-toggle-target="body" data-kt-toggle-name="app-sidebar-minimize">
|
||||
<i class="bx bx-chevrons-left bx-md"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SidebarMenu></SidebarMenu>
|
||||
|
||||
<div class="app-sidebar-footer flex-column-auto pt-2 pb-6 px-6" id="kt_app_sidebar_footer">
|
||||
<a id="support_ticket_toggle_sidebar"
|
||||
class="btn btn-flex flex-center btn-custom btn-primary overflow-hidden text-nowrap px-0 h-40px w-100 btn-label">
|
||||
@(TranslationService.Translate("Sidebar.Footer.OpenSupport"))
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private string sidebar;
|
||||
|
||||
private User? User;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
User = await IdentityService.Get();
|
||||
sidebar = await JsRuntime.InvokeAsync<string>("document.body.getAttribute", "data-kt-app-layout");
|
||||
StateHasChanged();
|
||||
}
|
||||
}
|
||||
}
|
266
Moonlight/Shared/Components/Partials/SidebarMenu.razor
Normal file
266
Moonlight/Shared/Components/Partials/SidebarMenu.razor
Normal file
|
@ -0,0 +1,266 @@
|
|||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Services.Sessions
|
||||
@using Moonlight.App.Database.Entities
|
||||
|
||||
@inject TranslationService TranslationService
|
||||
@inject IdentityService IdentityService
|
||||
|
||||
<div class="app-sidebar-menu overflow-hidden flex-column-fluid">
|
||||
<div id="kt_app_sidebar_menu_wrapper" class="app-sidebar-wrapper hover-scroll-overlay-y my-5" data-kt-scroll="true" data-kt-scroll-activate="true" data-kt-scroll-height="auto" data-kt-scroll-dependencies="#kt_app_sidebar_logo, #kt_app_sidebar_footer" data-kt-scroll-wrappers="#kt_app_sidebar_menu" data-kt-scroll-offset="5px" data-kt-scroll-save-state="true">
|
||||
<div class="menu menu-column menu-rounded menu-sub-indention px-3" id="#kt_app_sidebar_menu" data-kt-menu="true" data-kt-menu-expand="false">
|
||||
@if (User == null)
|
||||
{
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/login">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bxs-log-in"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Login")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/register">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-user-plus"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Register")</span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-layer"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Dashboard")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div data-kt-menu-trigger="click" class="menu-item menu-accordion">
|
||||
<span class="menu-link">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-cart-alt"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Order")</span>
|
||||
<span class="menu-arrow"></span>
|
||||
</span>
|
||||
<div class="menu-sub menu-sub-accordion">
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/store/website">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Website")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/store/database">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Database")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/store/domain">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Domain")</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/servers">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-server"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Servers")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/websites">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-globe"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Websites")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/databases">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-data"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Databases")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/domains">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-purchase-tag"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Domains")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/changelog">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-notepad"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Changelog")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
if (User.Admin)
|
||||
{
|
||||
<div class="menu-item pt-5">
|
||||
<div class="menu-content">
|
||||
<span class="menu-heading fw-bold text-uppercase fs-7">@TranslationService.Translate("Sidebar.Menu.Admin")</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-layer"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Dashboard")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/general">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-chip"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.System")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div data-kt-menu-trigger="click" class="menu-item menu-accordion">
|
||||
<span class="menu-link">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-server"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Servers")</span>
|
||||
<span class="menu-arrow"></span>
|
||||
</span>
|
||||
<div class="menu-sub menu-sub-accordion">
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/servers">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Overview")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/servers/manager">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Manager")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/servers/cleanup">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Cleanup")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/nodes">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Nodes")</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/images">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Images")</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-kt-menu-trigger="click" class="menu-item menu-accordion">
|
||||
<span class="menu-link">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-cube"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.AaPanel")</span>
|
||||
<span class="menu-arrow"></span>
|
||||
</span>
|
||||
<div class="menu-sub menu-sub-accordion">
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/aapanel/">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Overview")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/aapanel/databases">
|
||||
<span class="menu-bullet">
|
||||
<span class="bullet bullet-dot"></span>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Databases")</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/users">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-user"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Users")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/support">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-support"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Support")</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item">
|
||||
<a class="menu-link" href="/admin/statistics">
|
||||
<span class="menu-icon">
|
||||
<i class="bx bx-objects-vertical-bottom"></i>
|
||||
</span>
|
||||
<span class="menu-title">@TranslationService.Translate("Sidebar.Menu.Statistics")</span>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
private User? User;
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
User = await IdentityService.Get();
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
}
|
||||
}
|
52
Moonlight/Shared/Components/Partials/ThemeSwitcher.razor
Normal file
52
Moonlight/Shared/Components/Partials/ThemeSwitcher.razor
Normal file
|
@ -0,0 +1,52 @@
|
|||
@inject IJSRuntime JsRuntime
|
||||
|
||||
<a href="#" class="@ToggleBtnClass" data-kt-menu-trigger="@Trigger" data-kt-menu-attach="parent" data-kt-menu-placement="@MenuPlacement">
|
||||
<i class="theme-light-show bx bx-sun"></i>
|
||||
<i class="theme-dark-show bx bx-moon" ></i>
|
||||
</a>
|
||||
|
||||
<div class="menu menu-sub menu-sub-dropdown menu-column menu-rounded menu-title-gray-700 menu-icon-muted menu-active-bg menu-state-primary fw-semibold py-4 fs-base w-175px" data-kt-menu="true" data-kt-element="theme-mode-menu">
|
||||
<div class="menu-item px-3 my-0">
|
||||
<a href="#" class="menu-link px-3 py-2" data-kt-element="mode" data-kt-value="light" @onclick="TriggerFlashbang">
|
||||
<span class="menu-icon" data-kt-element="icon">
|
||||
<i class="bx bx-sun"></i>
|
||||
</span>
|
||||
<span class="menu-title">Lightmode</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item px-3 my-0">
|
||||
<a href="#" class="menu-link px-3 py-2" data-kt-element="mode" data-kt-value="dark">
|
||||
<span class="menu-icon" data-kt-element="icon">
|
||||
<i class="bx bx-moon"></i>
|
||||
</span>
|
||||
<span class="menu-title">Darkmode</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="menu-item px-3 my-0">
|
||||
<a href="#" class="menu-link px-3 py-2" data-kt-element="mode" data-kt-value="system">
|
||||
<span class="menu-icon" data-kt-element="icon">
|
||||
<i class="bx bx-cog"></i>
|
||||
</span>
|
||||
<span class="menu-title">System</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string ToggleBtnClass { get; set; } = "";
|
||||
|
||||
[Parameter]
|
||||
public string MenuPlacement { get; set; } = "bottom-end";
|
||||
|
||||
[Parameter]
|
||||
public string ToggleBtnIconClass { get; set; } = "svg-icon svg-icon-2";
|
||||
|
||||
[Parameter]
|
||||
public string Trigger { get; set; } = "{default:'click'}";
|
||||
|
||||
private async void TriggerFlashbang()
|
||||
{
|
||||
await JsRuntime.InvokeVoidAsync("flashbang");
|
||||
}
|
||||
}
|
139
Moonlight/Shared/Layouts/MainLayout.razor
Normal file
139
Moonlight/Shared/Layouts/MainLayout.razor
Normal file
|
@ -0,0 +1,139 @@
|
|||
@using Moonlight.Shared.Components.ErrorBoundaries
|
||||
@using Moonlight.Shared.Components.Partials
|
||||
@using Moonlight.Shared.Components.Alerts
|
||||
@using Moonlight.App.Database.Entities
|
||||
@using Moonlight.App.Models.Misc
|
||||
@using Moonlight.App.Services.Sessions
|
||||
|
||||
@layout ThemeInit
|
||||
@implements IDisposable
|
||||
@inherits LayoutComponentBase
|
||||
|
||||
@inject IJSRuntime JsRuntime
|
||||
@inject IdentityService IdentityService
|
||||
@inject SessionService SessionService
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
<GlobalErrorBoundary>
|
||||
<div class="d-flex flex-column flex-root app-root" id="kt_app_root">
|
||||
<div class="app-page flex-column flex-column-fluid" id="kt_app_page">
|
||||
<canvas id="snow" class="snow-canvas"></canvas>
|
||||
|
||||
@{
|
||||
//TODO: Add a way to disable the snow
|
||||
}
|
||||
|
||||
<PageHeader></PageHeader>
|
||||
<div class="app-wrapper flex-column flex-row-fluid" id="kt_app_wrapper">
|
||||
<Sidebar></Sidebar>
|
||||
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
|
||||
<div class="d-flex flex-column flex-column-fluid">
|
||||
<div id="kt_app_content" class="app-content flex-column-fluid">
|
||||
<div id="kt_app_content_container" class="app-container container-fluid">
|
||||
<div class="mt-10">
|
||||
<PageErrorBoundary>
|
||||
@if (User == null)
|
||||
{
|
||||
@Body
|
||||
}
|
||||
else
|
||||
{
|
||||
if (User.Status == UserStatus.Banned)
|
||||
{
|
||||
<BannedAlert></BannedAlert>
|
||||
}
|
||||
else if (User.Status == UserStatus.Disabled)
|
||||
{
|
||||
<DisabledAlert></DisabledAlert>
|
||||
}
|
||||
else
|
||||
{
|
||||
@Body
|
||||
}
|
||||
}
|
||||
</PageErrorBoundary>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer></Footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</GlobalErrorBoundary>
|
||||
|
||||
@code
|
||||
{
|
||||
private User? User;
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
AddBodyAttribute("data-kt-app-page-loading", "on");
|
||||
}
|
||||
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
//Initialize classes and attributes for layout with dark sidebar
|
||||
AddBodyAttribute("data-kt-app-reset-transition", "true");
|
||||
|
||||
AddBodyAttribute("data-kt-app-layout", "dark-sidebar");
|
||||
AddBodyAttribute("data-kt-app-header-fixed", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-fixed", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-hoverable", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-push-header", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-push-toolbar", "true");
|
||||
AddBodyAttribute("data-kt-app-sidebar-push-footer", "true");
|
||||
AddBodyAttribute("data-kt-app-toolbar-enabled", "true");
|
||||
|
||||
AddBodyClass("app-default");
|
||||
|
||||
JsRuntime.InvokeVoidAsync("KTModalUpgradePlan.init");
|
||||
JsRuntime.InvokeVoidAsync("KTCreateApp.init");
|
||||
JsRuntime.InvokeVoidAsync("KTModalUserSearch.init");
|
||||
JsRuntime.InvokeVoidAsync("KTModalNewTarget.init");
|
||||
}
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
try
|
||||
{
|
||||
User = await IdentityService.Get();
|
||||
|
||||
await InvokeAsync(StateHasChanged);
|
||||
await Task.Delay(300);
|
||||
|
||||
await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-reset-transition");
|
||||
await JsRuntime.InvokeVoidAsync("document.body.removeAttribute", "data-kt-app-page-loading");
|
||||
await JsRuntime.InvokeVoidAsync("KTMenu.createInstances");
|
||||
await JsRuntime.InvokeVoidAsync("KTDrawer.createInstances");
|
||||
await JsRuntime.InvokeVoidAsync("createSnow");
|
||||
|
||||
await SessionService.Register();
|
||||
|
||||
NavigationManager.LocationChanged += (sender, args) => { SessionService.Refresh(); };
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
SessionService.Close();
|
||||
}
|
||||
|
||||
private void AddBodyAttribute(string attribute, string value)
|
||||
{
|
||||
JsRuntime.InvokeVoidAsync("document.body.setAttribute", attribute, value);
|
||||
}
|
||||
|
||||
private void AddBodyClass(string className)
|
||||
{
|
||||
JsRuntime.InvokeVoidAsync("document.body.classList.add", className);
|
||||
}
|
||||
}
|
78
Moonlight/Shared/Layouts/ThemeInit.razor
Normal file
78
Moonlight/Shared/Layouts/ThemeInit.razor
Normal file
|
@ -0,0 +1,78 @@
|
|||
@inherits LayoutComponentBase
|
||||
@inject IJSRuntime JS
|
||||
@inject NavigationManager NavigationManager
|
||||
|
||||
@Body
|
||||
|
||||
<script suppress-error="BL9992">
|
||||
window.emptyBody = function(){
|
||||
document.body.className = '';
|
||||
}
|
||||
</script>
|
||||
|
||||
@code
|
||||
{
|
||||
protected override void OnAfterRender(bool firstRender)
|
||||
{
|
||||
JS.InvokeVoidAsync("KTThemeMode.init");
|
||||
JS.InvokeVoidAsync("emptyBody");
|
||||
|
||||
if (firstRender)
|
||||
{
|
||||
JS.InvokeVoidAsync("scrollTo", 0, 0);
|
||||
JS.InvokeVoidAsync("KTDialer.init");
|
||||
JS.InvokeVoidAsync("KTDrawer.init");
|
||||
JS.InvokeVoidAsync("KTMenu.init");
|
||||
JS.InvokeVoidAsync("KTImageInput.init");
|
||||
JS.InvokeVoidAsync("KTPasswordMeter.init");
|
||||
JS.InvokeVoidAsync("KTScroll.init");
|
||||
JS.InvokeVoidAsync("KTScrolltop.init");
|
||||
JS.InvokeVoidAsync("KTSticky.init");
|
||||
JS.InvokeVoidAsync("KTSwapper.init");
|
||||
JS.InvokeVoidAsync("KTToggle.init");
|
||||
JS.InvokeVoidAsync("KTMenu.updateByLinkAttribute", $"/{NavigationManager.ToBaseRelativePath(NavigationManager.Uri)}");
|
||||
}
|
||||
|
||||
JS.InvokeVoidAsync("KTLayoutSearch.init");
|
||||
JS.InvokeVoidAsync("KTAppSidebar.init");
|
||||
}
|
||||
|
||||
|
||||
protected override void OnInitialized()
|
||||
{
|
||||
NavigationManager.LocationChanged += OnLocationChanged;
|
||||
}
|
||||
|
||||
private async void OnLocationChanged(object sender, LocationChangedEventArgs args)
|
||||
{
|
||||
await InvokeJsSave("scrollTo", 0, 0);
|
||||
await InvokeJsSave("KTDrawer.createInstances");
|
||||
await InvokeJsSave("KTMenu.createInstances");
|
||||
await InvokeJsSave("KTImageInput.createInstances");
|
||||
await InvokeJsSave("KTPasswordMeter.createInstances");
|
||||
await InvokeJsSave("KTScroll.createInstances");
|
||||
await InvokeJsSave("KTScrolltop.createInstances");
|
||||
await InvokeJsSave("KTSticky.createInstances");
|
||||
await InvokeJsSave("KTSwapper.createInstances");
|
||||
await InvokeJsSave("KTToggle.createInstances");
|
||||
await InvokeJsSave("KTMenu.updateByLinkAttribute", $"/{NavigationManager.ToBaseRelativePath(args.Location)}");
|
||||
await InvokeJsSave("KTAppSidebar.init");
|
||||
}
|
||||
|
||||
private async Task InvokeJsSave(string method, params object[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
await JS.InvokeVoidAsync(method, args);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
NavigationManager.LocationChanged -= OnLocationChanged;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
@inherits LayoutComponentBase
|
||||
|
||||
<PageTitle>Moonlight</PageTitle>
|
||||
|
||||
<div class="page">
|
||||
<div class="sidebar">
|
||||
<NavMenu />
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<div class="top-row px-4">
|
||||
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
|
||||
</div>
|
||||
|
||||
<article class="content px-4">
|
||||
@Body
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
|
@ -1,70 +0,0 @@
|
|||
.page {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
background-color: #f7f7f7;
|
||||
border-bottom: 1px solid #d6d5d5;
|
||||
justify-content: flex-end;
|
||||
height: 3.5rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.top-row ::deep a, .top-row .btn-link {
|
||||
white-space: nowrap;
|
||||
margin-left: 1.5rem;
|
||||
}
|
||||
|
||||
.top-row a:first-child {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 640.98px) {
|
||||
.top-row:not(.auth) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.top-row.auth {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.top-row a, .top-row .btn-link {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.page {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.top-row {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.top-row, article {
|
||||
padding-left: 2rem !important;
|
||||
padding-right: 1.5rem !important;
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<div class="top-row ps-3 navbar navbar-dark">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="">Moonlight</a>
|
||||
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
|
||||
<nav class="flex-column">
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
||||
<span class="oi oi-home" aria-hidden="true"></span> Home
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="counter">
|
||||
<span class="oi oi-plus" aria-hidden="true"></span> Counter
|
||||
</NavLink>
|
||||
</div>
|
||||
<div class="nav-item px-3">
|
||||
<NavLink class="nav-link" href="fetchdata">
|
||||
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
|
||||
</NavLink>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@code {
|
||||
private bool collapseNavMenu = true;
|
||||
|
||||
private string? NavMenuCssClass => collapseNavMenu ? "collapse" : null;
|
||||
|
||||
private void ToggleNavMenu()
|
||||
{
|
||||
collapseNavMenu = !collapseNavMenu;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
.navbar-toggler {
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.top-row {
|
||||
height: 3.5rem;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.oi {
|
||||
width: 2rem;
|
||||
font-size: 1.1rem;
|
||||
vertical-align: text-top;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
font-size: 0.9rem;
|
||||
padding-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.nav-item:first-of-type {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
|
||||
.nav-item:last-of-type {
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a {
|
||||
color: #d7d7d7;
|
||||
border-radius: 4px;
|
||||
height: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 3rem;
|
||||
}
|
||||
|
||||
.nav-item ::deep a.active {
|
||||
background-color: rgba(255,255,255,0.25);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-item ::deep a:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media (min-width: 641px) {
|
||||
.navbar-toggler {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.collapse {
|
||||
/* Never collapse the sidebar for wide screens */
|
||||
display: block;
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<div class="alert alert-secondary mt-4">
|
||||
<span class="oi oi-pencil me-2" aria-hidden="true"></span>
|
||||
<strong>@Title</strong>
|
||||
|
||||
<span class="text-nowrap">
|
||||
Please take our
|
||||
<a target="_blank" class="font-weight-bold link-dark" href="https://go.microsoft.com/fwlink/?linkid=2149017">brief survey</a>
|
||||
</span>
|
||||
and tell us what you think.
|
||||
</div>
|
||||
|
||||
@code {
|
||||
// Demonstrates how a parent component can supply parameters
|
||||
[Parameter]
|
||||
public string? Title { get; set; }
|
||||
}
|
7
Moonlight/Shared/Views/Index.razor
Normal file
7
Moonlight/Shared/Views/Index.razor
Normal file
|
@ -0,0 +1,7 @@
|
|||
@page "/"
|
||||
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
x
|
||||
</div>
|
||||
</div>
|
|
@ -7,4 +7,3 @@
|
|||
@using Microsoft.AspNetCore.Components.Web.Virtualization
|
||||
@using Microsoft.JSInterop
|
||||
@using Moonlight
|
||||
@using Moonlight.Shared
|
||||
|
|
|
@ -15,38 +15,70 @@ build_property.GenerateRazorMetadataSourceChecksumAttributes =
|
|||
build_property.MSBuildProjectDirectory = C:\Users\marce\source\repos\MoonlightPublic\Moonlight\Moonlight
|
||||
build_property._RazorSourceGeneratorDebug =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/App.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = QXBwLnJhem9y
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/BlazorApp.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = Qmxhem9yQXBwLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Pages/Counter.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcQ291bnRlci5yYXpvcg==
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Alerts/BannedAlert.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcQWxlcnRzXEJhbm5lZEFsZXJ0LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Pages/FetchData.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcRmV0Y2hEYXRhLnJhem9y
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Alerts/DisabledAlert.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcQWxlcnRzXERpc2FibGVkQWxlcnQucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Pages/Index.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcSW5kZXgucmF6b3I=
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/ErrorBoundaries/ComponentErrorBoundary.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcRXJyb3JCb3VuZGFyaWVzXENvbXBvbmVudEVycm9yQm91bmRhcnkucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/SurveyPrompt.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFN1cnZleVByb21wdC5yYXpvcg==
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/ErrorBoundaries/GlobalErrorBoundary.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcRXJyb3JCb3VuZGFyaWVzXEdsb2JhbEVycm9yQm91bmRhcnkucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/ErrorBoundaries/PageErrorBoundary.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcRXJyb3JCb3VuZGFyaWVzXFBhZ2VFcnJvckJvdW5kYXJ5LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/Footer.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcRm9vdGVyLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/Navbar.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcTmF2YmFyLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/PageHeader.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcUGFnZUhlYWRlci5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/Sidebar.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcU2lkZWJhci5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/SidebarMenu.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcU2lkZWJhck1lbnUucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Components/Partials/ThemeSwitcher.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcUGFydGlhbHNcVGhlbWVTd2l0Y2hlci5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Layouts/MainLayout.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXExheW91dHNcTWFpbkxheW91dC5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Layouts/ThemeInit.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXExheW91dHNcVGhlbWVJbml0LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/Views/Index.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEluZGV4LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/_Imports.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = X0ltcG9ydHMucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/MainLayout.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXE1haW5MYXlvdXQucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope = b-0cy8r6qmkj
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Shared/NavMenu.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXE5hdk1lbnUucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope = b-h6mpglkmdc
|
||||
|
||||
[C:/Users/marce/source/repos/MoonlightPublic/Moonlight/Moonlight/Pages/Error.cshtml]
|
||||
build_metadata.AdditionalFiles.TargetPath = UGFnZXNcRXJyb3IuY3NodG1s
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -46,9 +46,95 @@
|
|||
"net6.0": {
|
||||
"targetAlias": "net6.0",
|
||||
"dependencies": {
|
||||
"BCrypt.Net-Next": {
|
||||
"target": "Package",
|
||||
"version": "[4.0.3, )"
|
||||
},
|
||||
"Ben.Demystifier": {
|
||||
"target": "Package",
|
||||
"version": "[0.4.1, )"
|
||||
},
|
||||
"Blazor.ContextMenu": {
|
||||
"target": "Package",
|
||||
"version": "[1.15.0, )"
|
||||
},
|
||||
"BlazorMonaco": {
|
||||
"target": "Package",
|
||||
"version": "[3.0.0, )"
|
||||
},
|
||||
"BlazorTable": {
|
||||
"target": "Package",
|
||||
"version": "[1.17.0, )"
|
||||
},
|
||||
"CurrieTechnologies.Razor.SweetAlert2": {
|
||||
"target": "Package",
|
||||
"version": "[5.4.0, )"
|
||||
},
|
||||
"Discord.Net": {
|
||||
"target": "Package",
|
||||
"version": "[3.9.0, )"
|
||||
},
|
||||
"GravatarSharp.Core": {
|
||||
"target": "Package",
|
||||
"version": "[0.9.0.2, )"
|
||||
},
|
||||
"JWT": {
|
||||
"target": "Package",
|
||||
"version": "[10.0.2, )"
|
||||
},
|
||||
"Logging.Net": {
|
||||
"target": "Package",
|
||||
"version": "[1.1.0, )"
|
||||
},
|
||||
"Microsoft.EntityFrameworkCore.Design": {
|
||||
"include": "Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive",
|
||||
"suppressParent": "All",
|
||||
"target": "Package",
|
||||
"version": "[7.0.3, )"
|
||||
},
|
||||
"Microsoft.VisualStudio.Azure.Containers.Tools.Targets": {
|
||||
"target": "Package",
|
||||
"version": "[1.15.1, )"
|
||||
},
|
||||
"MineStat": {
|
||||
"target": "Package",
|
||||
"version": "[3.1.1, )"
|
||||
},
|
||||
"Newtonsoft.Json": {
|
||||
"target": "Package",
|
||||
"version": "[13.0.3-beta1, )"
|
||||
},
|
||||
"Otp.NET": {
|
||||
"target": "Package",
|
||||
"version": "[1.3.0, )"
|
||||
},
|
||||
"Pomelo.EntityFrameworkCore.MySql": {
|
||||
"target": "Package",
|
||||
"version": "[7.0.0, )"
|
||||
},
|
||||
"PteroConsole.NET": {
|
||||
"target": "Package",
|
||||
"version": "[1.0.4, )"
|
||||
},
|
||||
"QRCoder": {
|
||||
"target": "Package",
|
||||
"version": "[1.4.3, )"
|
||||
},
|
||||
"RestSharp": {
|
||||
"target": "Package",
|
||||
"version": "[109.0.0-preview.1, )"
|
||||
},
|
||||
"UAParser": {
|
||||
"target": "Package",
|
||||
"version": "[3.1.47, )"
|
||||
},
|
||||
"XtermBlazor": {
|
||||
"target": "Package",
|
||||
"version": "[1.6.1, )"
|
||||
},
|
||||
"aaPanelSharp": {
|
||||
"target": "Package",
|
||||
"version": "[1.0.0, )"
|
||||
}
|
||||
},
|
||||
"imports": [
|
||||
|
|
|
@ -15,7 +15,14 @@
|
|||
<SourceRoot Include="C:\Program Files\dotnet\sdk\NuGetFallbackFolder\" />
|
||||
</ItemGroup>
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)xtermblazor\1.6.1\buildTransitive\XtermBlazor.props" Condition="Exists('$(NuGetPackageRoot)xtermblazor\1.6.1\buildTransitive\XtermBlazor.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.3\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore\7.0.3\buildTransitive\net6.0\Microsoft.EntityFrameworkCore.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.visualstudio.azure.containers.tools.targets\1.15.1\build\Microsoft.VisualStudio.Azure.Containers.Tools.Targets.props" Condition="Exists('$(NuGetPackageRoot)microsoft.visualstudio.azure.containers.tools.targets\1.15.1\build\Microsoft.VisualStudio.Azure.Containers.Tools.Targets.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.entityframeworkcore.design\7.0.3\build\net6.0\Microsoft.EntityFrameworkCore.Design.props" Condition="Exists('$(NuGetPackageRoot)microsoft.entityframeworkcore.design\7.0.3\build\net6.0\Microsoft.EntityFrameworkCore.Design.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)currietechnologies.razor.sweetalert2\5.4.0\buildTransitive\CurrieTechnologies.Razor.SweetAlert2.props" Condition="Exists('$(NuGetPackageRoot)currietechnologies.razor.sweetalert2\5.4.0\buildTransitive\CurrieTechnologies.Razor.SweetAlert2.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)blazortable\1.17.0\buildTransitive\BlazorTable.props" Condition="Exists('$(NuGetPackageRoot)blazortable\1.17.0\buildTransitive\BlazorTable.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)blazormonaco\3.0.0\buildTransitive\BlazorMonaco.props" Condition="Exists('$(NuGetPackageRoot)blazormonaco\3.0.0\buildTransitive\BlazorMonaco.props')" />
|
||||
<Import Project="$(NuGetPackageRoot)blazor.contextmenu\1.15.0\buildTransitive\Blazor.ContextMenu.props" Condition="Exists('$(NuGetPackageRoot)blazor.contextmenu\1.15.0\buildTransitive\Blazor.ContextMenu.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets Condition=" '$(PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets)' == '' ">C:\Users\marce\.nuget\packages\microsoft.visualstudio.azure.containers.tools.targets\1.15.1</PkgMicrosoft_VisualStudio_Azure_Containers_Tools_Targets>
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Condition=" '$(ExcludeRestorePackageImports)' != 'true' ">
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.extensions.logging.abstractions\7.0.0\buildTransitive\net6.0\Microsoft.Extensions.Logging.Abstractions.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.aspnetcore.components.analyzers\6.0.9\buildTransitive\netstandard2.0\Microsoft.AspNetCore.Components.Analyzers.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.aspnetcore.components.analyzers\6.0.9\buildTransitive\netstandard2.0\Microsoft.AspNetCore.Components.Analyzers.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)system.text.json\7.0.0\buildTransitive\net6.0\System.Text.Json.targets" Condition="Exists('$(NuGetPackageRoot)system.text.json\7.0.0\buildTransitive\net6.0\System.Text.Json.targets')" />
|
||||
<Import Project="$(NuGetPackageRoot)microsoft.visualstudio.azure.containers.tools.targets\1.15.1\build\Microsoft.VisualStudio.Azure.Containers.Tools.Targets.targets" Condition="Exists('$(NuGetPackageRoot)microsoft.visualstudio.azure.containers.tools.targets\1.15.1\build\Microsoft.VisualStudio.Azure.Containers.Tools.Targets.targets')" />
|
||||
</ImportGroup>
|
||||
</Project>
|
File diff suppressed because it is too large
Load diff
|
@ -1,10 +1,87 @@
|
|||
{
|
||||
"version": 2,
|
||||
"dgSpecHash": "yy/NjlE13jUBAfYW0Jby0Um0q1bacbuKsTzQSymbyV/SUAbvE/vTqe61sVtjo+aDJhhfe6IkK+vrTFEXlUUEoA==",
|
||||
"dgSpecHash": "kweG9cyheq0lvUg6tPkk+sPoY2pPlReL0QP5jHLJNWl9pUpDd+CJp7bLfFE9WjjPi9DegeiFh5tJQ1eO1r96RA==",
|
||||
"success": true,
|
||||
"projectFilePath": "C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj",
|
||||
"expectedPackageFiles": [
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.visualstudio.azure.containers.tools.targets\\1.15.1\\microsoft.visualstudio.azure.containers.tools.targets.1.15.1.nupkg.sha512"
|
||||
"C:\\Users\\marce\\.nuget\\packages\\aapanelsharp\\1.0.0\\aapanelsharp.1.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\bcrypt.net-next\\4.0.3\\bcrypt.net-next.4.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\ben.demystifier\\0.4.1\\ben.demystifier.0.4.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\blazor.contextmenu\\1.15.0\\blazor.contextmenu.1.15.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\blazormonaco\\3.0.0\\blazormonaco.3.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\blazortable\\1.17.0\\blazortable.1.17.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\currietechnologies.razor.sweetalert2\\5.4.0\\currietechnologies.razor.sweetalert2.5.4.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net\\3.9.0\\discord.net.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.commands\\3.9.0\\discord.net.commands.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.core\\3.9.0\\discord.net.core.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.interactions\\3.9.0\\discord.net.interactions.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.rest\\3.9.0\\discord.net.rest.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.webhook\\3.9.0\\discord.net.webhook.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\discord.net.websocket\\3.9.0\\discord.net.websocket.3.9.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\gravatarsharp.core\\0.9.0.2\\gravatarsharp.core.0.9.0.2.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\humanizer.core\\2.14.1\\humanizer.core.2.14.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\jwt\\10.0.2\\jwt.10.0.2.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\linqkit.core\\1.1.26\\linqkit.core.1.1.26.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\logging.net\\1.1.0\\logging.net.1.1.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\macross.json.extensions\\3.0.0\\macross.json.extensions.3.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.authorization\\6.0.9\\microsoft.aspnetcore.authorization.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.components\\6.0.9\\microsoft.aspnetcore.components.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.components.analyzers\\6.0.9\\microsoft.aspnetcore.components.analyzers.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.components.forms\\6.0.9\\microsoft.aspnetcore.components.forms.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.components.web\\6.0.9\\microsoft.aspnetcore.components.web.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.aspnetcore.metadata\\6.0.9\\microsoft.aspnetcore.metadata.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore\\7.0.3\\microsoft.entityframeworkcore.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore.abstractions\\7.0.3\\microsoft.entityframeworkcore.abstractions.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore.analyzers\\7.0.3\\microsoft.entityframeworkcore.analyzers.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore.design\\7.0.3\\microsoft.entityframeworkcore.design.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.entityframeworkcore.relational\\7.0.3\\microsoft.entityframeworkcore.relational.7.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.caching.abstractions\\7.0.0\\microsoft.extensions.caching.abstractions.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.caching.memory\\7.0.0\\microsoft.extensions.caching.memory.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.configuration.abstractions\\7.0.0\\microsoft.extensions.configuration.abstractions.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.dependencyinjection\\7.0.0\\microsoft.extensions.dependencyinjection.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.dependencyinjection.abstractions\\7.0.0\\microsoft.extensions.dependencyinjection.abstractions.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.dependencymodel\\7.0.0\\microsoft.extensions.dependencymodel.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.localization\\3.1.18\\microsoft.extensions.localization.3.1.18.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.localization.abstractions\\3.1.18\\microsoft.extensions.localization.abstractions.3.1.18.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.logging\\7.0.0\\microsoft.extensions.logging.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.logging.abstractions\\7.0.0\\microsoft.extensions.logging.abstractions.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.options\\7.0.0\\microsoft.extensions.options.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.extensions.primitives\\7.0.0\\microsoft.extensions.primitives.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.jsinterop\\6.0.9\\microsoft.jsinterop.6.0.9.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\microsoft.visualstudio.azure.containers.tools.targets\\1.15.1\\microsoft.visualstudio.azure.containers.tools.targets.1.15.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\minestat\\3.1.1\\minestat.3.1.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\mono.texttemplating\\2.2.1\\mono.texttemplating.2.2.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\mysqlconnector\\2.2.5\\mysqlconnector.2.2.5.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\newtonsoft.json\\13.0.3-beta1\\newtonsoft.json.13.0.3-beta1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\otp.net\\1.3.0\\otp.net.1.3.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\pomelo.entityframeworkcore.mysql\\7.0.0\\pomelo.entityframeworkcore.mysql.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\pteroconsole.net\\1.0.4\\pteroconsole.net.1.0.4.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\qrcoder\\1.4.3\\qrcoder.1.4.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\restsharp\\109.0.0-preview.1\\restsharp.109.0.0-preview.1.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.codedom\\4.4.0\\system.codedom.4.4.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.collections.immutable\\5.0.0\\system.collections.immutable.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.interactive.async\\5.0.0\\system.interactive.async.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.io.pipelines\\6.0.3\\system.io.pipelines.6.0.3.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.linq.async\\5.0.0\\system.linq.async.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.reactive\\5.0.0\\system.reactive.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.reflection.metadata\\5.0.0\\system.reflection.metadata.5.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.runtime.compilerservices.unsafe\\6.0.0\\system.runtime.compilerservices.unsafe.6.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.text.encodings.web\\7.0.0\\system.text.encodings.web.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.text.json\\7.0.0\\system.text.json.7.0.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\system.valuetuple\\4.5.0\\system.valuetuple.4.5.0.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\uaparser\\3.1.47\\uaparser.3.1.47.nupkg.sha512",
|
||||
"C:\\Users\\marce\\.nuget\\packages\\xtermblazor\\1.6.1\\xtermblazor.1.6.1.nupkg.sha512"
|
||||
],
|
||||
"logs": []
|
||||
"logs": [
|
||||
{
|
||||
"code": "NU1701",
|
||||
"level": "Warning",
|
||||
"warningLevel": 1,
|
||||
"message": "Package 'GravatarSharp.Core 0.9.0.2' was restored using '.NETFramework,Version=v4.6.1, .NETFramework,Version=v4.6.2, .NETFramework,Version=v4.7, .NETFramework,Version=v4.7.1, .NETFramework,Version=v4.7.2, .NETFramework,Version=v4.8' instead of the project target framework 'net6.0'. This package may not be fully compatible with your project.",
|
||||
"libraryId": "GravatarSharp.Core",
|
||||
"targetGraphs": [
|
||||
"net6.0"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1 +1 @@
|
|||
"restore":{"projectUniqueName":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj","projectName":"Moonlight","projectPath":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj","outputPath":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages","C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"],"originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"C:\\Users\\marce\\source\\repos\\Logging.Net\\LoggingNet\\LoggingNet\\bin\\Release\\net5.0\\newpublish":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"Microsoft.VisualStudio.Azure.Containers.Tools.Targets":{"target":"Package","version":"[1.15.1, )"}},"imports":["net461","net462","net47","net471","net472","net48"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.AspNetCore.App":{"privateAssets":"none"},"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\6.0.300\\RuntimeIdentifierGraph.json"}}
|
||||
"restore":{"projectUniqueName":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj","projectName":"Moonlight","projectPath":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\Moonlight.csproj","outputPath":"C:\\Users\\marce\\source\\repos\\MoonlightPublic\\Moonlight\\Moonlight\\obj\\","projectStyle":"PackageReference","fallbackFolders":["C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages","C:\\Program Files\\dotnet\\sdk\\NuGetFallbackFolder"],"originalTargetFrameworks":["net6.0"],"sources":{"C:\\Program Files (x86)\\Microsoft SDKs\\NuGetPackages\\":{},"C:\\Users\\marce\\source\\repos\\Logging.Net\\LoggingNet\\LoggingNet\\bin\\Release\\net5.0\\newpublish":{},"https://api.nuget.org/v3/index.json":{}},"frameworks":{"net6.0":{"targetAlias":"net6.0","projectReferences":{}}},"warningProperties":{"warnAsError":["NU1605"]}}"frameworks":{"net6.0":{"targetAlias":"net6.0","dependencies":{"BCrypt.Net-Next":{"target":"Package","version":"[4.0.3, )"},"Ben.Demystifier":{"target":"Package","version":"[0.4.1, )"},"Blazor.ContextMenu":{"target":"Package","version":"[1.15.0, )"},"BlazorMonaco":{"target":"Package","version":"[3.0.0, )"},"BlazorTable":{"target":"Package","version":"[1.17.0, )"},"CurrieTechnologies.Razor.SweetAlert2":{"target":"Package","version":"[5.4.0, )"},"Discord.Net":{"target":"Package","version":"[3.9.0, )"},"GravatarSharp.Core":{"target":"Package","version":"[0.9.0.2, )"},"JWT":{"target":"Package","version":"[10.0.2, )"},"Logging.Net":{"target":"Package","version":"[1.1.0, )"},"Microsoft.EntityFrameworkCore.Design":{"include":"Runtime, Build, Native, ContentFiles, Analyzers, BuildTransitive","suppressParent":"All","target":"Package","version":"[7.0.3, )"},"Microsoft.VisualStudio.Azure.Containers.Tools.Targets":{"target":"Package","version":"[1.15.1, )"},"MineStat":{"target":"Package","version":"[3.1.1, )"},"Newtonsoft.Json":{"target":"Package","version":"[13.0.3-beta1, )"},"Otp.NET":{"target":"Package","version":"[1.3.0, )"},"Pomelo.EntityFrameworkCore.MySql":{"target":"Package","version":"[7.0.0, )"},"PteroConsole.NET":{"target":"Package","version":"[1.0.4, )"},"QRCoder":{"target":"Package","version":"[1.4.3, )"},"RestSharp":{"target":"Package","version":"[109.0.0-preview.1, )"},"UAParser":{"target":"Package","version":"[3.1.47, )"},"XtermBlazor":{"target":"Package","version":"[1.6.1, )"},"aaPanelSharp":{"target":"Package","version":"[1.0.0, )"}},"imports":["net461","net462","net47","net471","net472","net48"],"assetTargetFallback":true,"warn":true,"frameworkReferences":{"Microsoft.AspNetCore.App":{"privateAssets":"none"},"Microsoft.NETCore.App":{"privateAssets":"all"}},"runtimeIdentifierGraphPath":"C:\\Program Files\\dotnet\\sdk\\6.0.300\\RuntimeIdentifierGraph.json"}}
|
67
Moonlight/resources/lang/en_us.json
Normal file
67
Moonlight/resources/lang/en_us.json
Normal file
|
@ -0,0 +1,67 @@
|
|||
{
|
||||
"Crashes": {
|
||||
"Component": {
|
||||
"Title": "Ooops. Something went wrong",
|
||||
"Details": "This component has crashed"
|
||||
},
|
||||
"Page": {
|
||||
"Title": "Ooops. Something went wrong",
|
||||
"Details": "This site has crashed"
|
||||
},
|
||||
"Global": {
|
||||
"Title": "Ooops. Something went wrong",
|
||||
"Details": "Your moonlight client has crashed"
|
||||
}
|
||||
},
|
||||
"Footer": {
|
||||
"AboutUs": "About us",
|
||||
"Imprint": "Imprint",
|
||||
"Privacy": "Privacy"
|
||||
},
|
||||
"Alerts": {
|
||||
"Banned": {
|
||||
"Title": "Your account is banned from moonlight",
|
||||
"Details": "Your data will be deleted shortly. For more information contact support"
|
||||
},
|
||||
"Disabled": {
|
||||
"Title": "Your account is temporary banned from moonlight",
|
||||
"Details": "Your data is is still saved but the access to it is not possible at this time. For more information contact support"
|
||||
}
|
||||
},
|
||||
"Navbar": {
|
||||
"Account": {
|
||||
"Settings": "Account settings"
|
||||
},
|
||||
"Logout": "Logout"
|
||||
},
|
||||
"Sidebar": {
|
||||
"Footer": {
|
||||
"OpenSupport": "Open support"
|
||||
},
|
||||
"Menu": {
|
||||
"Login": "Login",
|
||||
"Register": "Register",
|
||||
"Dashboard": "Dashboard",
|
||||
"Order": "Order",
|
||||
"Website": "Website",
|
||||
"Database": "Database",
|
||||
"Domain": "Domain",
|
||||
"Servers": "Servers",
|
||||
"Websites": "Websites",
|
||||
"Databases": "Databases",
|
||||
"Domains": "Domains",
|
||||
"Changelog": "Changelog",
|
||||
"Admin": "Admin",
|
||||
"System": "System",
|
||||
"Overview": "Overview",
|
||||
"Manager": "Manager",
|
||||
"Cleanup": "Cleanup",
|
||||
"Nodes": "Nodes",
|
||||
"Images": "Images",
|
||||
"AaPanel": "AaPanel",
|
||||
"Users": "Users",
|
||||
"Support": "Support",
|
||||
"Statistics": "Statistics"
|
||||
}
|
||||
}
|
||||
}
|
14
Moonlight/resources/public/images/logo.svg
Normal file
14
Moonlight/resources/public/images/logo.svg
Normal file
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="256px" height="301px" viewBox="0 0 256 301" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||
<defs>
|
||||
<linearGradient x1="2.17771739%" y1="34.7938955%" x2="92.7221942%" y2="91.3419405%" id="linearGradient-1">
|
||||
<stop stop-color="#41A7EF" offset="0%"></stop>
|
||||
<stop stop-color="#813DDE" offset="54.2186236%"></stop>
|
||||
<stop stop-color="#8F2EE2" offset="74.4988788%"></stop>
|
||||
<stop stop-color="#A11CE6" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g>
|
||||
<path d="M124.183681,101.699 C124.183681,66.515 136.256681,34.152 156.486681,8.525 C159.197681,5.092 156.787681,0.069 152.412681,0.012 C151.775681,0.004 151.136681,0 150.497681,0 C67.6206813,0 0.390681343,66.99 0.00168134279,149.775 C-0.386318657,232.369 66.4286813,300.195 149.019681,300.988 C189.884681,301.381 227.036681,285.484 254.376681,259.395 C257.519681,256.396 255.841681,251.082 251.548681,250.42 C179.413681,239.291 124.183681,176.949 124.183681,101.699" fill="url(#linearGradient-1)"></path>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Moonlight/resources/public/images/logolong.png
Normal file
BIN
Moonlight/resources/public/images/logolong.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
58
Moonlight/wwwroot/assets/css/blazor.css
Normal file
58
Moonlight/wwwroot/assets/css/blazor.css
Normal file
|
@ -0,0 +1,58 @@
|
|||
.my-reconnect-modal {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.my-reconnect-modal > div {
|
||||
position: fixed;
|
||||
inset: 0px;
|
||||
z-index: 1050;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
transition: visibility 0s linear 500ms;
|
||||
backdrop-filter: blur(20px);
|
||||
background-color: #0008;
|
||||
}
|
||||
|
||||
.components-reconnect-hide > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-show > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-show > .show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-reconnect-failed > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-failed > .failed {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-reconnect-rejected > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-rejected > .rejected {
|
||||
display: block;
|
||||
}
|
||||
.components-reconnect-hide > div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.components-reconnect-show {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-reconnect-failed {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.components-reconnect-rejected {
|
||||
display: block;
|
||||
}
|
1
Moonlight/wwwroot/assets/css/boxicons.min.css
vendored
Normal file
1
Moonlight/wwwroot/assets/css/boxicons.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
38
Moonlight/wwwroot/assets/css/flashbang.css
Normal file
38
Moonlight/wwwroot/assets/css/flashbang.css
Normal file
|
@ -0,0 +1,38 @@
|
|||
@keyframes flashbang {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
1% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
2% {
|
||||
opacity: 1;
|
||||
}
|
||||
45% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.8;
|
||||
}
|
||||
55% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
90% {
|
||||
opacity: 0.3;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.flashbanglight {
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
opacity: 1;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
border-radius: 100%;
|
||||
background: transparent;
|
||||
z-index: 999;
|
||||
color: gold;
|
||||
}
|
9
Moonlight/wwwroot/assets/css/invisiblea.css
Normal file
9
Moonlight/wwwroot/assets/css/invisiblea.css
Normal file
|
@ -0,0 +1,9 @@
|
|||
.invisible-a {
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.invisible-a:hover {
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
}
|
9
Moonlight/wwwroot/assets/css/snow.css
Normal file
9
Moonlight/wwwroot/assets/css/snow.css
Normal file
|
@ -0,0 +1,9 @@
|
|||
.snow-canvas {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
}
|
47684
Moonlight/wwwroot/assets/css/style.bundle.css
Normal file
47684
Moonlight/wwwroot/assets/css/style.bundle.css
Normal file
File diff suppressed because it is too large
Load diff
BIN
Moonlight/wwwroot/assets/fonts/boxicons.eot
Normal file
BIN
Moonlight/wwwroot/assets/fonts/boxicons.eot
Normal file
Binary file not shown.
1653
Moonlight/wwwroot/assets/fonts/boxicons.svg
Normal file
1653
Moonlight/wwwroot/assets/fonts/boxicons.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 1.2 MiB |
BIN
Moonlight/wwwroot/assets/fonts/boxicons.ttf
Normal file
BIN
Moonlight/wwwroot/assets/fonts/boxicons.ttf
Normal file
Binary file not shown.
BIN
Moonlight/wwwroot/assets/fonts/boxicons.woff
Normal file
BIN
Moonlight/wwwroot/assets/fonts/boxicons.woff
Normal file
Binary file not shown.
BIN
Moonlight/wwwroot/assets/fonts/boxicons.woff2
Normal file
BIN
Moonlight/wwwroot/assets/fonts/boxicons.woff2
Normal file
Binary file not shown.
68
Moonlight/wwwroot/assets/js/alertUtils.js
Normal file
68
Moonlight/wwwroot/assets/js/alertUtils.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
window.showAlertInfo = function (title, description)
|
||||
{
|
||||
Swal.fire(
|
||||
title,
|
||||
description,
|
||||
'info'
|
||||
)
|
||||
}
|
||||
|
||||
window.showAlertSuccess = function (title, description)
|
||||
{
|
||||
Swal.fire(
|
||||
title,
|
||||
description,
|
||||
'success'
|
||||
)
|
||||
}
|
||||
|
||||
window.showAlertWarning = function (title, description)
|
||||
{
|
||||
Swal.fire(
|
||||
title,
|
||||
description,
|
||||
'warning'
|
||||
)
|
||||
}
|
||||
|
||||
window.showAlertError = function (title, description)
|
||||
{
|
||||
Swal.fire(
|
||||
title,
|
||||
description,
|
||||
'error'
|
||||
)
|
||||
}
|
||||
|
||||
window.showAlertYesNo = function (title, yesText, noText)
|
||||
{
|
||||
return Swal.fire({
|
||||
title: title,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: yesText,
|
||||
denyButtonText: noText,
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
return true;
|
||||
} else if (result.isDenied) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
window.showAlertText = function (title, description) {
|
||||
const {value: text} = Swal.fire({
|
||||
title: title,
|
||||
input: 'text',
|
||||
inputLabel: description,
|
||||
inputValue: "",
|
||||
showCancelButton: false,
|
||||
inputValidator: (value) => {
|
||||
if (!value) {
|
||||
return 'Es muss ein Wert angegeben werden'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return text;
|
||||
}
|
32
Moonlight/wwwroot/assets/js/clipboard.js
Normal file
32
Moonlight/wwwroot/assets/js/clipboard.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
function fallbackCopyTextToClipboard(text) {
|
||||
var textArea = document.createElement("textarea");
|
||||
textArea.value = text;
|
||||
|
||||
// Avoid scrolling to bottom
|
||||
textArea.style.top = "0";
|
||||
textArea.style.left = "0";
|
||||
textArea.style.position = "fixed";
|
||||
|
||||
document.body.appendChild(textArea);
|
||||
textArea.focus();
|
||||
textArea.select();
|
||||
|
||||
try {
|
||||
var successful = document.execCommand('copy');
|
||||
var msg = successful ? 'successful' : 'unsuccessful';
|
||||
} catch (err) {
|
||||
console.error('Fallback: Oops, unable to copy', err);
|
||||
}
|
||||
|
||||
document.body.removeChild(textArea);
|
||||
}
|
||||
function copyTextToClipboard(text) {
|
||||
if (!navigator.clipboard) {
|
||||
fallbackCopyTextToClipboard(text);
|
||||
return;
|
||||
}
|
||||
navigator.clipboard.writeText(text).then(function() {
|
||||
}, function(err) {
|
||||
console.error('Async: Could not copy text: ', err);
|
||||
});
|
||||
}
|
143
Moonlight/wwwroot/assets/js/consoleUtils.js
Normal file
143
Moonlight/wwwroot/assets/js/consoleUtils.js
Normal file
|
@ -0,0 +1,143 @@
|
|||
window.initConsolePlugins = function () {
|
||||
window.XtermBlazor.registerAddon("xterm-addon-fit", new window.FitAddon.FitAddon());
|
||||
|
||||
addEventListener('resize', (event) => {
|
||||
//XtermBlazor.invokeAddonFunction()
|
||||
});
|
||||
};
|
||||
|
||||
window.initGraphs = function () {
|
||||
|
||||
};
|
||||
|
||||
window.initCpu = function () {
|
||||
var element = document.getElementById('cpuchart');
|
||||
|
||||
var height = parseInt(KTUtil.css(element, 'height'));
|
||||
var labelColor = KTUtil.getCssVariableValue('--kt-gray-500');
|
||||
var borderColor = KTUtil.getCssVariableValue('--kt-gray-200');
|
||||
var baseColor = KTUtil.getCssVariableValue('--kt-info');
|
||||
var lightColor = KTUtil.getCssVariableValue('--kt-info-light');
|
||||
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
var options = {
|
||||
series: [{
|
||||
name: 'CPU Auslastung',
|
||||
data: [0, 0, 0, 0, 0, 0, 0]
|
||||
}],
|
||||
chart: {
|
||||
fontFamily: 'inherit',
|
||||
type: 'area',
|
||||
height: height,
|
||||
toolbar: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
plotOptions: {},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: false
|
||||
},
|
||||
fill: {
|
||||
type: 'solid',
|
||||
opacity: 1
|
||||
},
|
||||
stroke: {
|
||||
curve: 'smooth',
|
||||
show: true,
|
||||
width: 3,
|
||||
colors: [baseColor]
|
||||
},
|
||||
xaxis: {
|
||||
categories: [],
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false
|
||||
},
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '12px'
|
||||
}
|
||||
},
|
||||
crosshairs: {
|
||||
position: 'front',
|
||||
stroke: {
|
||||
color: baseColor,
|
||||
width: 1,
|
||||
dashArray: 3
|
||||
}
|
||||
},
|
||||
tooltip: {
|
||||
enabled: false,
|
||||
formatter: undefined,
|
||||
offsetY: 0,
|
||||
style: {
|
||||
fontSize: '12px'
|
||||
}
|
||||
}
|
||||
},
|
||||
yaxis: {
|
||||
labels: {
|
||||
style: {
|
||||
colors: labelColor,
|
||||
fontSize: '12px'
|
||||
}
|
||||
}
|
||||
},
|
||||
states: {
|
||||
normal: {
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
hover: {
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
active: {
|
||||
allowMultipleDataPointsSelection: false,
|
||||
filter: {
|
||||
type: 'none',
|
||||
value: 0
|
||||
}
|
||||
}
|
||||
},
|
||||
colors: [lightColor],
|
||||
grid: {
|
||||
borderColor: borderColor,
|
||||
strokeDashArray: 4,
|
||||
yaxis: {
|
||||
lines: {
|
||||
show: true
|
||||
}
|
||||
}
|
||||
},
|
||||
markers: {
|
||||
strokeColor: baseColor,
|
||||
strokeWidth: 3
|
||||
}
|
||||
};
|
||||
|
||||
var chart = new ApexCharts(element, options);
|
||||
chart.render();
|
||||
|
||||
window.console.cpuchart = chart;
|
||||
};
|
||||
|
||||
window.updateCpu = function (value) {
|
||||
window.console.cpuchart.appendSeries({
|
||||
name: 'CPU Auslastung',
|
||||
data: value
|
||||
});
|
||||
};
|
26
Moonlight/wwwroot/assets/js/cookieUtils.js
Normal file
26
Moonlight/wwwroot/assets/js/cookieUtils.js
Normal file
|
@ -0,0 +1,26 @@
|
|||
window.setCookie = function (key, value, days) {
|
||||
const d = new Date();
|
||||
d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
|
||||
let expires = "expires=" + d.toUTCString();
|
||||
document.cookie = key + "=" + value + ";" + expires + ";path=/";
|
||||
}
|
||||
|
||||
window.deleteCookie = function (key) {
|
||||
window.setCookie(key, "", 0);
|
||||
}
|
||||
|
||||
window.getCookie = function (cname) {
|
||||
let name = cname + "=";
|
||||
let decodedCookie = decodeURIComponent(document.cookie);
|
||||
let ca = decodedCookie.split(';');
|
||||
for (let i = 0; i < ca.length; i++) {
|
||||
let c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substring(1);
|
||||
}
|
||||
if (c.indexOf(name) == 0) {
|
||||
return c.substring(name.length, c.length);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
12
Moonlight/wwwroot/assets/js/flashbang.js
Normal file
12
Moonlight/wwwroot/assets/js/flashbang.js
Normal file
|
@ -0,0 +1,12 @@
|
|||
function flashbang() {
|
||||
const light = document.getElementById("flashbang");
|
||||
light.style.boxShadow = "0 0 10000px 10000px white, 0 0 250px 10px #FFFFFF";
|
||||
light.style.animation = "flashbang 5s linear forwards";
|
||||
light.onanimationend = clearFlashbang;
|
||||
}
|
||||
|
||||
function clearFlashbang() {
|
||||
const light = document.getElementById("flashbang");
|
||||
light.style.animation = "";
|
||||
light.style.opacity = "0";
|
||||
}
|
51
Moonlight/wwwroot/assets/js/loggingUtils.js
Normal file
51
Moonlight/wwwroot/assets/js/loggingUtils.js
Normal file
|
@ -0,0 +1,51 @@
|
|||
window.logInfo = function (prefix, message)
|
||||
{
|
||||
console.log(
|
||||
'%c[%cINFO%c] [%c' + prefix + '%c] %c' + message,
|
||||
'color: white', // [
|
||||
'color: aqua', // INFO
|
||||
'color: white', // ]
|
||||
'color: purple', // {prefix}
|
||||
'color: white', // ]
|
||||
'color: lightgray' // {message}
|
||||
);
|
||||
};
|
||||
|
||||
window.logWarn = function (prefix, message)
|
||||
{
|
||||
console.log(
|
||||
'%c[%cWARN%c] [%c' + prefix + '%c] %c' + message,
|
||||
'color: white', // [
|
||||
'color: orange', // WARN
|
||||
'color: white', // ]
|
||||
'color: purple', // {prefix}
|
||||
'color: white', // ]
|
||||
'color: lightgray' // {message}
|
||||
);
|
||||
};
|
||||
|
||||
window.logError = function (prefix, message)
|
||||
{
|
||||
console.log(
|
||||
'%c[%cERROR%c] [%c' + prefix + '%c] %c' + message,
|
||||
'color: white', // [
|
||||
'color: red', // ERROR
|
||||
'color: white', // ]
|
||||
'color: purple', // {prefix}
|
||||
'color: white', // ]
|
||||
'color: lightgray' // {message}
|
||||
);
|
||||
};
|
||||
|
||||
window.logDebug = function (prefix, message)
|
||||
{
|
||||
console.log(
|
||||
'%c[%cDEBUG%c] [%c' + prefix + '%c] %c' + message,
|
||||
'color: white', // [
|
||||
'color: green', // DEBUG
|
||||
'color: white', // ]
|
||||
'color: purple', // {prefix}
|
||||
'color: white', // ]
|
||||
'color: lightgray' // {message}
|
||||
);
|
||||
};
|
1
Moonlight/wwwroot/assets/js/monaco.js
Normal file
1
Moonlight/wwwroot/assets/js/monaco.js
Normal file
|
@ -0,0 +1 @@
|
|||
require.config({ paths: { 'vs': '_content/BlazorMonaco/lib/monaco-editor/min/vs' } });
|
9
Moonlight/wwwroot/assets/js/recaptcha.js
Normal file
9
Moonlight/wwwroot/assets/js/recaptcha.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
window.recaptcha = new Object();
|
||||
window.recaptcha.render = function (id, sitekey, page)
|
||||
{
|
||||
return grecaptcha.render(id, {
|
||||
'sitekey': sitekey,
|
||||
'callback': (response) => { page.invokeMethodAsync('CallbackOnSuccess', response); },
|
||||
'expired-callback': () => { page.invokeMethodAsync('CallbackOnExpired'); }
|
||||
});
|
||||
}
|
7832
Moonlight/wwwroot/assets/js/scripts.bundle.js
Normal file
7832
Moonlight/wwwroot/assets/js/scripts.bundle.js
Normal file
File diff suppressed because it is too large
Load diff
118
Moonlight/wwwroot/assets/js/snow.js
Normal file
118
Moonlight/wwwroot/assets/js/snow.js
Normal file
|
@ -0,0 +1,118 @@
|
|||
window.createSnow = function () {
|
||||
(function () {
|
||||
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
|
||||
function (callback) {
|
||||
window.setTimeout(callback, 1000 / 60);
|
||||
};
|
||||
window.requestAnimationFrame = requestAnimationFrame;
|
||||
})();
|
||||
|
||||
|
||||
var flakes = [],
|
||||
canvas = document.getElementById("snow"),
|
||||
ctx = canvas.getContext("2d"),
|
||||
flakeCount = 200,
|
||||
mX = -100,
|
||||
mY = -100
|
||||
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
|
||||
function snow() {
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
|
||||
for (var i = 0; i < flakeCount; i++) {
|
||||
var flake = flakes[i],
|
||||
x = mX,
|
||||
y = mY,
|
||||
minDist = 150,
|
||||
x2 = flake.x,
|
||||
y2 = flake.y;
|
||||
|
||||
var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
|
||||
dx = x2 - x,
|
||||
dy = y2 - y;
|
||||
|
||||
if (dist < minDist) {
|
||||
var force = minDist / (dist * dist),
|
||||
xcomp = (x - x2) / dist,
|
||||
ycomp = (y - y2) / dist,
|
||||
deltaV = force / 2;
|
||||
|
||||
flake.velX -= deltaV * xcomp;
|
||||
flake.velY -= deltaV * ycomp;
|
||||
|
||||
} else {
|
||||
flake.velX *= .98;
|
||||
if (flake.velY <= flake.speed) {
|
||||
flake.velY = flake.speed
|
||||
}
|
||||
flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
|
||||
}
|
||||
|
||||
ctx.fillStyle = "rgba(255,255,255," + flake.opacity + ")";
|
||||
flake.y += flake.velY;
|
||||
flake.x += flake.velX;
|
||||
|
||||
if (flake.y >= canvas.height || flake.y <= 0) {
|
||||
reset(flake);
|
||||
}
|
||||
|
||||
|
||||
if (flake.x >= canvas.width || flake.x <= 0) {
|
||||
reset(flake);
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
requestAnimationFrame(snow);
|
||||
};
|
||||
|
||||
function reset(flake) {
|
||||
flake.x = Math.floor(Math.random() * canvas.width);
|
||||
flake.y = 0;
|
||||
flake.size = (Math.random() * 3) + 2;
|
||||
flake.speed = (Math.random() * 1) + 0.5;
|
||||
flake.velY = flake.speed;
|
||||
flake.velX = 0;
|
||||
flake.opacity = (Math.random() * 0.5) + 0.3;
|
||||
}
|
||||
|
||||
function init() {
|
||||
for (var i = 0; i < flakeCount; i++) {
|
||||
var x = Math.floor(Math.random() * canvas.width),
|
||||
y = Math.floor(Math.random() * canvas.height),
|
||||
size = (Math.random() * 3) + 2,
|
||||
speed = (Math.random() * 1) + 0.5,
|
||||
opacity = (Math.random() * 0.5) + 0.3;
|
||||
|
||||
flakes.push({
|
||||
speed: speed,
|
||||
velY: speed,
|
||||
velX: 0,
|
||||
x: x,
|
||||
y: y,
|
||||
size: size,
|
||||
stepSize: (Math.random()) / 30,
|
||||
step: 0,
|
||||
opacity: opacity
|
||||
});
|
||||
}
|
||||
|
||||
snow();
|
||||
};
|
||||
|
||||
canvas.addEventListener("mousemove", function (e) {
|
||||
mX = e.clientX,
|
||||
mY = e.clientY
|
||||
});
|
||||
|
||||
window.addEventListener("resize", function () {
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
})
|
||||
|
||||
init();
|
||||
}
|
14
Moonlight/wwwroot/assets/js/theme.js
Normal file
14
Moonlight/wwwroot/assets/js/theme.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
if (document.documentElement) {
|
||||
const defaultThemeMode = "dark";
|
||||
const name = document.body.getAttribute("data-kt-name");
|
||||
let themeMode = localStorage.getItem("kt_" + (name !== null ? name + "_" : "") + "theme_mode_value");
|
||||
|
||||
if (themeMode === null) {
|
||||
if (defaultThemeMode === "system") {
|
||||
themeMode = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
||||
} else {
|
||||
themeMode = defaultThemeMode;
|
||||
}
|
||||
}
|
||||
document.documentElement.setAttribute("data-theme", themeMode);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue