diff --git a/Moonlight.ApiServer.Runtime/Moonlight.ApiServer.Runtime.csproj b/Moonlight.ApiServer.Runtime/Moonlight.ApiServer.Runtime.csproj new file mode 100644 index 00000000..c9706e8e --- /dev/null +++ b/Moonlight.ApiServer.Runtime/Moonlight.ApiServer.Runtime.csproj @@ -0,0 +1,21 @@ + + + + net9.0 + enable + enable + True + + + + + + + + + + + + + + diff --git a/Moonlight.ApiServer.Runtime/PluginLoader.cs b/Moonlight.ApiServer.Runtime/PluginLoader.cs new file mode 100644 index 00000000..2d5fc003 --- /dev/null +++ b/Moonlight.ApiServer.Runtime/PluginLoader.cs @@ -0,0 +1,10 @@ +using MoonCore.PluginFramework; +using Moonlight.ApiServer.Plugins; + +namespace Moonlight.ApiServer.Runtime; + +[PluginLoader] +public partial class PluginLoader : IPluginStartup +{ + +} \ No newline at end of file diff --git a/Moonlight.ApiServer.Runtime/Program.cs b/Moonlight.ApiServer.Runtime/Program.cs new file mode 100644 index 00000000..619c343a --- /dev/null +++ b/Moonlight.ApiServer.Runtime/Program.cs @@ -0,0 +1,9 @@ +using Moonlight.ApiServer; +using Moonlight.ApiServer.Runtime; + +var startup = new Startup(); + +var pluginLoader = new PluginLoader(); +pluginLoader.Initialize(); + +await startup.Run(args, pluginLoader.Instances); \ No newline at end of file diff --git a/Moonlight.ApiServer.Runtime/Properties/launchSettings.json b/Moonlight.ApiServer.Runtime/Properties/launchSettings.json new file mode 100644 index 00000000..8c3160eb --- /dev/null +++ b/Moonlight.ApiServer.Runtime/Properties/launchSettings.json @@ -0,0 +1,29 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5165", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "HTTP_PROXY": "", + "HTTPS_PROXY": "" + }, + "hotReloadEnabled": true + }, + "WASM Debug": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5165", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development", + "HTTP_PROXY": "", + "HTTPS_PROXY": "" + }, + "hotReloadEnabled": true, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}" + } + } +} \ No newline at end of file diff --git a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/FilesController.cs b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/FilesController.cs index 32cc0346..fdec530c 100644 --- a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/FilesController.cs +++ b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/FilesController.cs @@ -16,14 +16,14 @@ namespace Moonlight.ApiServer.Http.Controllers.Admin.Sys; [Authorize(Policy = "permissions:admin.system.files")] public class FilesController : Controller { - private readonly string BaseDirectory = PathBuilder.Dir("storage"); + private readonly string BaseDirectory = "storage"; private readonly long ChunkSize = ByteConverter.FromMegaBytes(20).Bytes; [HttpGet("list")] public Task List([FromQuery] string path) { var safePath = SanitizePath(path); - var physicalPath = PathBuilder.Dir(BaseDirectory, safePath); + var physicalPath = Path.Combine(BaseDirectory, safePath); var entries = new List(); @@ -84,7 +84,7 @@ public class FilesController : Controller var positionToSkipTo = ChunkSize * chunkId; var safePath = SanitizePath(path); - var physicalPath = PathBuilder.File(BaseDirectory, safePath); + var physicalPath = Path.Combine(BaseDirectory, safePath); var baseDir = Path.GetDirectoryName(physicalPath); if (!string.IsNullOrEmpty(baseDir)) @@ -113,11 +113,11 @@ public class FilesController : Controller var oldSafePath = SanitizePath(oldPath); var newSafePath = SanitizePath(newPath); - var oldPhysicalDirPath = PathBuilder.Dir(BaseDirectory, oldSafePath); + var oldPhysicalDirPath = Path.Combine(BaseDirectory, oldSafePath); if (Directory.Exists(oldPhysicalDirPath)) { - var newPhysicalDirPath = PathBuilder.Dir(BaseDirectory, newSafePath); + var newPhysicalDirPath = Path.Combine(BaseDirectory, newSafePath); Directory.Move( oldPhysicalDirPath, @@ -126,8 +126,8 @@ public class FilesController : Controller } else { - var oldPhysicalFilePath = PathBuilder.File(BaseDirectory, oldSafePath); - var newPhysicalFilePath = PathBuilder.File(BaseDirectory, newSafePath); + var oldPhysicalFilePath = Path.Combine(BaseDirectory, oldSafePath); + var newPhysicalFilePath = Path.Combine(BaseDirectory, newSafePath); System.IO.File.Move( oldPhysicalFilePath, @@ -142,13 +142,13 @@ public class FilesController : Controller public Task Delete([FromQuery] string path) { var safePath = SanitizePath(path); - var physicalDirPath = PathBuilder.Dir(BaseDirectory, safePath); + var physicalDirPath = Path.Combine(BaseDirectory, safePath); if (Directory.Exists(physicalDirPath)) Directory.Delete(physicalDirPath, true); else { - var physicalFilePath = PathBuilder.File(BaseDirectory, safePath); + var physicalFilePath = Path.Combine(BaseDirectory, safePath); System.IO.File.Delete(physicalFilePath); } @@ -160,7 +160,7 @@ public class FilesController : Controller public Task CreateDirectory([FromQuery] string path) { var safePath = SanitizePath(path); - var physicalPath = PathBuilder.Dir(BaseDirectory, safePath); + var physicalPath = Path.Combine(BaseDirectory, safePath); Directory.CreateDirectory(physicalPath); return Task.CompletedTask; @@ -170,7 +170,7 @@ public class FilesController : Controller public async Task Download([FromQuery] string path) { var safePath = SanitizePath(path); - var physicalPath = PathBuilder.File(BaseDirectory, safePath); + var physicalPath = Path.Combine(BaseDirectory, safePath); await using var fs = System.IO.File.Open(physicalPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); await fs.CopyToAsync(Response.Body); @@ -192,7 +192,7 @@ public class FilesController : Controller private async Task CompressTarGz(string path, string[] itemsToCompress) { var safePath = SanitizePath(path); - var destination = PathBuilder.File(BaseDirectory, safePath); + var destination = Path.Combine(BaseDirectory, safePath); await using var outStream = System.IO.File.Create(destination); await using var gzoStream = new GZipOutputStream(outStream); @@ -201,7 +201,7 @@ public class FilesController : Controller foreach (var itemName in itemsToCompress) { var safeFilePath = SanitizePath(itemName); - var filePath = PathBuilder.File(BaseDirectory, safeFilePath); + var filePath = Path.Combine(BaseDirectory, safeFilePath); var fi = new FileInfo(filePath); @@ -210,7 +210,7 @@ public class FilesController : Controller else { var safeDirePath = SanitizePath(itemName); - var dirPath = PathBuilder.Dir(BaseDirectory, safeDirePath); + var dirPath = Path.Combine(BaseDirectory, safeDirePath); await AddDirectoryToTarGz(tarStream, dirPath); } @@ -267,7 +267,7 @@ public class FilesController : Controller private async Task CompressZip(string path, string[] itemsToCompress) { var safePath = SanitizePath(path); - var destination = PathBuilder.File(BaseDirectory, safePath); + var destination = Path.Combine(BaseDirectory, safePath); await using var outStream = System.IO.File.Create(destination); await using var zipOutputStream = new ZipOutputStream(outStream); @@ -275,7 +275,7 @@ public class FilesController : Controller foreach (var itemName in itemsToCompress) { var safeFilePath = SanitizePath(itemName); - var filePath = PathBuilder.File(BaseDirectory, safeFilePath); + var filePath = Path.Combine(BaseDirectory, safeFilePath); var fi = new FileInfo(filePath); @@ -284,7 +284,7 @@ public class FilesController : Controller else { var safeDirePath = SanitizePath(itemName); - var dirPath = PathBuilder.Dir(BaseDirectory, safeDirePath); + var dirPath = Path.Combine(BaseDirectory, safeDirePath); await AddDirectoryToZip(zipOutputStream, dirPath); } @@ -350,7 +350,7 @@ public class FilesController : Controller var safeDestination = SanitizePath(destination); var safeArchivePath = SanitizePath(path); - var archivePath = PathBuilder.File(BaseDirectory, safeArchivePath); + var archivePath = Path.Combine(BaseDirectory, safeArchivePath); await using var fs = System.IO.File.Open(archivePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); await using var gzipInputStream = new GZipInputStream(fs); @@ -364,7 +364,7 @@ public class FilesController : Controller break; var safeFilePath = SanitizePath(entry.Name); - var fileDestination = PathBuilder.File(BaseDirectory, safeDestination, safeFilePath); + var fileDestination = Path.Combine(BaseDirectory, safeDestination, safeFilePath); var parentFolder = Path.GetDirectoryName(fileDestination); // Ensure parent directory exists, if it's not the base directory @@ -393,7 +393,7 @@ public class FilesController : Controller var safeDestination = SanitizePath(destination); var safeArchivePath = SanitizePath(path); - var archivePath = PathBuilder.File(BaseDirectory, safeArchivePath); + var archivePath = Path.Combine(BaseDirectory, safeArchivePath); await using var fs = System.IO.File.Open(archivePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); await using var zipInputStream = new ZipInputStream(fs); @@ -409,7 +409,7 @@ public class FilesController : Controller continue; var safeFilePath = SanitizePath(entry.Name); - var fileDestination = PathBuilder.File(BaseDirectory, safeDestination, safeFilePath); + var fileDestination = Path.Combine(BaseDirectory, safeDestination, safeFilePath); var parentFolder = Path.GetDirectoryName(fileDestination); // Ensure parent directory exists, if it's not the base directory diff --git a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/ThemeController.cs b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/ThemeController.cs index aca9704f..1ec69246 100644 --- a/Moonlight.ApiServer/Http/Controllers/Admin/Sys/ThemeController.cs +++ b/Moonlight.ApiServer/Http/Controllers/Admin/Sys/ThemeController.cs @@ -14,7 +14,7 @@ public class ThemeController : Controller [Authorize(Policy = "permissions:admin.system.theme.update")] public async Task Patch([FromBody] UpdateThemeRequest request) { - var themePath = PathBuilder.File("storage", "theme.json"); + var themePath = Path.Combine("storage", "theme.json"); await System.IO.File.WriteAllTextAsync( themePath, diff --git a/Moonlight.ApiServer/Http/Controllers/FrontendController.cs b/Moonlight.ApiServer/Http/Controllers/Frontend/FrontendController.cs similarity index 62% rename from Moonlight.ApiServer/Http/Controllers/FrontendController.cs rename to Moonlight.ApiServer/Http/Controllers/Frontend/FrontendController.cs index 721ab6a6..028971c6 100644 --- a/Moonlight.ApiServer/Http/Controllers/FrontendController.cs +++ b/Moonlight.ApiServer/Http/Controllers/Frontend/FrontendController.cs @@ -1,14 +1,12 @@ -using System.Text.Json; +using System.Text; using Microsoft.AspNetCore.Mvc; -using MoonCore.Exceptions; -using MoonCore.Helpers; -using Moonlight.ApiServer.Configuration; using Moonlight.ApiServer.Services; using Moonlight.Shared.Misc; -namespace Moonlight.ApiServer.Http.Controllers; +namespace Moonlight.ApiServer.Http.Controllers.Frontend; [ApiController] +[Route("/")] public class FrontendController : Controller { private readonly FrontendService FrontendService; @@ -21,4 +19,12 @@ public class FrontendController : Controller [HttpGet("frontend.json")] public async Task GetConfiguration() => await FrontendService.GetConfiguration(); + + [HttpGet] + public async Task Index() + { + var content = await FrontendService.GenerateIndexHtml(); + + return Results.Text(content, "text/html", Encoding.UTF8); + } } \ No newline at end of file diff --git a/Moonlight.ApiServer/Http/Controllers/Frontend/FrontendPage.razor b/Moonlight.ApiServer/Http/Controllers/Frontend/FrontendPage.razor new file mode 100644 index 00000000..277bed24 --- /dev/null +++ b/Moonlight.ApiServer/Http/Controllers/Frontend/FrontendPage.razor @@ -0,0 +1,51 @@ +@using Moonlight.Shared.Misc + + + + + + + @Configuration.Title + + + @foreach (var style in Configuration.Styles) + { + + } + + + + + + + +
+ +
+
+
+
+
+
+
+
+
+
+ +
+ +@foreach (var script in Configuration.Scripts) +{ + +} + + + + + + + +@code +{ + [Parameter] public FrontendConfiguration Configuration { get; set; } +} diff --git a/Moonlight.ApiServer/Http/Controllers/Swagger/SwaggerController.cs b/Moonlight.ApiServer/Http/Controllers/Swagger/SwaggerController.cs index 49e12005..5c8941fc 100644 --- a/Moonlight.ApiServer/Http/Controllers/Swagger/SwaggerController.cs +++ b/Moonlight.ApiServer/Http/Controllers/Swagger/SwaggerController.cs @@ -2,13 +2,11 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using MoonCore.Helpers; -using MoonCore.Services; using Moonlight.ApiServer.Configuration; using Moonlight.ApiServer.Models; namespace Moonlight.ApiServer.Http.Controllers.Swagger; -[AllowAnonymous] [Route("api/swagger")] public class SwaggerController : Controller { diff --git a/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs b/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs index 6f79c079..a125946c 100644 --- a/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs +++ b/Moonlight.ApiServer/Implementations/Startup/CoreStartup.cs @@ -4,6 +4,7 @@ using Moonlight.ApiServer.Database; using Moonlight.ApiServer.Implementations.Diagnose; using Moonlight.ApiServer.Implementations.Metrics; using Moonlight.ApiServer.Interfaces; +using Moonlight.ApiServer.Models; using Moonlight.ApiServer.Plugins; using Moonlight.ApiServer.Services; using OpenTelemetry.Metrics; @@ -11,7 +12,6 @@ using OpenTelemetry.Trace; namespace Moonlight.ApiServer.Implementations.Startup; -[PluginStartup] public class CoreStartup : IPluginStartup { public Task BuildApplication(IServiceProvider serviceProvider, IHostApplicationBuilder builder) @@ -81,20 +81,37 @@ public class CoreStartup : IPluginStartup #endregion + #region Client / Frontend + + if (configuration.Client.Enable) + { + builder.Services.AddSingleton(new FrontendConfigurationOption() + { + Scripts = + [ + "/_content/Moonlight.Client/js/moonlight.js", "/_content/Moonlight.Client/js/moonCore.js", + "/_content/Moonlight.Client/ace/ace.js" + ], + Styles = ["/css/style.min.css"] + }); + } + + #endregion + return Task.CompletedTask; } public Task ConfigureApplication(IServiceProvider serviceProvider, IApplicationBuilder app) { var configuration = serviceProvider.GetRequiredService(); - + #region Prometheus - if(configuration.Metrics.Enable) + if (configuration.Metrics.Enable) app.UseOpenTelemetryPrometheusScrapingEndpoint(); #endregion - + return Task.CompletedTask; } diff --git a/Moonlight.ApiServer/Implementations/UserAuthInvalidation.cs b/Moonlight.ApiServer/Implementations/UserAuthInvalidation.cs new file mode 100644 index 00000000..000dbb32 --- /dev/null +++ b/Moonlight.ApiServer/Implementations/UserAuthInvalidation.cs @@ -0,0 +1,62 @@ +using System.Security.Claims; +using Microsoft.EntityFrameworkCore; +using MoonCore.Extended.Abstractions; +using MoonCore.Extended.JwtInvalidation; +using Moonlight.ApiServer.Database.Entities; + +namespace Moonlight.ApiServer.Implementations; + +public class UserAuthInvalidation : IJwtInvalidateHandler +{ + private readonly DatabaseRepository UserRepository; + private readonly DatabaseRepository ApiKeyRepository; + + public UserAuthInvalidation( + DatabaseRepository userRepository, + DatabaseRepository apiKeyRepository + ) + { + UserRepository = userRepository; + ApiKeyRepository = apiKeyRepository; + } + + public async Task Handle(ClaimsPrincipal principal) + { + var userIdClaim = principal.FindFirstValue("userId"); + + if (!string.IsNullOrEmpty(userIdClaim)) + { + var userId = int.Parse(userIdClaim); + + var user = await UserRepository + .Get() + .FirstOrDefaultAsync(x => x.Id == userId); + + if (user == null) + return true; // User is deleted, invalidate session + + var iatStr = principal.FindFirstValue("iat")!; + var iat = DateTimeOffset.FromUnixTimeSeconds(long.Parse(iatStr)); + + // If the token has been issued before the token valid time, its expired, and we want to invalidate it + return user.TokenValidTimestamp > iat; + } + + var apiKeyIdClaim = principal.FindFirstValue("apiKeyId"); + + if (!string.IsNullOrEmpty(apiKeyIdClaim)) + { + var apiKeyId = int.Parse(apiKeyIdClaim); + + var apiKey = await ApiKeyRepository + .Get() + .FirstOrDefaultAsync(x => x.Id == apiKeyId); + + // If the api key exists, we don't want to invalidate the request. + // If it doesn't exist we want to invalidate the request + return apiKey == null; + } + + return true; + } +} \ No newline at end of file diff --git a/Moonlight.ApiServer/Moonlight.ApiServer.csproj b/Moonlight.ApiServer/Moonlight.ApiServer.csproj index 1da9f290..b84c8850 100644 --- a/Moonlight.ApiServer/Moonlight.ApiServer.csproj +++ b/Moonlight.ApiServer/Moonlight.ApiServer.csproj @@ -6,7 +6,6 @@ enable - @@ -30,13 +29,14 @@ true - - + + - - - - + + + + + diff --git a/Moonlight.ApiServer/Plugins/PluginStartupAttribute.cs b/Moonlight.ApiServer/Plugins/PluginStartupAttribute.cs deleted file mode 100644 index d38a0555..00000000 --- a/Moonlight.ApiServer/Plugins/PluginStartupAttribute.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Moonlight.ApiServer.Plugins; - -[AttributeUsage(AttributeTargets.Class)] -public class PluginStartupAttribute : Attribute -{ - -} \ No newline at end of file diff --git a/Moonlight.ApiServer/Services/FrontendService.cs b/Moonlight.ApiServer/Services/FrontendService.cs index cf478f82..0ae03fc5 100644 --- a/Moonlight.ApiServer/Services/FrontendService.cs +++ b/Moonlight.ApiServer/Services/FrontendService.cs @@ -6,6 +6,7 @@ using MoonCore.Attributes; using MoonCore.Exceptions; using MoonCore.Helpers; using Moonlight.ApiServer.Configuration; +using Moonlight.ApiServer.Http.Controllers.Frontend; using Moonlight.ApiServer.Models; using Moonlight.Shared.Misc; @@ -17,23 +18,26 @@ public class FrontendService private readonly AppConfiguration Configuration; private readonly IWebHostEnvironment WebHostEnvironment; private readonly IEnumerable ConfigurationOptions; + private readonly IServiceProvider ServiceProvider; public FrontendService( AppConfiguration configuration, IWebHostEnvironment webHostEnvironment, - IEnumerable configurationOptions + IEnumerable configurationOptions, + IServiceProvider serviceProvider ) { Configuration = configuration; WebHostEnvironment = webHostEnvironment; ConfigurationOptions = configurationOptions; + ServiceProvider = serviceProvider; } public async Task GetConfiguration() { var configuration = new FrontendConfiguration() { - Title = "Moonlight", + Title = "Moonlight", // TODO: CONFIG ApiUrl = Configuration.PublicUrl, HostEnvironment = "ApiServer" }; @@ -62,7 +66,20 @@ public class FrontendService return configuration; } - public async Task GenerateZip() + public async Task GenerateIndexHtml() // TODO: Cache + { + var configuration = await GetConfiguration(); + + return await ComponentHelper.RenderComponent( + ServiceProvider, + parameters => + { + parameters["Configuration"] = configuration; + } + ); + } + + public async Task GenerateZip() // TODO: Rework to be able to extract everything successfully { // We only allow the access to this function when we are actually hosting the frontend if (!Configuration.Client.Enable) diff --git a/Moonlight.ApiServer/Startup.cs b/Moonlight.ApiServer/Startup.cs index aac517d7..4cd04911 100644 --- a/Moonlight.ApiServer/Startup.cs +++ b/Moonlight.ApiServer/Startup.cs @@ -12,6 +12,7 @@ using MoonCore.Extended.Helpers; using MoonCore.Extended.JwtInvalidation; using MoonCore.Extensions; using MoonCore.Helpers; +using MoonCore.Logging; using MoonCore.Permissions; using Moonlight.ApiServer.Configuration; using Moonlight.ApiServer.Database; @@ -111,8 +112,7 @@ public class Startup private Task CreateStorage() { Directory.CreateDirectory("storage"); - Directory.CreateDirectory(PathBuilder.Dir("storage", "logs")); - Directory.CreateDirectory(PathBuilder.Dir("storage", "plugins")); + Directory.CreateDirectory(Path.Combine("storage", "logs")); return Task.CompletedTask; } @@ -142,7 +142,7 @@ public class Startup private Task UseBase() { WebApplication.UseRouting(); - WebApplication.UseApiExceptionHandler(); + WebApplication.UseExceptionHandler(); if (Configuration.Client.Enable) { @@ -161,7 +161,7 @@ public class Startup WebApplication.MapControllers(); if (Configuration.Client.Enable) - WebApplication.MapFallbackToFile("index.html"); + WebApplication.MapFallbackToController("Index", "Frontend"); return Task.CompletedTask; } @@ -194,7 +194,7 @@ public class Startup serviceCollection.AddLogging(builder => { builder.ClearProviders(); - builder.AddProviders(LoggerProviders); + builder.AddAnsiConsole(); }); PluginLoadServiceProvider = serviceCollection.BuildServiceProvider(); @@ -202,8 +202,6 @@ public class Startup // Collect startups var pluginStartups = new List(); - pluginStartups.Add(new CoreStartup()); - pluginStartups.AddRange(AdditionalPlugins); // Used by the development server // Do NOT remove the following comment, as its used to place the plugin startup register calls @@ -291,7 +289,7 @@ public class Startup var configurationBuilder = new ConfigurationBuilder(); // Ensure configuration file exists - var jsonFilePath = PathBuilder.File(Directory.GetCurrentDirectory(), "storage", "app.json"); + var jsonFilePath = Path.Combine(Directory.GetCurrentDirectory(), "storage", "app.json"); if (!File.Exists(jsonFilePath)) await File.WriteAllTextAsync(jsonFilePath, JsonSerializer.Serialize(new AppConfiguration())); @@ -336,18 +334,8 @@ public class Startup private Task SetupLogging() { - LoggerProviders = LoggerBuildHelper.BuildFromConfiguration(configuration => - { - configuration.Console.Enable = true; - configuration.Console.EnableAnsiMode = true; - configuration.FileLogging.Enable = true; - configuration.FileLogging.Path = PathBuilder.File("storage", "logs", "latest.log"); - configuration.FileLogging.EnableLogRotation = true; - configuration.FileLogging.RotateLogNameTemplate = PathBuilder.File("storage", "logs", "apiserver.{0}.log"); - }); - LoggerFactory = new LoggerFactory(); - LoggerFactory.AddProviders(LoggerProviders); + LoggerFactory.AddAnsiConsole(); Logger = LoggerFactory.CreateLogger(); @@ -358,30 +346,33 @@ public class Startup { // Configure application logging WebApplicationBuilder.Logging.ClearProviders(); - WebApplicationBuilder.Logging.AddProviders(LoggerProviders); + WebApplicationBuilder.Logging.AddAnsiConsole(); + WebApplicationBuilder.Logging.AddFile(Path.Combine("storage", "logs", "moonlight.log")); // Logging levels - var logConfigPath = PathBuilder.File("storage", "logConfig.json"); + var logConfigPath = Path.Combine("storage", "logConfig.json"); // Ensure logging config, add a default one is missing if (!File.Exists(logConfigPath)) { - var logLevels = new Dictionary + var defaultLogLevels = new Dictionary { { "Default", "Information" }, { "Microsoft.AspNetCore", "Warning" }, { "System.Net.Http.HttpClient", "Warning" } }; - var logLevelsJson = JsonSerializer.Serialize(logLevels); - var logConfig = "{\"LogLevel\":" + logLevelsJson + "}"; - await File.WriteAllTextAsync(logConfigPath, logConfig); + var logLevelsJson = JsonSerializer.Serialize(defaultLogLevels); + await File.WriteAllTextAsync(logConfigPath, logLevelsJson); } // Add logging configuration - WebApplicationBuilder.Logging.AddConfiguration( + var logLevels = JsonSerializer.Deserialize>( await File.ReadAllTextAsync(logConfigPath) - ); + )!; + + foreach (var level in logLevels) + WebApplicationBuilder.Logging.AddFilter(level.Key, Enum.Parse(level.Value)); // Mute exception handler middleware // https://github.com/dotnet/aspnetcore/issues/19740 @@ -406,7 +397,6 @@ public class Startup WebApplicationBuilder.Services.AddServiceCollectionAccessor(); WebApplicationBuilder.Services.AddScoped(typeof(DatabaseRepository<>)); - WebApplicationBuilder.Services.AddScoped(typeof(CrudHelper<,>)); return Task.CompletedTask; } @@ -442,43 +432,9 @@ public class Startup ValidIssuer = Configuration.PublicUrl }; }); - - WebApplicationBuilder.Services.AddJwtInvalidation("coreAuthentication", options => - { - options.InvalidateTimeProvider = async (provider, principal) => - { - var userIdClaim = principal.Claims.FirstOrDefault(x => x.Type == "userId"); - - if (userIdClaim != null) - { - var userId = int.Parse(userIdClaim.Value); - - var userRepository = provider.GetRequiredService>(); - var user = await userRepository.Get().FirstOrDefaultAsync(x => x.Id == userId); - - if (user == null) - return DateTime.MaxValue; - - return user.TokenValidTimestamp; - } - - var apiKeyIdClaim = principal.Claims.FirstOrDefault(x => x.Type == "apiKeyId"); - - if (apiKeyIdClaim != null) - { - var apiKeyId = int.Parse(apiKeyIdClaim.Value); - - var apiKeyRepository = provider.GetRequiredService>(); - var apiKey = await apiKeyRepository.Get().FirstOrDefaultAsync(x => x.Id == apiKeyId); - - // If the api key exists, we don't want to invalidate the request. - // If it doesn't exist we want to invalidate the request - return apiKey == null ? DateTime.MaxValue : DateTime.MinValue; - } - - return DateTime.MaxValue; - }; - }); + + WebApplicationBuilder.Services.AddJwtBearerInvalidation("coreAuthentication"); + WebApplicationBuilder.Services.AddScoped(); WebApplicationBuilder.Services.AddAuthorization(); @@ -499,8 +455,6 @@ public class Startup { WebApplication.UseAuthentication(); - WebApplication.UseJwtInvalidation(); - WebApplication.UseAuthorization(); return Task.CompletedTask; diff --git a/Moonlight.Client.Runtime/Moonlight.Client.Runtime.csproj b/Moonlight.Client.Runtime/Moonlight.Client.Runtime.csproj new file mode 100644 index 00000000..54698be4 --- /dev/null +++ b/Moonlight.Client.Runtime/Moonlight.Client.Runtime.csproj @@ -0,0 +1,64 @@ + + + + net9.0 + enable + enable + True + + + + + + + + + + + + + + + + + true + styles + Never + + + true + styles + Never + + + true + styles + Never + + + true + styles + Never + + + true + styles + Never + + + true + styles + Never + + + + + + + + + <_ContentIncludedByDefault Remove="wwwroot\js\moonCore.js" /> + <_ContentIncludedByDefault Remove="wwwroot\js\moonlight.js" /> + + + diff --git a/Moonlight.Client.Runtime/PluginLoader.cs b/Moonlight.Client.Runtime/PluginLoader.cs new file mode 100644 index 00000000..78b278a9 --- /dev/null +++ b/Moonlight.Client.Runtime/PluginLoader.cs @@ -0,0 +1,10 @@ +using MoonCore.PluginFramework; +using Moonlight.Client.Plugins; + +namespace Moonlight.Client.Runtime; + +[PluginLoader] +public partial class PluginLoader : IPluginStartup +{ + +} \ No newline at end of file diff --git a/Moonlight.Client.Runtime/Program.cs b/Moonlight.Client.Runtime/Program.cs new file mode 100644 index 00000000..5cb70381 --- /dev/null +++ b/Moonlight.Client.Runtime/Program.cs @@ -0,0 +1,9 @@ +using Moonlight.Client; +using Moonlight.Client.Runtime; + +var startup = new Startup(); + +var pluginLoader = new PluginLoader(); +pluginLoader.Initialize(); + +await startup.Run(args, pluginLoader.Instances); \ No newline at end of file diff --git a/Moonlight.Client.Runtime/Properties/launchSettings.json b/Moonlight.Client.Runtime/Properties/launchSettings.json new file mode 100644 index 00000000..d9cbefe5 --- /dev/null +++ b/Moonlight.Client.Runtime/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", + "applicationUrl": "http://localhost:5165", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/Moonlight.Client/Styles/additions/animations.css b/Moonlight.Client.Runtime/Styles/additions/animations.css similarity index 100% rename from Moonlight.Client/Styles/additions/animations.css rename to Moonlight.Client.Runtime/Styles/additions/animations.css diff --git a/Moonlight.Client/Styles/additions/buttons.css b/Moonlight.Client.Runtime/Styles/additions/buttons.css similarity index 100% rename from Moonlight.Client/Styles/additions/buttons.css rename to Moonlight.Client.Runtime/Styles/additions/buttons.css diff --git a/Moonlight.Client/Styles/additions/cards.css b/Moonlight.Client.Runtime/Styles/additions/cards.css similarity index 100% rename from Moonlight.Client/Styles/additions/cards.css rename to Moonlight.Client.Runtime/Styles/additions/cards.css diff --git a/Moonlight.Client/Styles/additions/fonts.css b/Moonlight.Client.Runtime/Styles/additions/fonts.css similarity index 68% rename from Moonlight.Client/Styles/additions/fonts.css rename to Moonlight.Client.Runtime/Styles/additions/fonts.css index e3567e61..30676ad8 100644 --- a/Moonlight.Client/Styles/additions/fonts.css +++ b/Moonlight.Client.Runtime/Styles/additions/fonts.css @@ -1,6 +1,6 @@ -@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=fallback') layer; -@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap') layer; -@import url("https://cdn.jsdelivr.net/npm/lucide-static/font/lucide.css") layer; +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=fallback') layer(base); +@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap') layer(base); +@import url("https://cdn.jsdelivr.net/npm/lucide-static/font/lucide.css") layer(base); @theme { --font-inter: "Inter", var(--font-sans); diff --git a/Moonlight.Client/Styles/additions/forms.css b/Moonlight.Client.Runtime/Styles/additions/forms.css similarity index 100% rename from Moonlight.Client/Styles/additions/forms.css rename to Moonlight.Client.Runtime/Styles/additions/forms.css diff --git a/Moonlight.Client/Styles/additions/loaders.css b/Moonlight.Client.Runtime/Styles/additions/loaders.css similarity index 100% rename from Moonlight.Client/Styles/additions/loaders.css rename to Moonlight.Client.Runtime/Styles/additions/loaders.css diff --git a/Moonlight.Client/Styles/additions/progress.css b/Moonlight.Client.Runtime/Styles/additions/progress.css similarity index 100% rename from Moonlight.Client/Styles/additions/progress.css rename to Moonlight.Client.Runtime/Styles/additions/progress.css diff --git a/Moonlight.Client/Styles/additions/scrollbar.css b/Moonlight.Client.Runtime/Styles/additions/scrollbar.css similarity index 100% rename from Moonlight.Client/Styles/additions/scrollbar.css rename to Moonlight.Client.Runtime/Styles/additions/scrollbar.css diff --git a/Moonlight.Client/Styles/additions/tabs.css b/Moonlight.Client.Runtime/Styles/additions/tabs.css similarity index 100% rename from Moonlight.Client/Styles/additions/tabs.css rename to Moonlight.Client.Runtime/Styles/additions/tabs.css diff --git a/Moonlight.Client/Styles/additions/theme.css b/Moonlight.Client.Runtime/Styles/additions/theme.css similarity index 100% rename from Moonlight.Client/Styles/additions/theme.css rename to Moonlight.Client.Runtime/Styles/additions/theme.css diff --git a/Moonlight.Client/Styles/additions/theme.white.css b/Moonlight.Client.Runtime/Styles/additions/theme.white.css similarity index 100% rename from Moonlight.Client/Styles/additions/theme.white.css rename to Moonlight.Client.Runtime/Styles/additions/theme.white.css diff --git a/Moonlight.Client/Styles/exports.css b/Moonlight.Client.Runtime/Styles/exports.css similarity index 100% rename from Moonlight.Client/Styles/exports.css rename to Moonlight.Client.Runtime/Styles/exports.css diff --git a/Moonlight.Client/Styles/mappings/mooncore.map b/Moonlight.Client.Runtime/Styles/mappings/mooncore.map old mode 100755 new mode 100644 similarity index 100% rename from Moonlight.Client/Styles/mappings/mooncore.map rename to Moonlight.Client.Runtime/Styles/mappings/mooncore.map diff --git a/Moonlight.Client/Styles/package-lock.json b/Moonlight.Client.Runtime/Styles/package-lock.json similarity index 100% rename from Moonlight.Client/Styles/package-lock.json rename to Moonlight.Client.Runtime/Styles/package-lock.json diff --git a/Moonlight.Client/Styles/package.json b/Moonlight.Client.Runtime/Styles/package.json similarity index 80% rename from Moonlight.Client/Styles/package.json rename to Moonlight.Client.Runtime/Styles/package.json index 25753cb8..716d25ce 100644 --- a/Moonlight.Client/Styles/package.json +++ b/Moonlight.Client.Runtime/Styles/package.json @@ -6,9 +6,9 @@ "xml2js": "^0.6.2" }, "scripts": { - "pretailwind-build": "node resolveNuget.js ../Moonlight.Client.csproj", + "pretailwind-build": "node resolveNuget.js ../Moonlight.Client.Runtime.csproj", "tailwind-build": "npx tailwindcss -i style.css -o ../wwwroot/css/style.min.css", - "pretailwind": "node resolveNuget.js ../Moonlight.Client.csproj", + "pretailwind": "node resolveNuget.js ../Moonlight.Client.Runtime.csproj", "tailwind": "npx tailwindcss -i style.css -o ../wwwroot/css/style.min.css --watch" } } diff --git a/Moonlight.Client/Styles/preTailwind.css b/Moonlight.Client.Runtime/Styles/preTailwind.css similarity index 100% rename from Moonlight.Client/Styles/preTailwind.css rename to Moonlight.Client.Runtime/Styles/preTailwind.css diff --git a/Moonlight.Client/Styles/resolveNuget.js b/Moonlight.Client.Runtime/Styles/resolveNuget.js similarity index 100% rename from Moonlight.Client/Styles/resolveNuget.js rename to Moonlight.Client.Runtime/Styles/resolveNuget.js diff --git a/Moonlight.Client/Styles/style.css b/Moonlight.Client.Runtime/Styles/style.css similarity index 69% rename from Moonlight.Client/Styles/style.css rename to Moonlight.Client.Runtime/Styles/style.css index 130fb3e0..e79f77f2 100644 --- a/Moonlight.Client/Styles/style.css +++ b/Moonlight.Client.Runtime/Styles/style.css @@ -13,4 +13,9 @@ @source "../**/*.razor"; @source "../**/*.cs"; @source "../**/*.html"; + +@source "../../Moonlight.Client/**/*.razor"; +@source "../../Moonlight.Client/**/*.cs"; +@source "../../Moonlight.Client/**/*.html"; + @source "./mappings/*.map"; \ No newline at end of file diff --git a/Moonlight.Client/wwwroot/frontend.example.json b/Moonlight.Client.Runtime/wwwroot/frontend.example.json similarity index 100% rename from Moonlight.Client/wwwroot/frontend.example.json rename to Moonlight.Client.Runtime/wwwroot/frontend.example.json diff --git a/Moonlight.Client.Runtime/wwwroot/img/icon-192.png b/Moonlight.Client.Runtime/wwwroot/img/icon-192.png new file mode 100644 index 00000000..1b417d98 Binary files /dev/null and b/Moonlight.Client.Runtime/wwwroot/img/icon-192.png differ diff --git a/Moonlight.Client.Runtime/wwwroot/img/icon-512.png b/Moonlight.Client.Runtime/wwwroot/img/icon-512.png new file mode 100644 index 00000000..437487cf Binary files /dev/null and b/Moonlight.Client.Runtime/wwwroot/img/icon-512.png differ diff --git a/Moonlight.Client.Runtime/wwwroot/img/pfp_placeholder.png b/Moonlight.Client.Runtime/wwwroot/img/pfp_placeholder.png new file mode 100644 index 00000000..1108ddbb Binary files /dev/null and b/Moonlight.Client.Runtime/wwwroot/img/pfp_placeholder.png differ diff --git a/Moonlight.Client/wwwroot/manifest.webmanifest b/Moonlight.Client.Runtime/wwwroot/manifest.webmanifest similarity index 100% rename from Moonlight.Client/wwwroot/manifest.webmanifest rename to Moonlight.Client.Runtime/wwwroot/manifest.webmanifest diff --git a/Moonlight.Client/wwwroot/service-worker.js b/Moonlight.Client.Runtime/wwwroot/service-worker.js similarity index 100% rename from Moonlight.Client/wwwroot/service-worker.js rename to Moonlight.Client.Runtime/wwwroot/service-worker.js diff --git a/Moonlight.Client/wwwroot/service-worker.published.js b/Moonlight.Client.Runtime/wwwroot/service-worker.published.js similarity index 100% rename from Moonlight.Client/wwwroot/service-worker.published.js rename to Moonlight.Client.Runtime/wwwroot/service-worker.published.js diff --git a/Moonlight.Client/wwwroot/svg/logo.svg b/Moonlight.Client.Runtime/wwwroot/svg/logo.svg similarity index 100% rename from Moonlight.Client/wwwroot/svg/logo.svg rename to Moonlight.Client.Runtime/wwwroot/svg/logo.svg diff --git a/Moonlight.Client/GlobalUsings.cs b/Moonlight.Client/GlobalUsings.cs new file mode 100644 index 00000000..0598b4b1 --- /dev/null +++ b/Moonlight.Client/GlobalUsings.cs @@ -0,0 +1,6 @@ +// Global using directives + +global using Microsoft.AspNetCore.Components.Web; +global using Microsoft.JSInterop; +global using Microsoft.Extensions.Logging; +global using MoonCore.Blazor.FlyonUi.Components; \ No newline at end of file diff --git a/Moonlight.Client/Implementations/CoreStartup.cs b/Moonlight.Client/Implementations/CoreStartup.cs index 55005986..06ae3249 100644 --- a/Moonlight.Client/Implementations/CoreStartup.cs +++ b/Moonlight.Client/Implementations/CoreStartup.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Components.WebAssembly.Hosting; +using Microsoft.Extensions.DependencyInjection; using Moonlight.Client.Interfaces; using Moonlight.Client.Plugins; diff --git a/Moonlight.Client/Implementations/SysFileSystemProvider.cs b/Moonlight.Client/Implementations/SysFileSystemProvider.cs index 4e6ca06e..32718012 100644 --- a/Moonlight.Client/Implementations/SysFileSystemProvider.cs +++ b/Moonlight.Client/Implementations/SysFileSystemProvider.cs @@ -1,7 +1,6 @@ using MoonCore.Blazor.Services; using MoonCore.Blazor.Tailwind.Fm; using MoonCore.Blazor.Tailwind.Fm.Models; -using MoonCore.Blazor.Tailwind.Services; using MoonCore.Helpers; using Moonlight.Shared.Http.Requests.Admin.Sys.Files; using Moonlight.Shared.Http.Responses.Admin.Sys; diff --git a/Moonlight.Client/Moonlight.Client.csproj b/Moonlight.Client/Moonlight.Client.csproj index b3988510..46b6a65e 100644 --- a/Moonlight.Client/Moonlight.Client.csproj +++ b/Moonlight.Client/Moonlight.Client.csproj @@ -1,5 +1,5 @@  - + net9.0 enable @@ -22,11 +22,9 @@ - - - - - + + + @@ -56,4 +54,10 @@ + + + + + <_ContentIncludedByDefault Remove="wwwroot\css\style.min.css" /> + \ No newline at end of file diff --git a/Moonlight.Client/Plugins/PluginStartupAttribute.cs b/Moonlight.Client/Plugins/PluginStartupAttribute.cs deleted file mode 100644 index d55d5491..00000000 --- a/Moonlight.Client/Plugins/PluginStartupAttribute.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Moonlight.Client.Plugins; - -[AttributeUsage(AttributeTargets.Class)] -public class PluginStartupAttribute : Attribute -{ - -} \ No newline at end of file diff --git a/Moonlight.Client/Program.cs b/Moonlight.Client/Program.cs deleted file mode 100644 index 6e5b4824..00000000 --- a/Moonlight.Client/Program.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Moonlight.Client; - -var startup = new Startup(); - -try -{ - await startup.Run(args); -} -catch (Exception e) -{ - Console.WriteLine(e); - throw; -} \ No newline at end of file diff --git a/Moonlight.Client/Services/RemoteAuthStateManager.cs b/Moonlight.Client/Services/RemoteAuthStateManager.cs index e621446b..43302b90 100644 --- a/Moonlight.Client/Services/RemoteAuthStateManager.cs +++ b/Moonlight.Client/Services/RemoteAuthStateManager.cs @@ -2,8 +2,8 @@ using System.Web; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Authorization; +using MoonCore.Blazor.FlyonUi.Auth; using MoonCore.Blazor.Services; -using MoonCore.Blazor.Tailwind.Auth; using MoonCore.Exceptions; using MoonCore.Helpers; using Moonlight.Shared.Http.Requests.Auth; diff --git a/Moonlight.Client/Services/WindowService.cs b/Moonlight.Client/Services/WindowService.cs index 266b4b9d..692706c3 100644 --- a/Moonlight.Client/Services/WindowService.cs +++ b/Moonlight.Client/Services/WindowService.cs @@ -1,5 +1,3 @@ -using Microsoft.JSInterop; - namespace Moonlight.Client.Services; public class WindowService diff --git a/Moonlight.Client/Startup.cs b/Moonlight.Client/Startup.cs index 4e01ee27..2963ee95 100644 --- a/Moonlight.Client/Startup.cs +++ b/Moonlight.Client/Startup.cs @@ -1,21 +1,18 @@ -using System.Reflection; -using System.Runtime.Loader; using System.Text.Json; -using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; -using Microsoft.JSInterop; +using Microsoft.Extensions.DependencyInjection; +using MoonCore.Blazor.FlyonUi; +using MoonCore.Blazor.FlyonUi.Auth; using MoonCore.Blazor.Services; -using MoonCore.Blazor.Tailwind.Extensions; -using MoonCore.Blazor.Tailwind.Auth; using MoonCore.Extensions; using MoonCore.Helpers; +using MoonCore.Logging; using MoonCore.Permissions; -using Moonlight.Client.Implementations; -using Moonlight.Client.Interfaces; using Moonlight.Client.Plugins; using Moonlight.Client.Services; using Moonlight.Shared.Misc; using Moonlight.Client.UI; +using WindowService = Moonlight.Client.Services.WindowService; namespace Moonlight.Client; @@ -27,7 +24,6 @@ public class Startup private FrontendConfiguration Configuration; // Logging - private ILoggerProvider[] LoggerProviders; private ILoggerFactory LoggerFactory; private ILogger Logger; @@ -143,12 +139,13 @@ public class Startup }); WebAssemblyHostBuilder.Services.AddScoped(); - WebAssemblyHostBuilder.Services.AddMoonCoreBlazorTailwind(); + WebAssemblyHostBuilder.Services.AddFileManagerOperations(); + WebAssemblyHostBuilder.Services.AddFlyonUiServices(); WebAssemblyHostBuilder.Services.AddScoped(); WebAssemblyHostBuilder.Services.AddScoped(); - WebAssemblyHostBuilder.Services.AutoAddServices(); + WebAssemblyHostBuilder.Services.AutoAddServices(); return Task.CompletedTask; } @@ -179,7 +176,7 @@ public class Startup startupSc.AddLogging(builder => { builder.ClearProviders(); - builder.AddProviders(LoggerProviders); + builder.AddAnsiConsole(); }); PluginLoadServiceProvider = startupSc.BuildServiceProvider(); @@ -187,8 +184,6 @@ public class Startup // Collect startups var pluginStartups = new List(); - pluginStartups.Add(new CoreStartup()); - pluginStartups.AddRange(AdditionalPlugins); // Used by the development server // Do NOT remove the following comment, as its used to place the plugin startup register calls @@ -259,15 +254,8 @@ public class Startup private Task SetupLogging() { - LoggerProviders = LoggerBuildHelper.BuildFromConfiguration(configuration => - { - configuration.Console.Enable = true; - configuration.Console.EnableAnsiMode = true; - configuration.FileLogging.Enable = false; - }); - LoggerFactory = new LoggerFactory(); - LoggerFactory.AddProviders(LoggerProviders); + LoggerFactory.AddAnsiConsole(); Logger = LoggerFactory.CreateLogger(); @@ -277,7 +265,7 @@ public class Startup private Task RegisterLogging() { WebAssemblyHostBuilder.Logging.ClearProviders(); - WebAssemblyHostBuilder.Logging.AddProviders(LoggerProviders); + WebAssemblyHostBuilder.Logging.AddAnsiConsole(); return Task.CompletedTask; } diff --git a/Moonlight.Client/UI/Layouts/MainLayout.razor b/Moonlight.Client/UI/Layouts/MainLayout.razor index 0f292a70..1a12401e 100644 --- a/Moonlight.Client/UI/Layouts/MainLayout.razor +++ b/Moonlight.Client/UI/Layouts/MainLayout.razor @@ -22,7 +22,7 @@
-
+
An unhandled error has occurred. diff --git a/Moonlight.Client/UI/Partials/AppSidebar.razor b/Moonlight.Client/UI/Partials/AppSidebar.razor index e698a6d9..f47ef4aa 100644 --- a/Moonlight.Client/UI/Partials/AppSidebar.razor +++ b/Moonlight.Client/UI/Partials/AppSidebar.razor @@ -1,12 +1,11 @@ @using System.Security.Claims @using Microsoft.AspNetCore.Authorization @using Microsoft.AspNetCore.Components.Authorization -@using MoonCore.Blazor.Tailwind.Auth +@using MoonCore.Blazor.FlyonUi.Auth @using Moonlight.Client.Interfaces @using Moonlight.Client.Models @using Moonlight.Client.UI.Layouts -@inject ToastService ToastService @inject NavigationManager Navigation @inject AuthenticationStateManager AuthStateManager @inject IEnumerable SidebarItemProviders diff --git a/Moonlight.Client/UI/Partials/Design/ThemeSettings.razor b/Moonlight.Client/UI/Partials/Design/ThemeSettings.razor index 17a1f29e..9881cf0a 100644 --- a/Moonlight.Client/UI/Partials/Design/ThemeSettings.razor +++ b/Moonlight.Client/UI/Partials/Design/ThemeSettings.razor @@ -9,7 +9,8 @@ @inject FrontendConfiguration FrontendConfiguration @inject ThemeService ThemeService @inject ToastService ToastService -@inject DownloadService DownloadService + +@* @inject DownloadService DownloadService *@
@@ -108,7 +109,7 @@ AddSetting("danger", "danger-300", 252, 165, 165); AddSetting("danger", "danger-400", 248, 113, 113); AddSetting("danger", "danger", 239, 68, 68); - AddSetting("danger", "danger-600", 220, 38, 38); + AddSetting("danger", "error", 220, 38, 38); AddSetting("danger", "danger-700", 185, 28, 28); AddSetting("danger", "danger-800", 153, 27, 27); AddSetting("danger", "danger-900", 127, 29, 29); @@ -192,7 +193,7 @@ { if (FrontendConfiguration.HostEnvironment != "ApiServer") { - await ToastService.Danger( + await ToastService.Error( "Theme Settings", "Unable to save the theme settings. If you are using a static host, you need to configure the colors in the frontend.json file" ); @@ -215,7 +216,7 @@ var json = JsonSerializer.Serialize(ThemeService.Variables); // Download the theme configuration - await DownloadService.DownloadString("theme.json", json); + //await DownloadService.DownloadString("theme.json", json); await ToastService.Success("Successfully exported theme configuration"); } @@ -224,7 +225,7 @@ { if (!eventArgs.File.Name.EndsWith(".json")) { - await ToastService.Danger("Only .json files are allowed"); + await ToastService.Error("Only .json files are allowed"); return; } diff --git a/Moonlight.Client/UI/Views/Admin/Api/Create.razor b/Moonlight.Client/UI/Views/Admin/Api/Create.razor index af9e2cb5..691175f3 100644 --- a/Moonlight.Client/UI/Views/Admin/Api/Create.razor +++ b/Moonlight.Client/UI/Views/Admin/Api/Create.razor @@ -10,7 +10,8 @@ @inject NavigationManager Navigation @inject ToastService ToastService @inject AlertService AlertService -@inject DownloadService DownloadService + +@* @inject DownloadService DownloadService *@ diff --git a/Moonlight.Client/UI/Views/Admin/Api/Index.razor b/Moonlight.Client/UI/Views/Admin/Api/Index.razor index 6f6e4baa..ad3634d3 100644 --- a/Moonlight.Client/UI/Views/Admin/Api/Index.razor +++ b/Moonlight.Client/UI/Views/Admin/Api/Index.razor @@ -2,8 +2,8 @@ @using MoonCore.Helpers @using MoonCore.Models -@using MoonCore.Blazor.Tailwind.Dt @using Moonlight.Shared.Http.Responses.Admin.ApiKeys +@using MoonCore.Blazor.FlyonUi.DataTables @inject HttpApiClient ApiClient @inject AlertService AlertService diff --git a/Moonlight.Client/UI/Views/Admin/Users/Create.razor b/Moonlight.Client/UI/Views/Admin/Users/Create.razor index 022951a7..69fbaa12 100644 --- a/Moonlight.Client/UI/Views/Admin/Users/Create.razor +++ b/Moonlight.Client/UI/Views/Admin/Users/Create.razor @@ -3,7 +3,6 @@ @using System.Text.Json @using MoonCore.Helpers @using Moonlight.Shared.Http.Requests.Admin.Users -@using MoonCore.Blazor.Tailwind.Input2 @inject HttpApiClient ApiClient @inject NavigationManager Navigation diff --git a/Moonlight.Client/UI/Views/Admin/Users/Index.razor b/Moonlight.Client/UI/Views/Admin/Users/Index.razor index 870e944a..f0a89872 100644 --- a/Moonlight.Client/UI/Views/Admin/Users/Index.razor +++ b/Moonlight.Client/UI/Views/Admin/Users/Index.razor @@ -2,8 +2,8 @@ @using MoonCore.Helpers @using MoonCore.Models -@using MoonCore.Blazor.Tailwind.Dt @using Moonlight.Shared.Http.Responses.Admin.Users +@using MoonCore.Blazor.FlyonUi.DataTables @inject HttpApiClient ApiClient @inject AlertService AlertService diff --git a/Moonlight.Client/UI/Views/Admin/Users/Update.razor b/Moonlight.Client/UI/Views/Admin/Users/Update.razor index 36c4b269..fd48300a 100644 --- a/Moonlight.Client/UI/Views/Admin/Users/Update.razor +++ b/Moonlight.Client/UI/Views/Admin/Users/Update.razor @@ -4,7 +4,6 @@ @using MoonCore.Helpers @using Moonlight.Shared.Http.Requests.Admin.Users @using Moonlight.Shared.Http.Responses.Admin.Users -@using MoonCore.Blazor.Tailwind.Input2 @inject HttpApiClient ApiClient @inject NavigationManager Navigation diff --git a/Moonlight.Client/_Imports.razor b/Moonlight.Client/_Imports.razor index 1eb61723..33fab635 100644 --- a/Moonlight.Client/_Imports.razor +++ b/Moonlight.Client/_Imports.razor @@ -8,9 +8,7 @@ @using Microsoft.JSInterop @using Moonlight.Client -@using MoonCore.Blazor.Tailwind.Components -@using MoonCore.Blazor.Tailwind.Alerts -@using MoonCore.Blazor.Tailwind.Helpers -@using MoonCore.Blazor.Tailwind.Modals -@using MoonCore.Blazor.Tailwind.Services -@using MoonCore.Blazor.Tailwind.Toasts \ No newline at end of file +@using MoonCore.Blazor.FlyonUi.Components +@using MoonCore.Blazor.FlyonUi.Modals +@using MoonCore.Blazor.FlyonUi.Toasts +@using MoonCore.Blazor.FlyonUi.Alerts \ No newline at end of file diff --git a/Moonlight.Client/wwwroot/index.html b/Moonlight.Client/wwwroot/index.html deleted file mode 100644 index 98f69182..00000000 --- a/Moonlight.Client/wwwroot/index.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - Moonlight.Client - - - - - - - - -
- -
-
-
-
-
-
-
-
-
-
- -
- - - - - - - - - diff --git a/Moonlight.Client/wwwroot/svg/completed.svg b/Moonlight.Client/wwwroot/svg/completed.svg deleted file mode 100644 index 6d51f78d..00000000 --- a/Moonlight.Client/wwwroot/svg/completed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/Moonlight.Client/wwwroot/svg/notfound.svg b/Moonlight.Client/wwwroot/svg/notfound.svg deleted file mode 100644 index 8174fed0..00000000 --- a/Moonlight.Client/wwwroot/svg/notfound.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/Moonlight.sln b/Moonlight.sln index f8306250..6ee5c7aa 100644 --- a/Moonlight.sln +++ b/Moonlight.sln @@ -6,6 +6,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moonlight.Client", "Moonlig EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moonlight.Shared", "Moonlight.Shared\Moonlight.Shared.csproj", "{C82E4F2A-91D2-4BC7-9AA7-241FDAAFC823}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moonlight.ApiServer.Runtime", "Moonlight.ApiServer.Runtime\Moonlight.ApiServer.Runtime.csproj", "{97FC686D-BC8A-4145-90C7-CA86B598441E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moonlight.Client.Runtime", "Moonlight.Client.Runtime\Moonlight.Client.Runtime.csproj", "{72F21AA4-4721-4B4C-B2FF-CFDCBB1BCB05}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -24,6 +28,14 @@ Global {C82E4F2A-91D2-4BC7-9AA7-241FDAAFC823}.Debug|Any CPU.Build.0 = Debug|Any CPU {C82E4F2A-91D2-4BC7-9AA7-241FDAAFC823}.Release|Any CPU.ActiveCfg = Release|Any CPU {C82E4F2A-91D2-4BC7-9AA7-241FDAAFC823}.Release|Any CPU.Build.0 = Release|Any CPU + {97FC686D-BC8A-4145-90C7-CA86B598441E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {97FC686D-BC8A-4145-90C7-CA86B598441E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {97FC686D-BC8A-4145-90C7-CA86B598441E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {97FC686D-BC8A-4145-90C7-CA86B598441E}.Release|Any CPU.Build.0 = Release|Any CPU + {72F21AA4-4721-4B4C-B2FF-CFDCBB1BCB05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {72F21AA4-4721-4B4C-B2FF-CFDCBB1BCB05}.Debug|Any CPU.Build.0 = Debug|Any CPU + {72F21AA4-4721-4B4C-B2FF-CFDCBB1BCB05}.Release|Any CPU.ActiveCfg = Release|Any CPU + {72F21AA4-4721-4B4C-B2FF-CFDCBB1BCB05}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution EndGlobalSection