diff --git a/.gitignore b/.gitignore
index 86d943a..7a4b137 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,8 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
+bin/
+obj/
+
# compiled output
/dist
/tmp
diff --git a/Kyoo.WebApp.csproj b/Kyoo.WebApp.csproj
new file mode 100644
index 0000000..c12907a
--- /dev/null
+++ b/Kyoo.WebApp.csproj
@@ -0,0 +1,62 @@
+
+
+ net5.0
+ true
+ Latest
+ false
+ $(DefaultItemExcludes);$(SpaRoot)node_modules/**
+ ./
+
+
+ false
+
+ SDG
+ Zoe Roux
+ https://github.com/AnonymusRaccoon/Kyoo
+ default
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ wwwroot/%(DistFiles.Filename)%(DistFiles.Extension)
+ PreserveNewest
+ true
+
+
+
+
+
+
+
+ wwwroot/%(StaticFiles.RecursiveDir)%(StaticFiles.Filename)%(StaticFiles.Extension)
+ PreserveNewest
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WebAppModule.cs b/WebAppModule.cs
new file mode 100644
index 0000000..6870569
--- /dev/null
+++ b/WebAppModule.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Kyoo.Controllers;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.AspNetCore.SpaServices.AngularCli;
+using Microsoft.AspNetCore.StaticFiles;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.FileProviders;
+using Microsoft.Extensions.Hosting;
+
+namespace Kyoo.WebApp
+{
+ ///
+ /// A module to enable the web-app (the front-end of kyoo).
+ ///
+ public class WebAppModule : IPlugin
+ {
+ ///
+ public string Slug => "webapp";
+
+ ///
+ public string Name => "WebApp";
+
+ ///
+ public string Description => "A module to enable the web-app (the front-end of kyoo).";
+
+ ///
+ public Dictionary Configuration => new();
+
+
+ ///
+ public void Configure(IServiceCollection services)
+ {
+ services.AddSpaStaticFiles(x =>
+ {
+ x.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
+ });
+ }
+
+ ///
+ public IEnumerable ConfigureSteps => new IStartupAction[]
+ {
+ SA.New((app, env) =>
+ {
+ if (!env.IsDevelopment())
+ app.UseSpaStaticFiles();
+ }, SA.StaticFiles),
+ SA.New((app, contentTypeProvider) =>
+ {
+ app.UseStaticFiles(new StaticFileOptions
+ {
+ ContentTypeProvider = contentTypeProvider,
+ FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
+ });
+ }, SA.StaticFiles),
+ SA.New(app =>
+ {
+ app.Use((ctx, next) =>
+ {
+ ctx.Response.Headers.Remove("X-Powered-By");
+ ctx.Response.Headers.Remove("Server");
+ ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen");
+ ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self' blob:; script-src 'self' blob: 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; frame-src 'self'");
+ ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
+ ctx.Response.Headers.Add("Referrer-Policy", "no-referrer");
+ ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null");
+ ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff");
+ return next();
+ });
+ }, SA.Endpoint - 499),
+ SA.New((app, env) =>
+ {
+ app.UseSpa(spa =>
+ {
+ spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp");
+
+ if (env.IsDevelopment())
+ spa.UseAngularCliServer("start");
+ });
+ }, SA.Endpoint - 500)
+ };
+ }
+}
\ No newline at end of file