Browse Source

Merge pull request #65 from Moonlight-Panel/PersistentStorage

Persistent storage
Marcel Baumgartner 2 years ago
parent
commit
8903f95a80

+ 3 - 1
.gitignore

@@ -38,4 +38,6 @@ _UpgradeReport_Files/
 Thumbs.db
 Thumbs.db
 Desktop.ini
 Desktop.ini
 .DS_Store
 .DS_Store
-.idea/.idea.Moonlight/.idea/discord.xml
+.idea/.idea.Moonlight/.idea/discord.xml
+
+storage/

+ 28 - 0
Moonlight/App/Helpers/PathBuilder.cs

@@ -0,0 +1,28 @@
+namespace Moonlight.App.Helpers;
+
+public class PathBuilder
+{
+    public static string Dir(params string[] parts)
+    {
+        var res = "";
+
+        foreach (var part in parts)
+        {
+            res += part + Path.DirectorySeparatorChar;
+        }
+
+        return res;
+    }
+    
+    public static string File(params string[] parts)
+    {
+        var res = "";
+
+        foreach (var part in parts)
+        {
+            res += part + (part == parts.Last() ? "" : Path.DirectorySeparatorChar);
+        }
+
+        return res;
+    }
+}

+ 2 - 2
Moonlight/App/Helpers/SmartTranslateHelper.cs

@@ -8,7 +8,7 @@ public class SmartTranslateHelper
     {
     {
         Languages = new();
         Languages = new();
         
         
-        foreach (var file in Directory.GetFiles("resources/lang"))
+        foreach (var file in Directory.GetFiles(PathBuilder.Dir("storage", "resources", "lang")))
         {
         {
             if (Path.GetExtension(file) == ".lang")
             if (Path.GetExtension(file) == ".lang")
             {
             {
@@ -40,7 +40,7 @@ public class SmartTranslateHelper
         {
         {
             Languages[langKey].Add(content, content);
             Languages[langKey].Add(content, content);
             
             
-            File.WriteAllLines($"resources/lang/{langKey}.lang", GenerateData(Languages[langKey]));
+            File.WriteAllLines(PathBuilder.File("storage", "resources", "lang", $"{langKey}.lang"), GenerateData(Languages[langKey]));
         }
         }
 
 
         return Languages[langKey][content];
         return Languages[langKey][content];

+ 4 - 4
Moonlight/App/Http/Controllers/Api/Moonlight/ResourcesController.cs

@@ -1,5 +1,6 @@
 using Logging.Net;
 using Logging.Net;
 using Microsoft.AspNetCore.Mvc;
 using Microsoft.AspNetCore.Mvc;
+using Moonlight.App.Helpers;
 using Moonlight.App.Models.Misc;
 using Moonlight.App.Models.Misc;
 using Moonlight.App.Services.LogServices;
 using Moonlight.App.Services.LogServices;
 
 
@@ -28,14 +29,13 @@ public class ResourcesController : Controller
             return NotFound();
             return NotFound();
         }
         }
 
 
-        if (System.IO.File.Exists($"resources/public/images/{name}"))
+        if (System.IO.File.Exists(PathBuilder.File("storage", "resources", "public", "images", name)))
         {
         {
-            var fs = new FileStream($"resources/public/images/{name}", FileMode.Open);
+            var fs = new FileStream(PathBuilder.File("storage", "resources", "public", "images", name), FileMode.Open);
         
         
             return File(fs, MimeTypes.GetMimeType(name), name);
             return File(fs, MimeTypes.GetMimeType(name), name);
         }
         }
-        
-        Logger.Debug("404 on resources");
+
         return NotFound();
         return NotFound();
     }
     }
 }
 }

+ 26 - 8
Moonlight/App/Services/ConfigService.cs

@@ -7,26 +7,44 @@ namespace Moonlight.App.Services;
 
 
 public class ConfigService : IConfiguration
 public class ConfigService : IConfiguration
 {
 {
+    private readonly StorageService StorageService;
+
     private IConfiguration Configuration;
     private IConfiguration Configuration;
 
 
     public bool DebugMode { get; private set; } = false;
     public bool DebugMode { get; private set; } = false;
-    
-    public ConfigService()
+
+    public ConfigService(StorageService storageService)
     {
     {
-        Configuration = new ConfigurationBuilder().AddJsonStream(
-            new MemoryStream(Encoding.ASCII.GetBytes(File.ReadAllText("..\\..\\appsettings.json")))
-        ).Build();
+        StorageService = storageService;
+        StorageService.EnsureCreated();
+
+        Reload();
 
 
         // Env vars
         // Env vars
         var debugVar = Environment.GetEnvironmentVariable("ML_DEBUG");
         var debugVar = Environment.GetEnvironmentVariable("ML_DEBUG");
 
 
         if (debugVar != null)
         if (debugVar != null)
             DebugMode = bool.Parse(debugVar);
             DebugMode = bool.Parse(debugVar);
-        
-        if(DebugMode)
+
+        if (DebugMode)
             Logger.Debug("Debug mode enabled");
             Logger.Debug("Debug mode enabled");
     }
     }
-    
+
+    public void Reload()
+    {
+        Logger.Info($"Reading config from '{PathBuilder.File("storage", "configs", "config.json")}'");
+        
+        Configuration = new ConfigurationBuilder().AddJsonStream(
+            new MemoryStream(Encoding.ASCII.GetBytes(
+                    File.ReadAllText(
+                        PathBuilder.File("storage", "configs", "config.json")
+                    )
+                )
+            )).Build();
+
+        Logger.Info("Reloaded configuration file");
+    }
+
     public IEnumerable<IConfigurationSection> GetChildren()
     public IEnumerable<IConfigurationSection> GetChildren()
     {
     {
         return Configuration.GetChildren();
         return Configuration.GetChildren();

+ 58 - 0
Moonlight/App/Services/StorageService.cs

@@ -0,0 +1,58 @@
+using Logging.Net;
+using Moonlight.App.Helpers;
+
+namespace Moonlight.App.Services;
+
+public class StorageService
+{
+    public StorageService()
+    {
+        EnsureCreated();
+    }
+    
+    public void EnsureCreated()
+    {
+        Directory.CreateDirectory(PathBuilder.Dir("storage", "uploads"));
+        Directory.CreateDirectory(PathBuilder.Dir("storage", "configs"));
+        Directory.CreateDirectory(PathBuilder.Dir("storage", "resources"));
+        
+        if(IsEmpty(PathBuilder.Dir("storage", "resources")))
+        {
+            Logger.Info("Default resources not found. Copying default resources");
+            
+            CopyFilesRecursively(
+                PathBuilder.Dir("defaultstorage", "resources"), 
+                PathBuilder.Dir("storage", "resources")
+            );
+        }
+
+        if (IsEmpty(PathBuilder.Dir("storage", "configs")))
+        {
+            Logger.Info("Default configs not found. Copying default configs");
+            
+            CopyFilesRecursively(
+                PathBuilder.Dir("defaultstorage", "configs"), 
+                PathBuilder.Dir("storage", "configs")
+            );
+        }
+    }
+
+    private bool IsEmpty(string path)
+    {
+        return !Directory.EnumerateFiles(path).Any();
+    }
+    private static void CopyFilesRecursively(string sourcePath, string targetPath)
+    {
+        //Now Create all of the directories
+        foreach (string dirPath in Directory.GetDirectories(sourcePath, "*", SearchOption.AllDirectories))
+        {
+            Directory.CreateDirectory(dirPath.Replace(sourcePath, targetPath));
+        }
+
+        //Copy all the files & Replaces any files with the same name
+        foreach (string newPath in Directory.GetFiles(sourcePath, "*.*",SearchOption.AllDirectories))
+        {
+            File.Copy(newPath, newPath.Replace(sourcePath, targetPath), true);
+        }
+    }
+}

+ 2 - 0
Moonlight/Dockerfile

@@ -19,4 +19,6 @@ RUN dotnet publish "Moonlight.csproj" -c Release -o /app/publish
 FROM base AS final
 FROM base AS final
 WORKDIR /app
 WORKDIR /app
 COPY --from=publish /app/publish .
 COPY --from=publish /app/publish .
+RUN mkdir /app/storage
+RUN rm -r /app/storage/*
 ENTRYPOINT ["dotnet", "Moonlight.dll"]
 ENTRYPOINT ["dotnet", "Moonlight.dll"]

+ 1 - 0
Moonlight/Program.cs

@@ -74,6 +74,7 @@ namespace Moonlight
             
             
             // Services
             // Services
             builder.Services.AddSingleton<ConfigService>();
             builder.Services.AddSingleton<ConfigService>();
+            builder.Services.AddSingleton<StorageService>();
             builder.Services.AddScoped<CookieService>();
             builder.Services.AddScoped<CookieService>();
             builder.Services.AddScoped<IdentityService>();
             builder.Services.AddScoped<IdentityService>();
             builder.Services.AddScoped<IpLocateService>();
             builder.Services.AddScoped<IpLocateService>();

+ 13 - 0
Moonlight/README.md

@@ -0,0 +1,13 @@
+### Some explanations
+
+defaultstorage:
+
+This directory is for the default assets of a moonlight instance, e.g. lang files, images etc
+
+storage:
+
+This directory is empty in fresh moonlight instances and will be populated with example config upon first run.
+Before using moonlight this config file has to be modified.
+Also resources are going to be copied from the default storage to this storage.
+To access files in this storage we recommend to use the PathBuilder functions to ensure cross platform compatibility.
+The storage directory should be mounted to a specific path when using docker container so when the container is replaced/rebuild your storage will not be modified

+ 3 - 2
Moonlight/Shared/Views/Admin/Sys/Resources.razor

@@ -3,12 +3,13 @@
 @using Moonlight.Shared.Components.FileManagerPartials
 @using Moonlight.Shared.Components.FileManagerPartials
 @using Moonlight.App.Helpers.Files
 @using Moonlight.App.Helpers.Files
 @using Moonlight.Shared.Components.Navigations
 @using Moonlight.Shared.Components.Navigations
+@using Moonlight.App.Helpers
 
 
 <OnlyAdmin>
 <OnlyAdmin>
     <AdminSystemNavigation Index="5" />
     <AdminSystemNavigation Index="5" />
     
     
     <div class="card card-body">
     <div class="card card-body">
-        <FileManager Access="@(new HostFileAccess("resources"))">
-        </FileManager>        
+        <FileManager Access="@(new HostFileAccess(PathBuilder.Dir("storage")))">
+        </FileManager>
     </div>
     </div>
 </OnlyAdmin>
 </OnlyAdmin>

+ 78 - 0
Moonlight/defaultstorage/configs/config.json

@@ -0,0 +1,78 @@
+{
+  "Moonlight": {
+    "AppUrl": "http://your-moonlight-url.test",
+    "Database": {
+      "Database": "database_name",
+      "Host": "your-moonlight-database-host.de",
+      "Password": "s3cr3t",
+      "Port": "10324",
+      "Username": "user_name"
+    },
+    "DiscordBot": {
+      "Enable": "True",
+      "Token": "Discord.Token.Here"
+    },
+    "Domains": {
+      "_comment": "Cloudflare Api Credentials",
+      "AccountId": "Account Id here",
+      "Email": "Cloudflare Email here",
+      "Key": "Api Key Here"
+    },
+    "Html": {
+      "Headers": {
+        "Color": "#4b27e8",
+        "Description": "the next generation hosting panel",
+        "Keywords": "moonlight",
+        "Title": "Moonlight - moonlight.tld"
+      }
+    },
+    "Marketing": {
+      "BrandName": "My cool project",
+      "Imprint": "https://mycoolproject.de/imprint",
+      "Privacy": "https://mycoolproject.de/privacy",
+      "Website": "https://mycoolproject.de/"
+    },
+    "OAuth2": {
+      "Discord": {
+        "ClientId": "10324",
+        "ClientSecret": "s3cr3t",
+        "Enable": "True"
+      },
+      "Google": {
+        "ClientId": "xyz.apps.googleusercontent.com",
+        "ClientSecret": "s3cr3t",
+        "Enable": "True"
+      },
+      "EnableOverrideUrl": "True",
+      "OverrideUrl": "http://your-moonlight-url.test"
+    },
+    "Security": {
+      "Token": "RANDOM UUID HERE"
+    },
+    "SetupComplete": "True",
+    "SupportChat": {
+      "Enabled": "True"
+    },
+    "Mail": {
+      "Email": "no-reply@mycoolproject.de",
+      "Server": "mycoolproject.de",
+      "Password": "s3cr3t",
+      "Port": 25
+    },
+    "Cleanup": {
+      "Cpu": 90,
+      "Memory": 8192,
+      "Wait": 15,
+      "Uptime": 6,
+      "Enable": false,
+      "MinUptime": 10
+    },
+    "Subscriptions": {
+      "_comment": "Not implemented",
+      "SellPass": {
+        "Enable": false,
+        "Url": ""
+      }
+    }
+  }
+}

+ 567 - 0
Moonlight/defaultstorage/resources/lang/de_de.lang

@@ -0,0 +1,567 @@
+Open support;Open support
+About us;About us
+Imprint;Imprint
+Privacy;Privacy
+Login;Login
+Register;Register
+Insert brand name...;Insert brand name...
+Save and continue;Save and continue
+Saving;Saving
+Configure basics;Configure basics
+Brand name;Brand name
+test;test
+Insert first name...;Insert first name...
+Insert last name...;Insert last name...
+Insert email address...;Insert email address...
+Add;Add
+Adding...;Adding...
+Add admin accounts;Add admin accounts
+First name;First name
+Last name;Last name
+Email address;Email address
+Enter password;Enter password
+Next;Next
+Back;Back
+Configure features;Configure features
+Support chat;Support chat
+Finish;Finish
+Finalize installation;Finalize installation
+Moonlight basic settings successfully configured;Moonlight basic settings successfully configured
+Ooops. This page is crashed;Ooops. This page is crashed
+This page is crashed. The error has been reported to the moonlight team. Meanwhile you can try reloading the page;This page is crashed. The error has been reported to the moonlight team. Meanwhile you can try reloading the page
+Setup complete;Setup complete
+It looks like this moonlight instance is ready to go;It looks like this moonlight instance is ready to go
+User successfully created;User successfully created
+Ooops. Your moonlight client is crashed;Ooops. Your moonlight client is crashed
+This error has been reported to the moonlight team;This error has been reported to the moonlight team
+Sign In;Sign In
+Sign in to start with moonlight;Sign in to start with moonlight
+Sign in with Discord;Sign in with Discord
+Or with email;Or with email
+Forgot password?;Forgot password?
+Sign-in;Sign-in
+Not registered yet?;Not registered yet?
+Sign up;Sign up
+Authenticating;Authenticating
+Sign in with Google;Sign in with Google
+Working;Working
+Error;Error
+Email and password combination not found;Email and password combination not found
+Email;Email
+Password;Password
+Account settings;Account settings
+Logout;Logout
+Dashboard;Dashboard
+Order;Order
+Website;Website
+Database;Database
+Domain;Domain
+Servers;Servers
+Websites;Websites
+Databases;Databases
+Domains;Domains
+Changelog;Changelog
+Firstname;Firstname
+Lastname;Lastname
+Repeat password;Repeat password
+Sign Up;Sign Up
+Sign up to start with moonlight;Sign up to start with moonlight
+Sign up with Discord;Sign up with Discord
+Sign up with Google;Sign up with Google
+Sign-up;Sign-up
+Already registered?;Already registered?
+Sign in;Sign in
+Create something new;Create something new
+Create a gameserver;Create a gameserver
+A new gameserver in just a few minutes;A new gameserver in just a few minutes
+Create a database;Create a database
+A quick way to store your data and manage it from all around the world;A quick way to store your data and manage it from all around the world
+Manage your services;Manage your services
+Manage your gameservers;Manage your gameservers
+Adjust your gameservers;Adjust your gameservers
+Manage your databases;Manage your databases
+Insert, delete and update the data in your databases;Insert, delete and update the data in your databases
+Create a website;Create a website
+Make your own websites with a webspace;Make your own websites with a webspace
+Create a domain;Create a domain
+Make your servvices accessible throught your own domain;Make your servvices accessible throught your own domain
+Manage your websites;Manage your websites
+Modify the content of your websites;Modify the content of your websites
+Manage your domains;Manage your domains
+Add, edit and delete dns records;Add, edit and delete dns records
+Admin;Admin
+System;System
+Overview;Overview
+Manager;Manager
+Cleanup;Cleanup
+Nodes;Nodes
+Images;Images
+aaPanel;aaPanel
+Users;Users
+Support;Support
+Statistics;Statistics
+No nodes found. Start with adding a new node;No nodes found. Start with adding a new node
+Nodename;Nodename
+FQDN;FQDN
+Create;Create
+Creating;Creating
+Http port;Http port
+Sftp port;Sftp port
+Moonlight daemon port;Moonlight daemon port
+SSL;SSL
+CPU Usage;CPU Usage
+In %;In %
+Memory;Memory
+Used / Available memory;Used / Available memory
+Storage;Storage
+Available storage;Available storage
+Add a new node;Add a new node
+Delete;Delete
+Deleting;Deleting
+Edit;Edit
+Token Id;Token Id
+Token;Token
+Save;Save
+Setup;Setup
+Open a ssh connection to your node and enter;Open a ssh connection to your node and enter
+and paste the config below. Then press STRG+O and STRG+X to save;and paste the config below. Then press STRG+O and STRG+X to save
+Before configuring this node, install the daemon;Before configuring this node, install the daemon
+Delete this node?;Delete this node?
+Do you really want to delete this node;Do you really want to delete this node
+Yes;Yes
+No;No
+Status;Status
+Adding;Adding
+Port;Port
+Id;Id
+Manage;Manage
+Create new server;Create new server
+No servers found;No servers found
+Server name;Server name
+Cpu cores;Cpu cores
+Disk;Disk
+Image;Image
+Override startup;Override startup
+Docker image;Docker image
+CPU Cores (100% = 1 Core);CPU Cores (100% = 1 Core)
+Server successfully created;Server successfully created
+Name;Name
+Cores;Cores
+Owner;Owner
+Value;Value
+An unknown error occured;An unknown error occured
+No allocation found;No allocation found
+Identifier;Identifier
+UuidIdentifier;UuidIdentifier
+Override startup command;Override startup command
+Loading;Loading
+Offline;Offline
+Connecting;Connecting
+Start;Start
+Restart;Restart
+Stop;Stop
+Shared IP;Shared IP
+Server ID;Server ID
+Cpu;Cpu
+Console;Console
+Files;Files
+Backups;Backups
+Network;Network
+Plugins;Plugins
+Settings;Settings
+Enter command;Enter command
+Execute;Execute
+Checking disk space;Checking disk space
+Updating config files;Updating config files
+Checking file permissions;Checking file permissions
+Downloading server image;Downloading server image
+Downloaded server image;Downloaded server image
+Starting;Starting
+Online;Online
+Kill;Kill
+Stopping;Stopping
+Search files and folders;Search files and folders
+Launch WinSCP;Launch WinSCP
+New folder;New folder
+Upload;Upload
+File name;File name
+File size;File size
+Last modified;Last modified
+Cancel;Cancel
+Canceling;Canceling
+Running;Running
+Loading backups;Loading backups
+Started backup creation;Started backup creation
+Backup is going to be created;Backup is going to be created
+Rename;Rename
+Move;Move
+Archive;Archive
+Unarchive;Unarchive
+Download;Download
+Starting download;Starting download
+Backup successfully created;Backup successfully created
+Restore;Restore
+Copy url;Copy url
+Backup deletion started;Backup deletion started
+Backup successfully deleted;Backup successfully deleted
+Primary;Primary
+This feature is currently not available;This feature is currently not available
+Send;Send
+Sending;Sending
+Welcome to the support chat. Ask your question here and we will help you;Welcome to the support chat. Ask your question here and we will help you
+ minutes ago; minutes ago
+just now;just now
+less than a minute ago;less than a minute ago
+1 hour ago;1 hour ago
+1 minute ago;1 minute ago
+Failed;Failed
+ hours ago; hours ago
+Open tickets;Open tickets
+Actions;Actions
+No support ticket is currently open;No support ticket is currently open
+User information;User information
+Close ticket;Close ticket
+Closing;Closing
+The support team has been notified. Please be patient;The support team has been notified. Please be patient
+The ticket is now closed. Type a message to open it again;The ticket is now closed. Type a message to open it again
+1 day ago;1 day ago
+is typing;is typing
+are typing;are typing
+No domains available;No domains available
+Shared domains;Shared domains
+Shared domain;Shared domain
+Shared domain successfully deleted;Shared domain successfully deleted
+Shared domain successfully added;Shared domain successfully added
+Domain name;Domain name
+DNS records for;DNS records for 
+Fetching dns records;Fetching dns records
+No dns records found;No dns records found
+Content;Content
+Priority;Priority
+Ttl;Ttl
+Enable cloudflare proxy;Enable cloudflare proxy
+CF Proxy;CF Proxy
+ days ago; days ago
+Cancle;Cancle
+An unexpected error occured;An unexpected error occured
+Testy;Testy
+Error from cloudflare api;Error from cloudflare api
+Profile;Profile
+No subscription available;No subscription available
+Buy;Buy
+Redirecting;Redirecting
+Apply;Apply
+Applying code;Applying code
+Invalid subscription code;Invalid subscription code
+Cancel Subscription;Cancel Subscription
+Active until;Active until
+We will send you a notification upon subscription expiration;We will send you a notification upon subscription expiration
+This token has been already used;This token has been already used
+New login for;New login for
+No records found for this day;No records found for this day
+Change;Change
+Changing;Changing
+Minecraft version;Minecraft version
+Build version;Build version
+Server installation is currently running;Server installation is currently running
+Selected;Selected
+Move deleted;Move deleted
+Delete selected;Delete selected
+Log level;Log level
+Log message;Log message
+Time;Time
+Version;Version
+You are running moonlight version;You are running moonlight version
+Operating system;Operating system
+Moonlight is running on;Moonlight is running on
+Memory usage;Memory usage
+Moonlight is using;Moonlight is using
+of memory;of memory
+Cpu usage;Cpu usage
+Refresh;Refresh
+Send a message to all users;Send a message to all users
+IP;IP
+URL;URL
+Device;Device
+Change url;Change url
+Message;Message
+Enter message;Enter message
+Enter the message to send;Enter the message to send
+Confirm;Confirm
+Are you sure?;Are you sure?
+Enter url;Enter url
+An unknown error occured while starting backup deletion;An unknown error occured while starting backup deletion
+Success;Success
+Backup URL successfully copied to your clipboard;Backup URL successfully copied to your clipboard
+Backup restore started;Backup restore started
+Backup successfully restored;Backup successfully restored
+Register for;Register for
+Core;Core
+Logs;Logs
+AuditLog;AuditLog
+SecurityLog;SecurityLog
+ErrorLog;ErrorLog
+Resources;Resources
+WinSCP cannot be launched here;WinSCP cannot be launched here
+Create a new folder;Create a new folder
+Enter a name;Enter a name
+File upload complete;File upload complete
+New server;New server
+Sessions;Sessions
+New user;New user
+Created at;Created at
+Mail template not found;Mail template not found
+Missing admin permissions. This attempt has been logged ;)
+Address;Address
+City;City
+State;State
+Country;Country
+Totp;Totp
+Discord;Discord
+Subscription;Subscription
+None;None
+No user with this id found;No user with this id found
+Back to list;Back to list
+New domain;New domain
+Reset password;Reset password
+Password reset;Password reset
+Reset the password of your account;Reset the password of your account
+Wrong here?;Wrong here?
+A user with this email can not be found;A user with this email can not be found
+Passwort reset successfull. Check your mail;Passwort reset successfull. Check your mail
+Discord bot;Discord bot
+New image;New image
+Description;Description
+Uuid;Uuid
+Enter tag name;Enter tag name
+Remove;Remove
+No tags found;No tags found
+Enter docker image name;Enter docker image name
+Tags;Tags
+Docker images;Docker images
+Default image;Default image
+Startup command;Startup command
+Install container;Install container
+Install entry;Install entry
+Configuration files;Configuration files
+Startup detection;Startup detection
+Stop command;Stop command
+Successfully saved image;Successfully saved image
+No docker images found;No docker images found
+Key;Key
+Default value;Default value
+Allocations;Allocations
+No variables found;No variables found
+Successfully added image;Successfully added image
+Password change for;Password change for
+of;of
+New node;New node
+Fqdn;Fqdn
+Cores used;Cores used
+used;used
+5.15.90.1-microsoft-standard-WSL2 - amd64;5.15.90.1-microsoft-standard-WSL2 - amd64
+Host system information;Host system information
+0;0
+Docker containers running;Docker containers running
+details;details
+1;1
+2;2
+DDos;DDos
+No ddos attacks found;No ddos attacks found
+Node;Node
+Date;Date
+DDos attack started;DDos attack started
+packets;packets
+DDos attack stopped;DDos attack stopped
+ packets; packets
+Stop all;Stop all
+Kill all;Kill all
+Network in;Network in
+Network out;Network out
+Kill all servers;Kill all servers
+Do you really want to kill all running servers?;Do you really want to kill all running servers?
+Change power state for;Change power state for
+to;to
+Stop all servers;Stop all servers
+Do you really want to stop all running servers?;Do you really want to stop all running servers?
+Manage ;Manage 
+Manage user ;Manage user 
+Reloading;Reloading
+Update;Update
+Updating;Updating
+Successfully updated user;Successfully updated user
+Discord id;Discord id
+Discord username;Discord username
+Discord discriminator;Discord discriminator
+The Name field is required.;The Name field is required.
+An error occured while logging you in;An error occured while logging you in
+You need to enter an email address;You need to enter an email address
+You need to enter a password;You need to enter a password
+You need to enter a password with minimum 8 characters in lenght;You need to enter a password with minimum 8 characters in lenght
+Proccessing;Proccessing
+The FirstName field is required.;The FirstName field is required.
+The LastName field is required.;The LastName field is required.
+The Address field is required.;The Address field is required.
+The City field is required.;The City field is required.
+The State field is required.;The State field is required.
+The Country field is required.;The Country field is required.
+Street and house number requered;Street and house number requered
+Max lenght reached;Max lenght reached
+Server;Server
+stopped;stopped
+Cleanups;Cleanups
+executed;executed
+Used clanup;Used clanup
+Enable;Enable
+Disabble;Disabble
+Disable;Disable
+Addons;Addons
+Javascript version;Javascript version
+Javascript file;Javascript file
+Select javascript file to execute on start;Select javascript file to execute on start
+Submit;Submit
+Processing;Processing
+Go up;Go up
+Running cleanup;Running cleanup
+servers;servers
+Select folder to move the file(s) to;Select folder to move the file(s) to
+Paper version;Paper version
+Join2Start;Join2Start
+Server reset;Server reset
+Reset;Reset
+Resetting;Resetting
+Are you sure you want to reset this server?;Are you sure you want to reset this server?
+Are you sure? This cannot be undone;Are you sure? This cannot be undone
+Resetting server;Resetting server
+Deleted file;Deleted file
+Reinstalling server;Reinstalling server
+Uploading files;Uploading files
+complete;complete
+Upload complete;Upload complete
+Security;Security
+Subscriptions;Subscriptions
+2fa Code;2fa Code
+Your account is secured with 2fa;Your account is secured with 2fa
+anyone write a fancy text here?;anyone write a fancy text here?
+Activate 2fa;Activate 2fa
+2fa apps;2fa apps
+Use an app like ;Use an app like 
+or;or
+and scan the following QR Code;and scan the following QR Code
+If you have trouble using the QR Code, select manual input in the app and enter your email and the following code:;If you have trouble using the QR Code, select manual input in the app and enter your email and the following code:
+Finish activation;Finish activation
+2fa Code requiered;2fa Code requiered
+New password;New password
+Secure your account;Secure your account
+2fa adds another layer of security to your account. You have to enter a 6 digit code in order to login.;2fa adds another layer of security to your account. You have to enter a 6 digit code in order to login.
+New subscription;New subscription
+You need to enter a name;You need to enter a name
+You need to enter a description;You need to enter a description
+Add new limit;Add new limit
+Create subscription;Create subscription
+Options;Options
+Amount;Amount
+Do you really want to delete it?;Do you really want to delete it?
+Loading your subscription;Loading your subscription
+Searching for deploy node;Searching for deploy node
+Searching for available images;Searching for available images
+Server details;Server details
+Configure your server;Configure your server
+Default;Default
+You reached the maximum amount of servers for every image of your subscription;You reached the maximum amount of servers for every image of your subscription
+Personal information;Personal information
+Enter code;Enter code
+Server rename;Server rename
+Create code;Create code
+Save subscription;Save subscription
+Enter your information;Enter your information
+You need to enter your full name in order to use moonlight;You need to enter your full name in order to use moonlight
+No node found;No node found
+No node found to deploy to found;No node found to deploy to found
+Node offline;Node offline
+The node the server is running on is currently offline;The node the server is running on is currently offline
+Server not found;Server not found
+A server with that id cannot be found or you have no access for this server;A server with that id cannot be found or you have no access for this server
+Compress;Compress
+Decompress;Decompress
+Moving;Moving
+Compressing;Compressing
+selected;selected
+New website;New website
+Plesk servers;Plesk servers
+Base domain;Base domain
+Plesk server;Plesk server
+Ftp;Ftp
+No SSL certificate found;No SSL certificate found
+Ftp Host;Ftp Host
+Ftp Port;Ftp Port
+Ftp Username;Ftp Username
+Ftp Password;Ftp Password
+Use;Use
+SSL Certificates;SSL Certificates
+SSL certificates;SSL certificates
+Issue certificate;Issue certificate
+New plesk server;New plesk server
+Api url;Api url
+Host system offline;Host system offline
+The host system the website is running on is currently offline;The host system the website is running on is currently offline
+No SSL certificates found;No SSL certificates found
+No databases found for this website;No databases found for this website
+The name should be at least 8 characters long;The name should be at least 8 characters long
+The name should only contain of lower case characters and numbers;The name should only contain of lower case characters and numbers
+Error from plesk;Error from plesk
+Host;Host
+Username;Username
+SRV records cannot be updated thanks to the cloudflare api client. Please delete the record and create a new one;SRV records cannot be updated thanks to the cloudflare api client. Please delete the record and create a new one
+The User field is required.;The User field is required.
+You need to specify a owner;You need to specify a owner
+You need to specify a image;You need to specify a image
+Api Url;Api Url
+Api Key;Api Key
+Duration;Duration
+Enter duration of subscription;Enter duration of subscription
+Copied code to clipboard;Copied code to clipboard
+Invalid or expired subscription code;Invalid or expired subscription code
+Current subscription;Current subscription
+You need to specify a server image;You need to specify a server image
+CPU;CPU
+Hour;Hour
+Day;Day
+Month;Month
+Year;Year
+All time;All time
+This function is not implemented;This function is not implemented
+Domain details;Domain details
+Configure your domain;Configure your domain
+You reached the maximum amount of domains in your subscription;You reached the maximum amount of domains in your subscription
+You need to specify a shared domain;You need to specify a shared domain
+A domain with this name does already exist for this shared domain;A domain with this name does already exist for this shared domain
+The Email field is required.;The Email field is required.
+The Password field is required.;The Password field is required.
+The ConfirmPassword field is required.;The ConfirmPassword field is required.
+Passwords need to match;Passwords need to match
+Cleanup exception;Cleanup exception
+No shared domain found;No shared domain found
+Searching for deploy plesk server;Searching for deploy plesk server
+No plesk server found;No plesk server found
+No plesk server found to deploy to;No plesk server found to deploy to
+No node found to deploy to;No node found to deploy to
+Website details;Website details
+Configure your website;Configure your website
+The name cannot be longer that 32 characters;The name cannot be longer that 32 characters
+The name should only consist of lower case characters;The name should only consist of lower case characters
+News;News
+Title...;Title...
+Enter text...;Enter text...
+Saving...;Saving...
+Deleting...;Deleting...
+Delete post;Delete post
+Do you really want to delete the post ";Do you really want to delete the post "
+You have no domains;You have no domains
+We were not able to find any domains associated with your account;We were not able to find any domains associated with your account
+You have no websites;You have no websites
+We were not able to find any websites associated with your account;We were not able to find any websites associated with your account
+Guest;Guest
+You need a domain;You need a domain
+New post;New post
+New entry;New entry

+ 86 - 0
Moonlight/defaultstorage/resources/lang/en_us.lang

@@ -0,0 +1,86 @@
+Open support;Open support
+About us;About us
+Imprint;Imprint
+Privacy;Privacy
+Create;Create
+Server;Server
+Domain;Domain
+Website;Website
+Login;Login
+Register;Register
+Email;Email
+Password;Password
+Sign In;Sign In
+Sign in to start with moonlight;Sign in to start with moonlight
+Sign in with Discord;Sign in with Discord
+Sign in with Google;Sign in with Google
+Or with email;Or with email
+Forgot password?;Forgot password?
+Sign-in;Sign-in
+Not registered yet?;Not registered yet?
+Sign up;Sign up
+Profile;Profile
+Logout;Logout
+Dashboard;Dashboard
+Servers;Servers
+Websites;Websites
+Domains;Domains
+Changelog;Changelog
+Admin;Admin
+System;System
+Overview;Overview
+Manager;Manager
+Cleanup;Cleanup
+Nodes;Nodes
+Images;Images
+Users;Users
+Shared domains;Shared domains
+Support;Support
+Subscriptions;Subscriptions
+Statistics;Statistics
+Create something new;Create something new
+Create a gameserver;Create a gameserver
+A new gameserver in just a few minutes;A new gameserver in just a few minutes
+Create a website;Create a website
+Make your own websites with a webspace;Make your own websites with a webspace
+Create a domain;Create a domain
+Make your servvices accessible throught your own domain;Make your servvices accessible throught your own domain
+Manage your services;Manage your services
+Manage your gameservers;Manage your gameservers
+Adjust your gameservers;Adjust your gameservers
+Manage your websites;Manage your websites
+Modify the content of your websites;Modify the content of your websites
+Manage your domains;Manage your domains
+Add, edit and delete dns records;Add, edit and delete dns records
+New server;New server
+Id;Id
+Name;Name
+Cores;Cores
+Memory;Memory
+Disk;Disk
+Owner;Owner
+Manage;Manage
+Node offline;Node offline
+The node the server is running on is currently offline;The node the server is running on is currently offline
+Sessions;Sessions
+New user;New user
+First name;First name
+Last name;Last name
+Created at;Created at
+Refresh;Refresh
+Send a message to all users;Send a message to all users
+IP;IP
+URL;URL
+Device;Device
+Time;Time
+Actions;Actions
+Change url;Change url
+Message;Message
+Enter url;Enter url
+Send;Send
+Sending;Sending
+Welcome to the support chat. Ask your question here and we will help you;Welcome to the support chat. Ask your question here and we will help you
+less than a minute ago;less than a minute ago
+The support team has been notified. Please be patient;The support team has been notified. Please be patient
+is typing;is typing
+Proccessing;Proccessing

+ 53 - 0
Moonlight/defaultstorage/resources/mail/login.html

@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>New moonlight login</title>
+</head>
+<body>
+<div style="background-color:#ffffff; padding: 45px 0 34px 0; border-radius: 24px; margin:40px auto; max-width: 600px;">
+    <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" height="auto"
+           style="border-collapse:collapse">
+        <tbody>
+        <tr>
+            <td align="center" valign="center" style="text-align:center; padding-bottom: 10px">
+                <div style="text-align:center; margin:0 15px 34px 15px">
+                    <div style="margin-bottom: 10px">
+                        <a href="https://endelon-hosting.de" rel="noopener" target="_blank">
+                            <img alt="Logo" src="https://moonlight.endelon-hosting.de/assets/media/logo/MoonFullText.png" style="height: 35px">
+                        </a>
+                    </div>
+                    <div style="font-size: 14px; font-weight: 500; margin-bottom: 27px; font-family:Arial,Helvetica,sans-serif;">
+                        <p style="margin-bottom:9px; color:#181C32; font-size: 22px; font-weight:700">Hey {{FirstName}}, there is a new login in your moonlight account</p>
+                        <p style="margin-bottom:2px; color:#7E8299">Here is all the data we collected</p>
+                        <p style="margin-bottom:2px; color:#7E8299">IP: {{Ip}}</p>
+                        <p style="margin-bottom:2px; color:#7E8299">Device: {{Device}}</p>
+                        <p style="margin-bottom:2px; color:#7E8299">Location: {{Location}}</p>
+                    </div>
+                    <a href="https://moonlight.endelon-hosting.de" target="_blank"
+                       style="background-color:#50cd89; border-radius:6px;display:inline-block; padding:11px 19px; color: #FFFFFF; font-size: 14px; font-weight:500;">Open Moonlight
+                    </a>
+                </div>
+            </td>
+        </tr>
+        <tr>
+            <td align="center" valign="center"
+                style="font-size: 13px; text-align:center; padding: 0 10px 10px 10px; font-weight: 500; color: #A1A5B7; font-family:Arial,Helvetica,sans-serif">
+                <p style="color:#181C32; font-size: 16px; font-weight: 600; margin-bottom:9px">You need help?</p>
+                <p style="margin-bottom:2px">We are happy to help!</p>
+                <p style="margin-bottom:4px">More information at
+                    <a href="https://endelon.link/support" rel="noopener" target="_blank" style="font-weight: 600">endelon.link/support</a>.
+                </p>
+            </td>
+        </tr>
+        <tr>
+            <td align="center" valign="center"
+                style="font-size: 13px; padding:0 15px; text-align:center; font-weight: 500; color: #A1A5B7;font-family:Arial,Helvetica,sans-serif">
+                <p>Copyright 2022 Endelon Hosting </p>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+</body>
+</html>

+ 53 - 0
Moonlight/defaultstorage/resources/mail/passwordChange.html

@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Moonlight password change</title>
+</head>
+<body>
+<div style="background-color:#ffffff; padding: 45px 0 34px 0; border-radius: 24px; margin:40px auto; max-width: 600px;">
+    <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" height="auto"
+           style="border-collapse:collapse">
+        <tbody>
+        <tr>
+            <td align="center" valign="center" style="text-align:center; padding-bottom: 10px">
+                <div style="text-align:center; margin:0 15px 34px 15px">
+                    <div style="margin-bottom: 10px">
+                        <a href="https://endelon-hosting.de" rel="noopener" target="_blank">
+                            <img alt="Logo" src="https://moonlight.endelon-hosting.de/assets/media/logo/MoonFullText.png" style="height: 35px">
+                        </a>
+                    </div>
+                    <div style="font-size: 14px; font-weight: 500; margin-bottom: 27px; font-family:Arial,Helvetica,sans-serif;">
+                        <p style="margin-bottom:9px; color:#181C32; font-size: 22px; font-weight:700">Hey {{FirstName}}, your password has been changed</p>
+                        <p style="margin-bottom:2px; color:#7E8299">If this was not you please contact us. Also here is the data we collected.</p>
+                        <p style="margin-bottom:2px; color:#7E8299">IP: {{Ip}}</p>
+                        <p style="margin-bottom:2px; color:#7E8299">Device: {{Device}}</p>
+                        <p style="margin-bottom:2px; color:#7E8299">Location: {{Location}}</p>
+                    </div>
+                    <a href="https://moonlight.endelon-hosting.de" target="_blank"
+                       style="background-color:#50cd89; border-radius:6px;display:inline-block; padding:11px 19px; color: #FFFFFF; font-size: 14px; font-weight:500;">Open Moonlight
+                    </a>
+                </div>
+            </td>
+        </tr>
+        <tr>
+            <td align="center" valign="center"
+                style="font-size: 13px; text-align:center; padding: 0 10px 10px 10px; font-weight: 500; color: #A1A5B7; font-family:Arial,Helvetica,sans-serif">
+                <p style="color:#181C32; font-size: 16px; font-weight: 600; margin-bottom:9px">You need help?</p>
+                <p style="margin-bottom:2px">We are happy to help!</p>
+                <p style="margin-bottom:4px">More information at
+                    <a href="https://endelon.link/support" rel="noopener" target="_blank" style="font-weight: 600">endelon.link/support</a>.
+                </p>
+            </td>
+        </tr>
+        <tr>
+            <td align="center" valign="center"
+                style="font-size: 13px; padding:0 15px; text-align:center; font-weight: 500; color: #A1A5B7;font-family:Arial,Helvetica,sans-serif">
+                <p>Copyright 2023 Endelon Hosting </p>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+</body>
+</html>

+ 54 - 0
Moonlight/defaultstorage/resources/mail/passwordReset.html

@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Moonlight password reset</title>
+</head>
+<body>
+<div style="background-color:#ffffff; padding: 45px 0 34px 0; border-radius: 24px; margin:40px auto; max-width: 600px;">
+    <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" height="auto"
+           style="border-collapse:collapse">
+        <tbody>
+        <tr>
+            <td align="center" valign="center" style="text-align:center; padding-bottom: 10px">
+                <div style="text-align:center; margin:0 15px 34px 15px">
+                    <div style="margin-bottom: 10px">
+                        <a href="https://endelon-hosting.de" rel="noopener" target="_blank">
+                            <img alt="Logo" src="https://moonlight.endelon-hosting.de/assets/media/logo/MoonFullText.png" style="height: 35px">
+                        </a>
+                    </div>
+                    <div style="font-size: 14px; font-weight: 500; margin-bottom: 27px; font-family:Arial,Helvetica,sans-serif;">
+                        <p style="margin-bottom:9px; color:#181C32; font-size: 22px; font-weight:700">Hey {{FirstName}}, your password has been resetted</p>
+                        <p style="margin-bottom:2px; color:#7E8299">Your new password is: <b>{{Password}}</b></p>
+                        <p style="margin-bottom:2px; color:#7E8299">If this was not you please contact us. Also here is the data we collected.</p>
+                        <p style="margin-bottom:2px; color:#7E8299">IP: {{Ip}}</p>
+                        <p style="margin-bottom:2px; color:#7E8299">Device: {{Device}}</p>
+                        <p style="margin-bottom:2px; color:#7E8299">Location: {{Location}}</p>
+                    </div>
+                    <a href="https://moonlight.endelon-hosting.de" target="_blank"
+                       style="background-color:#50cd89; border-radius:6px;display:inline-block; padding:11px 19px; color: #FFFFFF; font-size: 14px; font-weight:500;">Open Moonlight
+                    </a>
+                </div>
+            </td>
+        </tr>
+        <tr>
+            <td align="center" valign="center"
+                style="font-size: 13px; text-align:center; padding: 0 10px 10px 10px; font-weight: 500; color: #A1A5B7; font-family:Arial,Helvetica,sans-serif">
+                <p style="color:#181C32; font-size: 16px; font-weight: 600; margin-bottom:9px">You need help?</p>
+                <p style="margin-bottom:2px">We are happy to help!</p>
+                <p style="margin-bottom:4px">More information at
+                    <a href="https://endelon.link/support" rel="noopener" target="_blank" style="font-weight: 600">endelon.link/support</a>.
+                </p>
+            </td>
+        </tr>
+        <tr>
+            <td align="center" valign="center"
+                style="font-size: 13px; padding:0 15px; text-align:center; font-weight: 500; color: #A1A5B7;font-family:Arial,Helvetica,sans-serif">
+                <p>Copyright 2022 Endelon Hosting </p>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+</body>
+</html>

+ 50 - 0
Moonlight/defaultstorage/resources/mail/register.html

@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Welcome</title>
+</head>
+<body>
+<div style="background-color:#ffffff; padding: 45px 0 34px 0; border-radius: 24px; margin:40px auto; max-width: 600px;">
+    <table align="center" border="0" cellpadding="0" cellspacing="0" width="100%" height="auto"
+           style="border-collapse:collapse">
+        <tbody>
+        <tr>
+            <td align="center" valign="center" style="text-align:center; padding-bottom: 10px">
+                <div style="text-align:center; margin:0 15px 34px 15px">
+                    <div style="margin-bottom: 10px">
+                        <a href="https://endelon-hosting.de" rel="noopener" target="_blank">
+                            <img alt="Logo" src="https://moonlight.endelon-hosting.de/assets/media/logo/MoonFullText.png" style="height: 35px">
+                        </a>
+                    </div>
+                    <div style="font-size: 14px; font-weight: 500; margin-bottom: 27px; font-family:Arial,Helvetica,sans-serif;">
+                        <p style="margin-bottom:9px; color:#181C32; font-size: 22px; font-weight:700">Hey {{FirstName}}, welcome to moonlight</p>
+                        <p style="margin-bottom:2px; color:#7E8299">We are happy to welcome you in ;)</p>
+                    </div>
+                    <a href="https://moonlight.endelon-hosting.de" target="_blank"
+                       style="background-color:#50cd89; border-radius:6px;display:inline-block; padding:11px 19px; color: #FFFFFF; font-size: 14px; font-weight:500;">Open Moonlight
+                    </a>
+                </div>
+            </td>
+        </tr>
+        <tr>
+            <td align="center" valign="center"
+                style="font-size: 13px; text-align:center; padding: 0 10px 10px 10px; font-weight: 500; color: #A1A5B7; font-family:Arial,Helvetica,sans-serif">
+                <p style="color:#181C32; font-size: 16px; font-weight: 600; margin-bottom:9px">You need help?</p>
+                <p style="margin-bottom:2px">We are happy to help!</p>
+                <p style="margin-bottom:4px">More information at
+                    <a href="https://endelon.link/support" rel="noopener" target="_blank" style="font-weight: 600">endelon.link/support</a>.
+                </p>
+            </td>
+        </tr>
+        <tr>
+            <td align="center" valign="center"
+                style="font-size: 13px; padding:0 15px; text-align:center; font-weight: 500; color: #A1A5B7;font-family:Arial,Helvetica,sans-serif">
+                <p>Copyright 2022 Endelon Hosting </p>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+</body>
+</html>

+ 14 - 0
Moonlight/defaultstorage/resources/public/images/logo.svg

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="256px" height="301px" viewBox="0 0 256 301" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
+    <defs>
+        <linearGradient x1="2.17771739%" y1="34.7938955%" x2="92.7221942%" y2="91.3419405%" id="linearGradient-1">
+            <stop stop-color="#41A7EF" offset="0%"></stop>
+            <stop stop-color="#813DDE" offset="54.2186236%"></stop>
+            <stop stop-color="#8F2EE2" offset="74.4988788%"></stop>
+            <stop stop-color="#A11CE6" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g>
+        <path d="M124.183681,101.699 C124.183681,66.515 136.256681,34.152 156.486681,8.525 C159.197681,5.092 156.787681,0.069 152.412681,0.012 C151.775681,0.004 151.136681,0 150.497681,0 C67.6206813,0 0.390681343,66.99 0.00168134279,149.775 C-0.386318657,232.369 66.4286813,300.195 149.019681,300.988 C189.884681,301.381 227.036681,285.484 254.376681,259.395 C257.519681,256.396 255.841681,251.082 251.548681,250.42 C179.413681,239.291 124.183681,176.949 124.183681,101.699" fill="url(#linearGradient-1)"></path>
+    </g>
+</svg>

BIN
Moonlight/defaultstorage/resources/public/images/logolong.png