Add dynamic background images for servers

This commit is contained in:
Marcel Baumgartner
2023-06-10 00:00:54 +02:00
parent d7fbe54225
commit 61d547b2ce
13 changed files with 1520 additions and 334 deletions

View File

@@ -20,4 +20,5 @@ public class Image
public List<DockerImage> DockerImages { get; set; } = new(); public List<DockerImage> DockerImages { get; set; } = new();
public List<ImageVariable> Variables { get; set; } = new(); public List<ImageVariable> Variables { get; set; } = new();
public string TagsJson { get; set; } = ""; public string TagsJson { get; set; } = "";
public string BackgroundImageUrl { get; set; } = "";
} }

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Moonlight.App.Database.Migrations
{
/// <inheritdoc />
public partial class AddBackgroundImageUrlImage : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "BackgroundImageUrl",
table: "Images",
type: "longtext",
nullable: false)
.Annotation("MySql:CharSet", "utf8mb4");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "BackgroundImageUrl",
table: "Images");
}
}
}

View File

@@ -132,6 +132,10 @@ namespace Moonlight.App.Database.Migrations
b.Property<int>("Allocations") b.Property<int>("Allocations")
.HasColumnType("int"); .HasColumnType("int");
b.Property<string>("BackgroundImageUrl")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("ConfigFiles") b.Property<string>("ConfigFiles")
.IsRequired() .IsRequired()
.HasColumnType("longtext"); .HasColumnType("longtext");

View File

@@ -47,6 +47,29 @@ public class ResourcesController : Controller
return NotFound(); return NotFound();
} }
[HttpGet("background/{name}")]
public async Task<ActionResult> GetBackground([FromRoute] string name)
{
if (name.Contains(".."))
{
await SecurityLogService.Log(SecurityLogType.PathTransversal, x =>
{
x.Add<string>(name);
});
return NotFound();
}
if (System.IO.File.Exists(PathBuilder.File("storage", "resources", "public", "background", name)))
{
var fs = new FileStream(PathBuilder.File("storage", "resources", "public", "background", name), FileMode.Open);
return File(fs, MimeTypes.GetMimeType(name), name);
}
return NotFound();
}
[HttpGet("bucket/{bucket}/{name}")] [HttpGet("bucket/{bucket}/{name}")]
public async Task<ActionResult> GetBucket([FromRoute] string bucket, [FromRoute] string name) public async Task<ActionResult> GetBucket([FromRoute] string bucket, [FromRoute] string name)
{ {

View File

@@ -16,6 +16,11 @@ public class ResourceService
return $"{AppUrl}/api/moonlight/resources/images/{name}"; return $"{AppUrl}/api/moonlight/resources/images/{name}";
} }
public string BackgroundImage(string name)
{
return $"{AppUrl}/api/moonlight/resources/background/{name}";
}
public string Avatar(User user) public string Avatar(User user)
{ {
return $"{AppUrl}/api/moonlight/avatar/{user.Id}"; return $"{AppUrl}/api/moonlight/avatar/{user.Id}";

View File

@@ -0,0 +1,33 @@
using Logging.Net;
using Moonlight.App.Services.Files;
namespace Moonlight.App.Services.Sessions;
public class DynamicBackgroundService
{
public EventHandler OnBackgroundImageChanged { get; set; }
public string BackgroundImageUrl { get; private set; }
private string DefaultBackgroundImageUrl;
public DynamicBackgroundService(ResourceService resourceService)
{
DefaultBackgroundImageUrl = resourceService.BackgroundImage("main.jpg");
BackgroundImageUrl = DefaultBackgroundImageUrl;
}
public Task Change(string url)
{
BackgroundImageUrl = url;
OnBackgroundImageChanged?.Invoke(this, null!);
return Task.CompletedTask;
}
public Task Reset()
{
BackgroundImageUrl = DefaultBackgroundImageUrl;
OnBackgroundImageChanged?.Invoke(this, null!);
return Task.CompletedTask;
}
}

View File

@@ -74,6 +74,7 @@
<Folder Include="App\ApiClients\CloudPanel\Resources\" /> <Folder Include="App\ApiClients\CloudPanel\Resources\" />
<Folder Include="App\Http\Middleware" /> <Folder Include="App\Http\Middleware" />
<Folder Include="storage\backups\" /> <Folder Include="storage\backups\" />
<Folder Include="storage\resources\public\background\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -134,6 +134,7 @@ namespace Moonlight
builder.Services.AddScoped<ReCaptchaService>(); builder.Services.AddScoped<ReCaptchaService>();
builder.Services.AddScoped<IpBanService>(); builder.Services.AddScoped<IpBanService>();
builder.Services.AddSingleton<OAuth2Service>(); builder.Services.AddSingleton<OAuth2Service>();
builder.Services.AddScoped<DynamicBackgroundService>();
builder.Services.AddScoped<SubscriptionService>(); builder.Services.AddScoped<SubscriptionService>();
builder.Services.AddScoped<SubscriptionAdminService>(); builder.Services.AddScoped<SubscriptionAdminService>();

View File

@@ -20,6 +20,7 @@
@inject ToastService ToastService @inject ToastService ToastService
@inject SmartTranslateService SmartTranslateService @inject SmartTranslateService SmartTranslateService
@inject IpBanService IpBanService @inject IpBanService IpBanService
@inject DynamicBackgroundService DynamicBackgroundService
<GlobalErrorBoundary> <GlobalErrorBoundary>
@{ @{
@@ -56,7 +57,7 @@
<Sidebar></Sidebar> <Sidebar></Sidebar>
<div class="app-main flex-column flex-row-fluid" id="kt_app_main"> <div class="app-main flex-column flex-row-fluid" id="kt_app_main">
<div class="d-flex flex-column flex-column-fluid"> <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" class="app-content flex-column-fluid" style="background-position: center; background-size: cover; background-repeat: no-repeat; background-attachment: fixed; background-image: url('@(DynamicBackgroundService.BackgroundImageUrl)')">
<div id="kt_app_content_container" class="app-container container-fluid"> <div id="kt_app_content_container" class="app-container container-fluid">
<div class="mt-10"> <div class="mt-10">
<SoftErrorBoundary> <SoftErrorBoundary>
@@ -189,6 +190,11 @@
{ {
try try
{ {
DynamicBackgroundService.OnBackgroundImageChanged += async (_, _) =>
{
await InvokeAsync(StateHasChanged);
};
IsIpBanned = await IpBanService.IsBanned(); IsIpBanned = await IpBanService.IsBanned();
if(IsIpBanned) if(IsIpBanned)
@@ -211,7 +217,13 @@
await SessionService.Register(); await SessionService.Register();
NavigationManager.LocationChanged += (sender, args) => { SessionService.Refresh(); }; NavigationManager.LocationChanged += async (_, _) =>
{
SessionService.Refresh();
if (!NavigationManager.Uri.Contains("/server/"))
await DynamicBackgroundService.Reset();
};
if (User != null) if (User != null)
{ {

View File

@@ -38,6 +38,16 @@
</label> </label>
<textarea @bind="Image.Description" type="text" class="form-control"></textarea> <textarea @bind="Image.Description" type="text" class="form-control"></textarea>
</div> </div>
<div class="mb-10">
<label class="form-label">
<TL>Background image url</TL>
</label>
<input
@bind="Image.BackgroundImageUrl"
type="text"
class="form-control"
placeholder="@(SmartTranslateService.Translate("Leave empty for the default background image"))">
</div>
</div> </div>
</div> </div>
<div class="col-xl-6 mb-5 mb-xl-10"> <div class="col-xl-6 mb-5 mb-xl-10">

View File

@@ -125,7 +125,8 @@
</div> </div>
</div> </div>
<!--d-flex flex-row mb-5--> <div class="row">
<div class="col">
<div class="card mb-5"> <div class="card mb-5">
<div class="card-header card-header-stretch"> <div class="card-header card-header-stretch">
<div class="card-title d-flex align-items-center"> <div class="card-title d-flex align-items-center">
@@ -173,14 +174,15 @@
<TL>Create a domain</TL> <TL>Create a domain</TL>
</a> </a>
<span class="text-gray-400 fw-semibold d-block fs-6"> <span class="text-gray-400 fw-semibold d-block fs-6">
<TL>Make your servvices accessible throught your own domain</TL> <TL>Make your services accessible through your own domain</TL>
</span> </span>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="col">
<div class="card mb-5"> <div class="card mb-5">
<div class="card-header card-header-stretch"> <div class="card-header card-header-stretch">
<div class="card-title d-flex align-items-center"> <div class="card-title d-flex align-items-center">
@@ -235,6 +237,8 @@
</div> </div>
</div> </div>
</div> </div>
</div>
</div>
</LazyLoader> </LazyLoader>
@code @code

View File

@@ -10,6 +10,7 @@
@using Moonlight.App.Helpers.Wings.Enums @using Moonlight.App.Helpers.Wings.Enums
@using Moonlight.App.Repositories @using Moonlight.App.Repositories
@using Moonlight.App.Services @using Moonlight.App.Services
@using Moonlight.App.Services.Sessions
@using Moonlight.Shared.Components.Xterm @using Moonlight.Shared.Components.Xterm
@using Moonlight.Shared.Components.ServerControl @using Moonlight.Shared.Components.ServerControl
@using Newtonsoft.Json @using Newtonsoft.Json
@@ -20,6 +21,7 @@
@inject EventSystem Event @inject EventSystem Event
@inject ServerService ServerService @inject ServerService ServerService
@inject NavigationManager NavigationManager @inject NavigationManager NavigationManager
@inject DynamicBackgroundService DynamicBackgroundService
@implements IDisposable @implements IDisposable
@@ -291,6 +293,11 @@
return Task.CompletedTask; return Task.CompletedTask;
}); });
if (string.IsNullOrEmpty(Image.BackgroundImageUrl))
await DynamicBackgroundService.Reset();
else
await DynamicBackgroundService.Change(Image.BackgroundImageUrl);
} }
} }
else else