Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca05f105cf | ||
|
|
cd4d278ceb | ||
|
|
732fbdd46a | ||
|
|
a308a067d4 | ||
|
|
f33b218b17 | ||
|
|
6a58275681 | ||
|
|
eeba837009 | ||
|
|
8098368660 | ||
|
|
863ac22036 | ||
|
|
718342d532 |
18
.github/workflows/test-docker-build.yml
vendored
Normal file
18
.github/workflows/test-docker-build.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
name: Test Build
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "main" ]
|
||||||
|
pull_request:
|
||||||
|
types:
|
||||||
|
- closed
|
||||||
|
branches: [ "main" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Build Docker image
|
||||||
|
run: docker build -t moonlightpanel/moonlight:${{ github.sha }} -f Moonlight/Dockerfile .
|
||||||
@@ -8,16 +8,22 @@ using MySql.Data.MySqlClient;
|
|||||||
|
|
||||||
namespace Moonlight.App.Helpers;
|
namespace Moonlight.App.Helpers;
|
||||||
|
|
||||||
public class DatabaseCheckup
|
public class DatabaseCheckupService
|
||||||
{
|
{
|
||||||
public static void Perform()
|
private readonly ConfigService ConfigService;
|
||||||
|
|
||||||
|
public DatabaseCheckupService(ConfigService configService)
|
||||||
{
|
{
|
||||||
// This will also copy all default config files
|
ConfigService = configService;
|
||||||
var context = new DataContext(new ConfigService(new StorageService()));
|
}
|
||||||
|
|
||||||
|
public async Task Perform()
|
||||||
|
{
|
||||||
|
var context = new DataContext(ConfigService);
|
||||||
|
|
||||||
Logger.Info("Checking database");
|
Logger.Info("Checking database");
|
||||||
|
|
||||||
if (!context.Database.CanConnect())
|
if (!await context.Database.CanConnectAsync())
|
||||||
{
|
{
|
||||||
Logger.Fatal("-----------------------------------------------");
|
Logger.Fatal("-----------------------------------------------");
|
||||||
Logger.Fatal("Unable to connect to mysql database");
|
Logger.Fatal("Unable to connect to mysql database");
|
||||||
@@ -32,19 +38,19 @@ public class DatabaseCheckup
|
|||||||
|
|
||||||
Logger.Info("Checking for pending migrations");
|
Logger.Info("Checking for pending migrations");
|
||||||
|
|
||||||
var migrations = context.Database
|
var migrations = (await context.Database
|
||||||
.GetPendingMigrations()
|
.GetPendingMigrationsAsync())
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
if (migrations.Any())
|
if (migrations.Any())
|
||||||
{
|
{
|
||||||
Logger.Info($"{migrations.Length} migrations pending. Updating now");
|
Logger.Info($"{migrations.Length} migrations pending. Updating now");
|
||||||
|
|
||||||
BackupDatabase();
|
await BackupDatabase();
|
||||||
|
|
||||||
Logger.Info("Applying migrations");
|
Logger.Info("Applying migrations");
|
||||||
|
|
||||||
context.Database.Migrate();
|
await context.Database.MigrateAsync();
|
||||||
|
|
||||||
Logger.Info("Successfully applied migrations");
|
Logger.Info("Successfully applied migrations");
|
||||||
}
|
}
|
||||||
@@ -54,7 +60,7 @@ public class DatabaseCheckup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void BackupDatabase()
|
public async Task BackupDatabase()
|
||||||
{
|
{
|
||||||
Logger.Info("Creating backup from database");
|
Logger.Info("Creating backup from database");
|
||||||
|
|
||||||
@@ -79,14 +85,14 @@ public class DatabaseCheckup
|
|||||||
var sw = new Stopwatch();
|
var sw = new Stopwatch();
|
||||||
sw.Start();
|
sw.Start();
|
||||||
|
|
||||||
using MySqlConnection conn = new MySqlConnection(connectionString);
|
await using MySqlConnection conn = new MySqlConnection(connectionString);
|
||||||
using MySqlCommand cmd = new MySqlCommand();
|
await using MySqlCommand cmd = new MySqlCommand();
|
||||||
using MySqlBackup mb = new MySqlBackup(cmd);
|
using MySqlBackup mb = new MySqlBackup(cmd);
|
||||||
|
|
||||||
cmd.Connection = conn;
|
cmd.Connection = conn;
|
||||||
conn.Open();
|
await conn.OpenAsync();
|
||||||
mb.ExportToFile(file);
|
mb.ExportToFile(file);
|
||||||
conn.Close();
|
await conn.CloseAsync();
|
||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
Logger.Info($"Done. {sw.Elapsed.TotalSeconds}s");
|
Logger.Info($"Done. {sw.Elapsed.TotalSeconds}s");
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Moonlight.App.ApiClients.Wings;
|
||||||
|
using Moonlight.App.ApiClients.Wings.Resources;
|
||||||
|
using Moonlight.App.Database.Entities;
|
||||||
|
using Moonlight.App.Http.Requests.DiscordBot.Requests;
|
||||||
|
using Moonlight.App.Repositories;
|
||||||
|
using Moonlight.App.Services;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Http.Controllers.Api.Moonlight;
|
||||||
|
|
||||||
|
[ApiController]
|
||||||
|
[Route("api/moonlight/discordbot")]
|
||||||
|
public class DiscordBotController : Controller
|
||||||
|
{
|
||||||
|
private readonly Repository<User> UserRepository;
|
||||||
|
private readonly Repository<Server> ServerRepository;
|
||||||
|
private readonly ServerService ServerService;
|
||||||
|
private readonly string Token = "";
|
||||||
|
private readonly bool Enable;
|
||||||
|
|
||||||
|
public DiscordBotController(
|
||||||
|
Repository<User> userRepository,
|
||||||
|
Repository<Server> serverRepository,
|
||||||
|
ServerService serverService,
|
||||||
|
ConfigService configService)
|
||||||
|
{
|
||||||
|
UserRepository = userRepository;
|
||||||
|
ServerRepository = serverRepository;
|
||||||
|
ServerService = serverService;
|
||||||
|
|
||||||
|
var config = configService
|
||||||
|
.GetSection("Moonlight")
|
||||||
|
.GetSection("DiscordBotApi");
|
||||||
|
|
||||||
|
Enable = config.GetValue<bool>("Enable");
|
||||||
|
|
||||||
|
if (Enable)
|
||||||
|
{
|
||||||
|
Token = config.GetValue<string>("Token");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}/link")]
|
||||||
|
public async Task<ActionResult> GetLink(ulong id)
|
||||||
|
{
|
||||||
|
if (!await IsAuth(Request))
|
||||||
|
return StatusCode(403);
|
||||||
|
|
||||||
|
if (await GetUserFromDiscordId(id) == null)
|
||||||
|
{
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}/servers")]
|
||||||
|
public async Task<ActionResult<Server[]>> GetServers(ulong id)
|
||||||
|
{
|
||||||
|
if (!await IsAuth(Request))
|
||||||
|
return StatusCode(403);
|
||||||
|
|
||||||
|
var user = await GetUserFromDiscordId(id);
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
return BadRequest();
|
||||||
|
|
||||||
|
return ServerRepository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.Include(x => x.Image)
|
||||||
|
.Where(x => x.Owner.Id == user.Id)
|
||||||
|
.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost("{id}/servers/{uuid}")]
|
||||||
|
public async Task<ActionResult> SetPowerState(ulong id, Guid uuid, [FromBody] SetPowerSignal signal)
|
||||||
|
{
|
||||||
|
if (!await IsAuth(Request))
|
||||||
|
return StatusCode(403);
|
||||||
|
|
||||||
|
var user = await GetUserFromDiscordId(id);
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
return BadRequest();
|
||||||
|
|
||||||
|
var server = ServerRepository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.FirstOrDefault(x => x.Owner.Id == user.Id && x.Uuid == uuid);
|
||||||
|
|
||||||
|
if (server == null)
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
if (Enum.TryParse(signal.Signal, true, out PowerSignal powerSignal))
|
||||||
|
{
|
||||||
|
await ServerService.SetPowerState(server, powerSignal);
|
||||||
|
return Ok();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return BadRequest();
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{id}/servers/{uuid}")]
|
||||||
|
public async Task<ActionResult<ServerDetails>> GetServerDetails(ulong id, Guid uuid)
|
||||||
|
{
|
||||||
|
if (!await IsAuth(Request))
|
||||||
|
return StatusCode(403);
|
||||||
|
|
||||||
|
var user = await GetUserFromDiscordId(id);
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
return BadRequest();
|
||||||
|
|
||||||
|
var server = ServerRepository
|
||||||
|
.Get()
|
||||||
|
.Include(x => x.Owner)
|
||||||
|
.FirstOrDefault(x => x.Owner.Id == user.Id && x.Uuid == uuid);
|
||||||
|
|
||||||
|
if (server == null)
|
||||||
|
return NotFound();
|
||||||
|
|
||||||
|
return await ServerService.GetDetails(server);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<User?> GetUserFromDiscordId(ulong discordId)
|
||||||
|
{
|
||||||
|
var user = UserRepository
|
||||||
|
.Get()
|
||||||
|
.FirstOrDefault(x => x.DiscordId == discordId);
|
||||||
|
|
||||||
|
return Task.FromResult(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Task<bool> IsAuth(HttpRequest request)
|
||||||
|
{
|
||||||
|
if (!Enable)
|
||||||
|
return Task.FromResult(false);
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(request.Headers.Authorization))
|
||||||
|
return Task.FromResult(false);
|
||||||
|
|
||||||
|
if(request.Headers.Authorization == Token)
|
||||||
|
return Task.FromResult(true);
|
||||||
|
|
||||||
|
return Task.FromResult(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
using Logging.Net;
|
using System.Text;
|
||||||
|
using Logging.Net;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Moonlight.App.Helpers;
|
using Moonlight.App.Helpers;
|
||||||
using Moonlight.App.Models.Misc;
|
using Moonlight.App.Models.Misc;
|
||||||
using Moonlight.App.Services;
|
using Moonlight.App.Services;
|
||||||
using Moonlight.App.Services.Files;
|
using Moonlight.App.Services.Files;
|
||||||
using Moonlight.App.Services.LogServices;
|
using Moonlight.App.Services.LogServices;
|
||||||
|
using Moonlight.App.Services.Sessions;
|
||||||
|
|
||||||
namespace Moonlight.App.Http.Controllers.Api.Moonlight;
|
namespace Moonlight.App.Http.Controllers.Api.Moonlight;
|
||||||
|
|
||||||
@@ -14,12 +16,14 @@ public class ResourcesController : Controller
|
|||||||
{
|
{
|
||||||
private readonly SecurityLogService SecurityLogService;
|
private readonly SecurityLogService SecurityLogService;
|
||||||
private readonly BucketService BucketService;
|
private readonly BucketService BucketService;
|
||||||
|
private readonly BundleService BundleService;
|
||||||
|
|
||||||
public ResourcesController(SecurityLogService securityLogService,
|
public ResourcesController(SecurityLogService securityLogService,
|
||||||
BucketService bucketService)
|
BucketService bucketService, BundleService bundleService)
|
||||||
{
|
{
|
||||||
SecurityLogService = securityLogService;
|
SecurityLogService = securityLogService;
|
||||||
BucketService = bucketService;
|
BucketService = bucketService;
|
||||||
|
BundleService = bundleService;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("images/{name}")]
|
[HttpGet("images/{name}")]
|
||||||
@@ -73,4 +77,34 @@ public class ResourcesController : Controller
|
|||||||
return Problem();
|
return Problem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet("bundle/js")]
|
||||||
|
public Task<ActionResult> GetJs()
|
||||||
|
{
|
||||||
|
if (BundleService.BundledFinished)
|
||||||
|
{
|
||||||
|
return Task.FromResult<ActionResult>(
|
||||||
|
File(Encoding.ASCII.GetBytes(BundleService.BundledJs), "text/javascript")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult<ActionResult>(
|
||||||
|
NotFound()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("bundle/css")]
|
||||||
|
public Task<ActionResult> GetCss()
|
||||||
|
{
|
||||||
|
if (BundleService.BundledFinished)
|
||||||
|
{
|
||||||
|
return Task.FromResult<ActionResult>(
|
||||||
|
File(Encoding.ASCII.GetBytes(BundleService.BundledCss), "text/css")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.FromResult<ActionResult>(
|
||||||
|
NotFound()
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
using Moonlight.App.ApiClients.Wings;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Http.Requests.DiscordBot.Requests;
|
||||||
|
|
||||||
|
public class SetPowerSignal
|
||||||
|
{
|
||||||
|
public string Signal { get; set; }
|
||||||
|
}
|
||||||
129
Moonlight/App/Services/Sessions/BundleService.cs
Normal file
129
Moonlight/App/Services/Sessions/BundleService.cs
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
using Logging.Net;
|
||||||
|
|
||||||
|
namespace Moonlight.App.Services.Sessions;
|
||||||
|
|
||||||
|
public class BundleService
|
||||||
|
{
|
||||||
|
public BundleService(ConfigService configService)
|
||||||
|
{
|
||||||
|
var url = configService
|
||||||
|
.GetSection("Moonlight")
|
||||||
|
.GetValue<string>("AppUrl");
|
||||||
|
|
||||||
|
#region JS
|
||||||
|
|
||||||
|
JsFiles = new();
|
||||||
|
|
||||||
|
JsFiles.AddRange(new[]
|
||||||
|
{
|
||||||
|
url + "/_framework/blazor.server.js",
|
||||||
|
url + "/assets/plugins/global/plugins.bundle.js",
|
||||||
|
url + "/_content/XtermBlazor/XtermBlazor.min.js",
|
||||||
|
url + "/_content/BlazorTable/BlazorTable.min.js",
|
||||||
|
url + "/_content/CurrieTechnologies.Razor.SweetAlert2/sweetAlert2.min.js",
|
||||||
|
url + "/_content/Blazor.ContextMenu/blazorContextMenu.min.js",
|
||||||
|
"https://www.google.com/recaptcha/api.js",
|
||||||
|
"https://cdn.jsdelivr.net/npm/xterm-addon-fit@0.5.0/lib/xterm-addon-fit.min.js",
|
||||||
|
"https://cdn.jsdelivr.net/npm/xterm-addon-search@0.8.2/lib/xterm-addon-search.min.js",
|
||||||
|
"https://cdn.jsdelivr.net/npm/xterm-addon-web-links@0.5.0/lib/xterm-addon-web-links.min.js",
|
||||||
|
url + "/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js",
|
||||||
|
"require.config({ paths: { 'vs': '/_content/BlazorMonaco/lib/monaco-editor/min/vs' } });",
|
||||||
|
url + "/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js",
|
||||||
|
url + "/_content/BlazorMonaco/jsInterop.js",
|
||||||
|
url + "/assets/js/scripts.bundle.js",
|
||||||
|
url + "/assets/js/moonlight.js",
|
||||||
|
"moonlight.loading.registerXterm();",
|
||||||
|
url + "/_content/Blazor-ApexCharts/js/apex-charts.min.js",
|
||||||
|
url + "/_content/Blazor-ApexCharts/js/blazor-apex-charts.js"
|
||||||
|
});
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region CSS
|
||||||
|
|
||||||
|
CssFiles = new();
|
||||||
|
|
||||||
|
CssFiles.AddRange(new[]
|
||||||
|
{
|
||||||
|
"https://fonts.googleapis.com/css?family=Poppins:300,400,500,600,700",
|
||||||
|
url + "/assets/css/style.bundle.css",
|
||||||
|
url + "/assets/css/flashbang.css",
|
||||||
|
url + "/assets/css/snow.css",
|
||||||
|
url + "/assets/css/utils.css",
|
||||||
|
url + "/assets/css/blazor.css",
|
||||||
|
url + "/_content/XtermBlazor/XtermBlazor.css",
|
||||||
|
url + "/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.css",
|
||||||
|
url + "/_content/Blazor.ContextMenu/blazorContextMenu.min.css",
|
||||||
|
url + "/assets/plugins/global/plugins.bundle.css"
|
||||||
|
});
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
CacheId = Guid.NewGuid().ToString();
|
||||||
|
|
||||||
|
Task.Run(Bundle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Javascript
|
||||||
|
public string BundledJs { get; private set; }
|
||||||
|
public readonly List<string> JsFiles;
|
||||||
|
|
||||||
|
// CSS
|
||||||
|
public string BundledCss { get; private set; }
|
||||||
|
public readonly List<string> CssFiles;
|
||||||
|
|
||||||
|
// States
|
||||||
|
public string CacheId { get; private set; }
|
||||||
|
public bool BundledFinished { get; set; } = false;
|
||||||
|
private bool IsBundling { get; set; } = false;
|
||||||
|
|
||||||
|
private async Task Bundle()
|
||||||
|
{
|
||||||
|
if (!IsBundling)
|
||||||
|
IsBundling = true;
|
||||||
|
|
||||||
|
Logger.Info("Bundling js and css files");
|
||||||
|
|
||||||
|
BundledJs = "";
|
||||||
|
BundledCss = "";
|
||||||
|
|
||||||
|
BundledJs = await BundleFiles(
|
||||||
|
JsFiles
|
||||||
|
);
|
||||||
|
|
||||||
|
BundledCss = await BundleFiles(
|
||||||
|
CssFiles
|
||||||
|
);
|
||||||
|
|
||||||
|
Logger.Info("Successfully bundled");
|
||||||
|
BundledFinished = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<string> BundleFiles(IEnumerable<string> items)
|
||||||
|
{
|
||||||
|
var bundled = "";
|
||||||
|
|
||||||
|
using HttpClient client = new HttpClient();
|
||||||
|
foreach (string item in items)
|
||||||
|
{
|
||||||
|
// Item is a url, fetch it
|
||||||
|
if (item.StartsWith("http"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var jsCode = await client.GetStringAsync(item);
|
||||||
|
bundled += jsCode + "\n";
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Warn($"Error fetching '{item}' while bundling");
|
||||||
|
Logger.Warn(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // If not, it is probably a manual addition, so add it
|
||||||
|
bundled += item + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return bundled;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,7 @@ FROM base AS final
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY --from=publish /app/publish .
|
COPY --from=publish /app/publish .
|
||||||
RUN mkdir -p /app/storage
|
RUN mkdir -p /app/storage
|
||||||
|
RUN touch /app/storage/donttriggeranyerrors
|
||||||
RUN rm -r /app/storage/*
|
RUN rm -r /app/storage/*
|
||||||
COPY "Moonlight/defaultstorage" "/app/defaultstorage"
|
COPY "Moonlight/defaultstorage" "/app/defaultstorage"
|
||||||
ENTRYPOINT ["dotnet", "Moonlight.dll"]
|
ENTRYPOINT ["dotnet", "Moonlight.dll"]
|
||||||
@@ -2,10 +2,12 @@
|
|||||||
@using Moonlight.App.Extensions
|
@using Moonlight.App.Extensions
|
||||||
@using Moonlight.App.Repositories
|
@using Moonlight.App.Repositories
|
||||||
@using Moonlight.App.Services
|
@using Moonlight.App.Services
|
||||||
|
@using Moonlight.App.Services.Sessions
|
||||||
@namespace Moonlight.Pages
|
@namespace Moonlight.Pages
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
|
|
||||||
@inject ConfigService ConfigService
|
@inject ConfigService ConfigService
|
||||||
|
@inject BundleService BundleService
|
||||||
@inject LoadingMessageRepository LoadingMessageRepository
|
@inject LoadingMessageRepository LoadingMessageRepository
|
||||||
|
|
||||||
@{
|
@{
|
||||||
@@ -36,20 +38,29 @@
|
|||||||
|
|
||||||
<link rel="shortcut icon" href="@(moonlightConfig.GetValue<string>("AppUrl"))/api/moonlight/resources/images/logo.svg"/>
|
<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"/>
|
@*This import is not in the bundle because the files it references are linked relative to the current lath*@
|
||||||
|
|
||||||
<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/utils.css"/>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/assets/css/boxicons.min.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"/>
|
@if (BundleService.BundledFinished)
|
||||||
<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"/>
|
<link rel="stylesheet" type="text/css" href="/api/moonlight/resources/bundle/css?idontwannabecached=@(BundleService.CacheId)"/>
|
||||||
|
}
|
||||||
<link href="/assets/plugins/global/plugins.bundle.css" rel="stylesheet" type="text/css"/>
|
else
|
||||||
|
{
|
||||||
|
foreach (var cssFile in BundleService.CssFiles)
|
||||||
|
{
|
||||||
|
if (cssFile.StartsWith("http"))
|
||||||
|
{
|
||||||
|
<link rel="stylesheet" type="text/css" href="@(cssFile)">
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<style>
|
||||||
|
@cssFile
|
||||||
|
</style>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||||
<base href="~/"/>
|
<base href="~/"/>
|
||||||
@@ -95,33 +106,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/_framework/blazor.server.js"></script>
|
@if (BundleService.BundledFinished)
|
||||||
<script src="/assets/plugins/global/plugins.bundle.js"></script>
|
{
|
||||||
<script src="/_content/XtermBlazor/XtermBlazor.min.js"></script>
|
<script src="/api/moonlight/resources/bundle/js?idontwannabecached=@(BundleService.CacheId)">
|
||||||
<script src="/_content/BlazorTable/BlazorTable.min.js"></script>
|
|
||||||
<script src="/_content/BlazorInputFile/inputfile.js"></script>
|
|
||||||
<script src="/_content/CurrieTechnologies.Razor.SweetAlert2/sweetAlert2.min.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="/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
|
|
||||||
<script>require.config({ paths: { 'vs': '/_content/BlazorMonaco/lib/monaco-editor/min/vs' } });</script>
|
|
||||||
<script src="/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
|
|
||||||
<script src="/_content/BlazorMonaco/jsInterop.js"></script>
|
|
||||||
|
|
||||||
<script src="/assets/js/scripts.bundle.js"></script>
|
|
||||||
<script src="/assets/js/moonlight.js"></script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
moonlight.loading.registerXterm();
|
|
||||||
</script>
|
</script>
|
||||||
|
}
|
||||||
<script src="_content/Blazor-ApexCharts/js/apex-charts.min.js"></script>
|
else
|
||||||
<script src="_content/Blazor-ApexCharts/js/blazor-apex-charts.js"></script>
|
{
|
||||||
|
foreach (var jsFile in BundleService.JsFiles)
|
||||||
|
{
|
||||||
|
if (jsFile.StartsWith("http"))
|
||||||
|
{
|
||||||
|
<script src="@(jsFile)"></script>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
@Html.Raw("<script>" + jsFile +"</script>")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -34,13 +34,19 @@ namespace Moonlight
|
|||||||
// App version. Change for release
|
// App version. Change for release
|
||||||
public static readonly string AppVersion = $"InDev {Formatter.FormatDateOnly(DateTime.Now.Date)}";
|
public static readonly string AppVersion = $"InDev {Formatter.FormatDateOnly(DateTime.Now.Date)}";
|
||||||
|
|
||||||
public static void Main(string[] args)
|
public static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
Logger.UsedLogger = new CacheLogger();
|
Logger.UsedLogger = new CacheLogger();
|
||||||
|
|
||||||
Logger.Info($"Working dir: {Directory.GetCurrentDirectory()}");
|
Logger.Info($"Working dir: {Directory.GetCurrentDirectory()}");
|
||||||
|
|
||||||
DatabaseCheckup.Perform();
|
Logger.Info("Running pre-init tasks");
|
||||||
|
|
||||||
|
// This will also copy all default config files
|
||||||
|
var configService = new ConfigService(new StorageService());
|
||||||
|
var databaseCheckupService = new DatabaseCheckupService(configService);
|
||||||
|
|
||||||
|
await databaseCheckupService.Perform();
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@@ -121,6 +127,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.AddSingleton<BundleService>();
|
||||||
|
|
||||||
builder.Services.AddScoped<SubscriptionService>();
|
builder.Services.AddScoped<SubscriptionService>();
|
||||||
builder.Services.AddScoped<SubscriptionAdminService>();
|
builder.Services.AddScoped<SubscriptionAdminService>();
|
||||||
@@ -189,7 +196,7 @@ namespace Moonlight
|
|||||||
// Discord bot service
|
// Discord bot service
|
||||||
//var discordBotService = app.Services.GetRequiredService<DiscordBotService>();
|
//var discordBotService = app.Services.GetRequiredService<DiscordBotService>();
|
||||||
|
|
||||||
app.Run();
|
await app.RunAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -194,10 +194,10 @@
|
|||||||
if(IsIpBanned)
|
if(IsIpBanned)
|
||||||
await InvokeAsync(StateHasChanged);
|
await InvokeAsync(StateHasChanged);
|
||||||
|
|
||||||
await Event.On<Object>("ipBan.update", this, async o =>
|
await Event.On<Object>("ipBan.update", this, async _ =>
|
||||||
{
|
{
|
||||||
IsIpBanned = await IpBanService.IsBanned();
|
IsIpBanned = await IpBanService.IsBanned();
|
||||||
await InvokeAsync(StateHasChanged);
|
NavigationManager.NavigateTo(NavigationManager.Uri, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
User = await IdentityService.Get();
|
User = await IdentityService.Get();
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
"Port": "10324",
|
"Port": "10324",
|
||||||
"Username": "user_name"
|
"Username": "user_name"
|
||||||
},
|
},
|
||||||
|
"DiscordBotApi": {
|
||||||
|
"Enable": false,
|
||||||
|
"Token": "you api key here"
|
||||||
|
},
|
||||||
"DiscordBot": {
|
"DiscordBot": {
|
||||||
"Enable": false,
|
"Enable": false,
|
||||||
"Token": "Discord.Token.Here",
|
"Token": "Discord.Token.Here",
|
||||||
|
|||||||
Reference in New Issue
Block a user