Refactored project to module structure

This commit is contained in:
2026-03-12 22:50:15 +01:00
parent 93de9c5d00
commit 1257e8b950
219 changed files with 1231 additions and 1259 deletions

View File

@@ -0,0 +1,65 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Moonlight.Shared.Shared.Auth;
namespace Moonlight.Api.Shared.Auth;
[ApiController]
[Route("api/auth")]
public class AuthController : Controller
{
private readonly IAuthenticationSchemeProvider SchemeProvider;
public AuthController(IAuthenticationSchemeProvider schemeProvider)
{
SchemeProvider = schemeProvider;
}
[HttpGet]
public async Task<ActionResult<SchemeDto[]>> GetSchemesAsync()
{
var schemes = await SchemeProvider.GetAllSchemesAsync();
return schemes
.Where(scheme => !string.IsNullOrWhiteSpace(scheme.DisplayName))
.Select(scheme => new SchemeDto(scheme.Name, scheme.DisplayName!))
.ToArray();
}
[HttpGet("{schemeName:alpha}")]
public async Task<ActionResult> StartAsync([FromRoute] string schemeName)
{
var scheme = await SchemeProvider.GetSchemeAsync(schemeName);
if (scheme == null || string.IsNullOrWhiteSpace(scheme.DisplayName))
return Problem("Invalid authentication scheme name", statusCode: 400);
return Challenge(new AuthenticationProperties
{
RedirectUri = "/"
}, scheme.Name);
}
[Authorize]
[HttpGet("claims")]
public Task<ActionResult<ClaimDto[]>> GetClaimsAsync()
{
var result = User.Claims
.Select(claim => new ClaimDto(claim.Type, claim.Value))
.ToArray();
return Task.FromResult<ActionResult<ClaimDto[]>>(result);
}
[HttpGet("logout")]
public Task<ActionResult> LogoutAsync()
{
return Task.FromResult<ActionResult>(
SignOut(new AuthenticationProperties
{
RedirectUri = "/"
})
);
}
}

View File

@@ -0,0 +1,13 @@
using System.Diagnostics.CodeAnalysis;
using Moonlight.Shared.Shared.Frontend;
using Riok.Mapperly.Abstractions;
namespace Moonlight.Api.Shared.Frontend;
[Mapper]
[SuppressMessage("Mapper", "RMG020:No members are mapped in an object mapping")]
[SuppressMessage("Mapper", "RMG012:No members are mapped in an object mapping")]
public static partial class FrontendConfigMapper
{
public static partial FrontendConfigDto ToDto(FrontendConfiguration configuration);
}

View File

@@ -0,0 +1,3 @@
namespace Moonlight.Api.Shared.Frontend;
public record FrontendConfiguration(string Name, string? ThemeCss);

View File

@@ -0,0 +1,23 @@
using Microsoft.AspNetCore.Mvc;
using Moonlight.Shared.Shared.Frontend;
namespace Moonlight.Api.Shared.Frontend;
[ApiController]
[Route("api/frontend")]
public class FrontendController : Controller
{
private readonly FrontendService FrontendService;
public FrontendController(FrontendService frontendService)
{
FrontendService = frontendService;
}
[HttpGet("config")]
public async Task<ActionResult<FrontendConfigDto>> GetConfigAsync()
{
var configuration = await FrontendService.GetConfigurationAsync();
return FrontendConfigMapper.ToDto(configuration);
}
}

View File

@@ -0,0 +1,52 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Moonlight.Api.Admin.Sys.Settings;
using Moonlight.Api.Admin.Sys.Versions;
using Moonlight.Api.Infrastructure.Database;
using Moonlight.Api.Infrastructure.Database.Entities;
namespace Moonlight.Api.Shared.Frontend;
public class FrontendService
{
private const string CacheKey = $"Moonlight.{nameof(FrontendService)}.{nameof(GetConfigurationAsync)}";
private readonly IMemoryCache Cache;
private readonly IOptions<FrontendOptions> Options;
private readonly SettingsService SettingsService;
private readonly DatabaseRepository<Theme> ThemeRepository;
public FrontendService(IMemoryCache cache, DatabaseRepository<Theme> themeRepository,
IOptions<FrontendOptions> options, SettingsService settingsService)
{
Cache = cache;
ThemeRepository = themeRepository;
Options = options;
SettingsService = settingsService;
}
public async Task<FrontendConfiguration> GetConfigurationAsync()
{
if (Cache.TryGetValue(CacheKey, out FrontendConfiguration? value))
if (value != null)
return value;
var theme = await ThemeRepository
.Query()
.FirstOrDefaultAsync(x => x.IsEnabled);
var name = await SettingsService.GetValueAsync<string>(FrontendSettingConstants.Name);
var config = new FrontendConfiguration(name ?? "Moonlight", theme?.CssContent);
Cache.Set(CacheKey, config, TimeSpan.FromMinutes(Options.Value.CacheMinutes));
return config;
}
public Task ResetCacheAsync()
{
Cache.Remove(CacheKey);
return Task.CompletedTask;
}
}

View File

@@ -0,0 +1,6 @@
namespace Moonlight.Api.Shared.Frontend;
public class FrontendSettingConstants
{
public const string Name = "Moonlight.Frontend.Name";
}

View File

@@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Moonlight.Api.Shared;
[ApiController]
[Route("api/ping")]
public class PingController : Controller
{
[HttpGet]
[AllowAnonymous]
public IActionResult Get()
{
return Ok("Pong");
}
}