From 862fed5ac299a9e4c267a4ff6ad1d1852e13de4e Mon Sep 17 00:00:00 2001 From: Marcel Baumgartner Date: Sun, 12 Mar 2023 19:53:28 +0100 Subject: [PATCH] Added user view, added website and databases partialy --- Moonlight/App/Database/DataContext.cs | 2 + Moonlight/App/Database/Entities/AaPanel.cs | 9 + Moonlight/App/Database/Entities/Database.cs | 4 +- Moonlight/App/Database/Entities/Website.cs | 13 + .../App/Repositories/AaPanelRepository.cs | 44 +++ .../App/Repositories/WebsiteRepository.cs | 44 +++ Moonlight/App/Services/DatabaseService.cs | 76 +++++ .../App/Services/TrashMailDetectorService.cs | 46 +++ Moonlight/App/Services/UserService.cs | 4 +- Moonlight/App/Services/WebsiteService.cs | 39 +++ Moonlight/Moonlight.csproj | 2 + Moonlight/Program.cs | 4 + .../Shared/Views/Admin/AaPanels/Index.razor | 2 + .../Shared/Views/Admin/Databases/Index.razor | 5 + .../Shared/Views/Admin/Domains/Index.razor | 80 +++--- .../Shared/Views/Admin/Servers/Index.razor | 82 +++--- .../Shared/Views/Admin/Servers/New.razor | 52 ++-- Moonlight/Shared/Views/Admin/Sys/Logs.razor | 2 +- .../Shared/Views/Admin/Users/Index.razor | 63 ++++- Moonlight/Shared/Views/Admin/Users/New.razor | 66 +++++ .../Shared/Views/Admin/Users/Sessions.razor | 127 +++++---- Moonlight/Shared/Views/Admin/Users/View.razor | 261 ++++++++++++++++++ Moonlight/Shared/Views/Test.razor | 2 + Moonlight/resources/lang/de_de.lang | 17 ++ Moonlight/resources/mail/register.html | 50 ++++ 25 files changed, 945 insertions(+), 151 deletions(-) create mode 100644 Moonlight/App/Database/Entities/AaPanel.cs create mode 100644 Moonlight/App/Database/Entities/Website.cs create mode 100644 Moonlight/App/Repositories/AaPanelRepository.cs create mode 100644 Moonlight/App/Repositories/WebsiteRepository.cs create mode 100644 Moonlight/App/Services/DatabaseService.cs create mode 100644 Moonlight/App/Services/TrashMailDetectorService.cs create mode 100644 Moonlight/App/Services/WebsiteService.cs create mode 100644 Moonlight/Shared/Views/Admin/AaPanels/Index.razor create mode 100644 Moonlight/Shared/Views/Admin/Databases/Index.razor create mode 100644 Moonlight/Shared/Views/Admin/Users/New.razor create mode 100644 Moonlight/Shared/Views/Admin/Users/View.razor create mode 100644 Moonlight/Shared/Views/Test.razor create mode 100644 Moonlight/resources/mail/register.html diff --git a/Moonlight/App/Database/DataContext.cs b/Moonlight/App/Database/DataContext.cs index ef171ee8..a303bdf5 100644 --- a/Moonlight/App/Database/DataContext.cs +++ b/Moonlight/App/Database/DataContext.cs @@ -39,6 +39,8 @@ public class DataContext : DbContext public DbSet Revokes { get; set; } public DbSet NotificationClients { get; set; } public DbSet NotificationActions { get; set; } + public DbSet AaPanels { get; set; } + public DbSet Websites { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { diff --git a/Moonlight/App/Database/Entities/AaPanel.cs b/Moonlight/App/Database/Entities/AaPanel.cs new file mode 100644 index 00000000..da79d53e --- /dev/null +++ b/Moonlight/App/Database/Entities/AaPanel.cs @@ -0,0 +1,9 @@ +namespace Moonlight.App.Database.Entities; + +public class AaPanel +{ + public int Id { get; set; } + public string Url { get; set; } = ""; + public string Key { get; set; } = ""; + public string BaseDomain { get; set; } = ""; +} \ No newline at end of file diff --git a/Moonlight/App/Database/Entities/Database.cs b/Moonlight/App/Database/Entities/Database.cs index 662e0e5c..c14c1392 100644 --- a/Moonlight/App/Database/Entities/Database.cs +++ b/Moonlight/App/Database/Entities/Database.cs @@ -3,6 +3,8 @@ public class Database { public int Id { get; set; } - public int AaPanelId { get; set; } + public int InternalAaPanelId { get; set; } public User Owner { get; set; } + public AaPanel AaPanel { get; set; } + public string Name { get; set; } } \ No newline at end of file diff --git a/Moonlight/App/Database/Entities/Website.cs b/Moonlight/App/Database/Entities/Website.cs new file mode 100644 index 00000000..d5c86d97 --- /dev/null +++ b/Moonlight/App/Database/Entities/Website.cs @@ -0,0 +1,13 @@ +namespace Moonlight.App.Database.Entities; + +public class Website +{ + public int Id { get; set; } + public int InternalAaPanelId { get; set; } + public AaPanel AaPanel { get; set; } + public User Owner { get; set; } + public string DomainName { get; set; } + public string PhpVersion { get; set; } + public string FtpUsername { get; set; } + public string FtpPassword { get; set; } +} \ No newline at end of file diff --git a/Moonlight/App/Repositories/AaPanelRepository.cs b/Moonlight/App/Repositories/AaPanelRepository.cs new file mode 100644 index 00000000..92870f85 --- /dev/null +++ b/Moonlight/App/Repositories/AaPanelRepository.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore; +using Moonlight.App.Database; +using Moonlight.App.Database.Entities; + +namespace Moonlight.App.Repositories; + +public class AaPanelRepository : IDisposable +{ + private readonly DataContext DataContext; + + public AaPanelRepository(DataContext dataContext) + { + DataContext = dataContext; + } + + public DbSet Get() + { + return DataContext.AaPanels; + } + + public AaPanel Add(AaPanel aaPanel) + { + var x = DataContext.AaPanels.Add(aaPanel); + DataContext.SaveChanges(); + return x.Entity; + } + + public void Update(AaPanel aaPanel) + { + DataContext.AaPanels.Update(aaPanel); + DataContext.SaveChanges(); + } + + public void Delete(AaPanel aaPanel) + { + DataContext.AaPanels.Remove(aaPanel); + DataContext.SaveChanges(); + } + + public void Dispose() + { + DataContext.Dispose(); + } +} \ No newline at end of file diff --git a/Moonlight/App/Repositories/WebsiteRepository.cs b/Moonlight/App/Repositories/WebsiteRepository.cs new file mode 100644 index 00000000..aedf91f4 --- /dev/null +++ b/Moonlight/App/Repositories/WebsiteRepository.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore; +using Moonlight.App.Database; +using Moonlight.App.Database.Entities; + +namespace Moonlight.App.Repositories; + +public class WebsiteRepository : IDisposable +{ + private readonly DataContext DataContext; + + public WebsiteRepository(DataContext dataContext) + { + DataContext = dataContext; + } + + public DbSet Get() + { + return DataContext.Websites; + } + + public Website Add(Website website) + { + var x = DataContext.Websites.Add(website); + DataContext.SaveChanges(); + return x.Entity; + } + + public void Update(Website website) + { + DataContext.Websites.Update(website); + DataContext.SaveChanges(); + } + + public void Delete(Website website) + { + DataContext.Websites.Remove(website); + DataContext.SaveChanges(); + } + + public void Dispose() + { + DataContext.Dispose(); + } +} \ No newline at end of file diff --git a/Moonlight/App/Services/DatabaseService.cs b/Moonlight/App/Services/DatabaseService.cs new file mode 100644 index 00000000..33e5988f --- /dev/null +++ b/Moonlight/App/Services/DatabaseService.cs @@ -0,0 +1,76 @@ +using aaPanelSharp; +using Microsoft.EntityFrameworkCore; +using Moonlight.App.Database.Entities; +using Moonlight.App.Exceptions; +using Moonlight.App.Repositories; + +namespace Moonlight.App.Services; + +public class DatabaseService +{ + private readonly DatabaseRepository DatabaseRepository; + private readonly AaPanelRepository AaPanelRepository; + + public DatabaseService(DatabaseRepository databaseRepository, AaPanelRepository aaPanelRepository) + { + DatabaseRepository = databaseRepository; + AaPanelRepository = aaPanelRepository; + } + + public Task Create(string name, string password, User u, AaPanel? a = null) + { + if (DatabaseRepository.Get().Any(x => x.Name == name)) + throw new DisplayException("A database with this name has been already created"); + + var aaPanel = a ?? AaPanelRepository.Get().First(); + + var access = new aaPanel(a!.Url, a.Key); + + if (access.CreateDatabase(name, name, password)) + { + var aaDb = access.Databases.First(x => x.Name == name); + + return Task.FromResult(DatabaseRepository.Add(new() + { + Name = name, + AaPanel = aaPanel, + Owner = u, + InternalAaPanelId = aaDb.Id + })); + } + else + throw new DisplayException("An unknown error occured while creating the database"); + } + + public Task ChangePassword(Database.Entities.Database database, string newPassword) + { + var access = CreateApiAccess(database); + + access.Databases.First(x => x.Id == database.InternalAaPanelId).ChangePassword(newPassword); + + return Task.CompletedTask; + } + + public Task GetPassword(Database.Entities.Database database) + { + var access = CreateApiAccess(database); + + return Task.FromResult( + access.Databases + .First(x => x.Id == database.InternalAaPanelId).Password + ); + } + + private aaPanel CreateApiAccess(Database.Entities.Database database) + { + if (database.AaPanel == null) + { + database = DatabaseRepository + .Get() + .Include(x => x.AaPanel) + .First(x => x.Id == database.Id); + } + + return new aaPanel(database.AaPanel.Url, database.AaPanel.Key); + } +} \ No newline at end of file diff --git a/Moonlight/App/Services/TrashMailDetectorService.cs b/Moonlight/App/Services/TrashMailDetectorService.cs new file mode 100644 index 00000000..eba090b5 --- /dev/null +++ b/Moonlight/App/Services/TrashMailDetectorService.cs @@ -0,0 +1,46 @@ +using System.Net; +using Logging.Net; + +namespace Moonlight.App.Services; + +public class TrashMailDetectorService +{ + private string[] Domains; + + public TrashMailDetectorService() + { + Logger.Info("Fetching trash mail list from github repository"); + + using var wc = new WebClient(); + + var lines = wc + .DownloadString("https://raw.githubusercontent.com/Endelon-Hosting/TrashMailDomainDetector/main/trashmail_domains.md") + .Replace("\r\n", "\n") + .Split(new [] { "\n" }, StringSplitOptions.RemoveEmptyEntries); + + Domains = GetDomains(lines).ToArray(); + } + + private IEnumerable GetDomains(string[] lines) + { + foreach (var line in lines) + { + if (!string.IsNullOrWhiteSpace(line)) + { + if (line.Contains(".")) + { + var domain = line.Remove(0, line.IndexOf(".", StringComparison.Ordinal) + 1).Trim(); + if (domain.Contains(".")) + { + yield return domain; + } + } + } + } + } + + public bool IsTrashEmail(string mail) + { + return Domains.Contains(mail.Split('@')[1]); + } +} \ No newline at end of file diff --git a/Moonlight/App/Services/UserService.cs b/Moonlight/App/Services/UserService.cs index 196de75b..75e15ff8 100644 --- a/Moonlight/App/Services/UserService.cs +++ b/Moonlight/App/Services/UserService.cs @@ -67,13 +67,13 @@ public class UserService LastName = lastname, State = "", Status = UserStatus.Unverified, - CreatedAt = DateTime.Now, + CreatedAt = DateTime.UtcNow, DiscordDiscriminator = "", DiscordId = -1, DiscordUsername = "", TotpEnabled = false, TotpSecret = "", - UpdatedAt = DateTime.Now, + UpdatedAt = DateTime.UtcNow, TokenValidTime = DateTime.Now.AddDays(-5) }); diff --git a/Moonlight/App/Services/WebsiteService.cs b/Moonlight/App/Services/WebsiteService.cs new file mode 100644 index 00000000..4cdda657 --- /dev/null +++ b/Moonlight/App/Services/WebsiteService.cs @@ -0,0 +1,39 @@ +using aaPanelSharp; +using Microsoft.EntityFrameworkCore; +using Moonlight.App.Database.Entities; +using Moonlight.App.Exceptions; +using Moonlight.App.Repositories; + +namespace Moonlight.App.Services; + +public class WebsiteService +{ + private readonly WebsiteRepository WebsiteRepository; + + public WebsiteService(WebsiteRepository websiteRepository) + { + WebsiteRepository = websiteRepository; + } + + public Website Create(AaPanel aaPanel, User user, string name) + { + if (WebsiteRepository.Get().Any(x => x.DomainName == name)) + throw new DisplayException("A website with this domain has already been created"); + + var access = new aaPanel(aaPanel.Url, aaPanel.Key); + return null; + } + + private aaPanel CreateApiAccess(Website website) + { + if (website.AaPanel == null) + { + website = WebsiteRepository + .Get() + .Include(x => x.AaPanel) + .First(x => x.Id == website.Id); + } + + return new aaPanel(website.AaPanel.Url, website.AaPanel.Key); + } +} \ No newline at end of file diff --git a/Moonlight/Moonlight.csproj b/Moonlight/Moonlight.csproj index c9c7eeda..57522d5a 100644 --- a/Moonlight/Moonlight.csproj +++ b/Moonlight/Moonlight.csproj @@ -56,6 +56,8 @@ <_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\ICON-LICENSE" /> <_ContentIncludedByDefault Remove="wwwroot\css\open-iconic\README.md" /> <_ContentIncludedByDefault Remove="wwwroot\css\site.css" /> + <_ContentIncludedByDefault Remove="Shared\Components\Tables\Column.razor" /> + <_ContentIncludedByDefault Remove="Shared\Components\Tables\Table.razor" /> diff --git a/Moonlight/Program.cs b/Moonlight/Program.cs index 36dce008..f41e7ad5 100644 --- a/Moonlight/Program.cs +++ b/Moonlight/Program.cs @@ -62,6 +62,8 @@ namespace Moonlight builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddScoped(); + builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); @@ -100,6 +102,8 @@ namespace Moonlight builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddSingleton(); + builder.Services.AddScoped(); // Support builder.Services.AddSingleton(); diff --git a/Moonlight/Shared/Views/Admin/AaPanels/Index.razor b/Moonlight/Shared/Views/Admin/AaPanels/Index.razor new file mode 100644 index 00000000..17f952c3 --- /dev/null +++ b/Moonlight/Shared/Views/Admin/AaPanels/Index.razor @@ -0,0 +1,2 @@ +@page "/admin/aapanels" + diff --git a/Moonlight/Shared/Views/Admin/Databases/Index.razor b/Moonlight/Shared/Views/Admin/Databases/Index.razor new file mode 100644 index 00000000..4b858ad2 --- /dev/null +++ b/Moonlight/Shared/Views/Admin/Databases/Index.razor @@ -0,0 +1,5 @@ +@page "/admin/databases" + + + + \ No newline at end of file diff --git a/Moonlight/Shared/Views/Admin/Domains/Index.razor b/Moonlight/Shared/Views/Admin/Domains/Index.razor index d2f7238e..0f5cfc48 100644 --- a/Moonlight/Shared/Views/Admin/Domains/Index.razor +++ b/Moonlight/Shared/Views/Admin/Domains/Index.razor @@ -10,38 +10,54 @@ - -
- - - - - - - - - - - - - - - -
+
+
+
+

+ + Domains + +

+ +
+
+
+ + + + + + + + + + + + + + + +
+
+
+
diff --git a/Moonlight/Shared/Views/Admin/Servers/Index.razor b/Moonlight/Shared/Views/Admin/Servers/Index.razor index c613485e..f60b9b14 100644 --- a/Moonlight/Shared/Views/Admin/Servers/Index.razor +++ b/Moonlight/Shared/Views/Admin/Servers/Index.razor @@ -9,45 +9,53 @@ @inject SmartTranslateService SmartTranslateService -
-
- @if (Servers.Any()) - { - - - - - - - - - - - - - -
- } - else - { -
- No servers found +
+
+

+ Servers +

+ - } +
+
+ @if (Servers.Any()) + { +
+ + + + + + + + + + + + + +
+
+ } + else + { +
+ No servers found +
+ } +
@@ -63,7 +71,7 @@ .Get() .Include(x => x.Owner) .ToArray(); - + return Task.CompletedTask; } } \ No newline at end of file diff --git a/Moonlight/Shared/Views/Admin/Servers/New.razor b/Moonlight/Shared/Views/Admin/Servers/New.razor index d71cbbbc..1f40142d 100644 --- a/Moonlight/Shared/Views/Admin/Servers/New.razor +++ b/Moonlight/Shared/Views/Admin/Servers/New.razor @@ -125,37 +125,45 @@
- @if (Image != null) - { -
- @foreach (var vars in ServerVariables.Chunk(4)) +
+
+ @if (Image != null) { -
- @foreach (var variable in vars) +
+ @foreach (var vars in ServerVariables.Chunk(4)) { -
-
- -
- +
+ @foreach (var variable in vars) + { +
+
+ +
+ +
+ +
+ +
+
- -
- -
-
+ }
}
}
- } +
-
- - Back +
+ + Cancel
- +
diff --git a/Moonlight/Shared/Views/Admin/Users/Index.razor b/Moonlight/Shared/Views/Admin/Users/Index.razor index a104f71b..b034f6a2 100644 --- a/Moonlight/Shared/Views/Admin/Users/Index.razor +++ b/Moonlight/Shared/Views/Admin/Users/Index.razor @@ -1,7 +1,66 @@ @page "/admin/users" @using Moonlight.Shared.Components.Navigations +@using Moonlight.App.Repositories +@using Moonlight.App.Database.Entities +@using BlazorTable +@using Moonlight.App.Services + +@inject UserRepository UserRepository +@inject SmartTranslateService SmartTranslateService - - \ No newline at end of file + + +
+ +
+

+ + Users + +

+ +
+
+
+
+ + + + + + + + + + + +
+
+
+ +
+ + +@code +{ + private User[] Users; + + private async Task Load(LazyLoader lazyLoader) + { + Users = UserRepository.Get().ToArray(); + await InvokeAsync(StateHasChanged); + } +} \ No newline at end of file diff --git a/Moonlight/Shared/Views/Admin/Users/New.razor b/Moonlight/Shared/Views/Admin/Users/New.razor new file mode 100644 index 00000000..29d611ca --- /dev/null +++ b/Moonlight/Shared/Views/Admin/Users/New.razor @@ -0,0 +1,66 @@ +@page "/admin/users/new" +@using Moonlight.App.Database.Entities +@using Moonlight.App.Services +@using Moonlight.App.Services.Interop + +@inject SmartTranslateService SmartTranslateService +@inject NavigationManager NavigationManager +@inject ToastService ToastService +@inject UserService UserService + + +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+
+
+
+ + Cancel + + + +
+
+
+
+ +@code +{ + private User User = new(); + + private async Task Create() + { + await UserService.Register(User.Email, User.Password, User.FirstName, User.LastName); + await ToastService.Success(SmartTranslateService.Translate("User successfully created")); + NavigationManager.NavigateTo("/admin/users"); + } +} \ No newline at end of file diff --git a/Moonlight/Shared/Views/Admin/Users/Sessions.razor b/Moonlight/Shared/Views/Admin/Users/Sessions.razor index bd4b593a..80cca6ce 100644 --- a/Moonlight/Shared/Views/Admin/Users/Sessions.razor +++ b/Moonlight/Shared/Views/Admin/Users/Sessions.razor @@ -16,58 +16,77 @@ -
+
- - - - @if (AllSessions == null) - { -
- - Loading sessions +
+

+ + Sessions + +

+
+ +
- } - else - { - - - - - - - - - - - - - - - - - -
- } +
+
+ @if (AllSessions == null) + { +
+ + Loading sessions +
+ } + else + { + + + + + + + + + + + + + + + + + +
+ } +
@@ -79,7 +98,7 @@ private Task Load(LazyLoader arg) { AllSessions = SessionService.GetAll(); - + Task.Run(async () => { while (true) @@ -96,7 +115,7 @@ } } }); - + return Task.CompletedTask; } @@ -109,8 +128,8 @@ private async Task Navigate(Session session) { var url = await AlertService.Text("URL", SmartTranslateService.Translate("Enter url"), ""); - - if(url == null) + + if (url == null) return; if (url == "") diff --git a/Moonlight/Shared/Views/Admin/Users/View.razor b/Moonlight/Shared/Views/Admin/Users/View.razor new file mode 100644 index 00000000..d8c7cde8 --- /dev/null +++ b/Moonlight/Shared/Views/Admin/Users/View.razor @@ -0,0 +1,261 @@ +@page "/admin/users/view/{Id:int}" +@using Moonlight.App.Database.Entities +@using Moonlight.App.Helpers +@using Moonlight.App.Repositories +@using Moonlight.App.Repositories.Servers +@using Microsoft.EntityFrameworkCore +@using Moonlight.App.Repositories.Domains + +@inject UserRepository UserRepository +@inject ServerRepository ServerRepository +@inject DomainRepository DomainRepository + + + +@if (User == null) +{ +
+ No user with this id found +
+} +else +{ +
+
+
+
+ Profile picture +
+
+ +
+
+

+ Servers +

+
+
+ @foreach (var server in Servers) + { + + + if (server != Servers.Last()) + { +
+ } + } +
+
+
+
+

+ Domains +

+
+
+ @foreach (var domain in Domains) + { + + + if (domain != Domains.Last()) + { +
+ } + } +
+
+
+
+
+
+
+ +
+ @(User.FirstName) +
+
+
+
+ +
+ @(User.LastName) +
+
+
+
+ +
+ @(User.Email) +
+
+
+
+ +
+ @(User.Address) +
+
+
+
+ +
+ @(User.City) +
+
+
+
+ +
+ @(User.State) +
+
+
+
+ +
+ @(User.Country) +
+
+
+
+ +
+ + @if (User.Admin) + { + + } + else + { + + } + +
+
+
+
+ +
+ @(User.Status) +
+
+
+
+ +
+ @(User.TotpEnabled) +
+
+
+
+ +
+ @(User.DiscordUsername)#@(User.DiscordDiscriminator) +
+
+
+
+ +
+ + @if (User.Subscription == null) + { + + None + + } + else + { + @(User.Subscription.Name) + } + +
+
+
+
+ +
+ @(Formatter.FormatDate(User.CreatedAt)) +
+
+
+
+
+
+} +
+
+ +@code +{ + [Parameter] + public int Id { get; set; } + + private User? User; + private Server[] Servers; + private Domain[] Domains; + + private Task Load(LazyLoader arg) + { + User = UserRepository.Get().FirstOrDefault(x => x.Id == Id); + + if (User != null) + { + Servers = ServerRepository + .Get() + .Include(x => x.Owner) + .Include(x => x.Image) + .Where(x => x.Owner.Id == User.Id) + .ToArray(); + + Domains = DomainRepository + .Get() + .Include(x => x.SharedDomain) + .Include(x => x.Owner) + .Where(x => x.Owner.Id == User.Id) + .ToArray(); + } + + return Task.CompletedTask; + } +} \ No newline at end of file diff --git a/Moonlight/Shared/Views/Test.razor b/Moonlight/Shared/Views/Test.razor new file mode 100644 index 00000000..257b4518 --- /dev/null +++ b/Moonlight/Shared/Views/Test.razor @@ -0,0 +1,2 @@ +@page "/test" + diff --git a/Moonlight/resources/lang/de_de.lang b/Moonlight/resources/lang/de_de.lang index b470c8cd..29db8d82 100644 --- a/Moonlight/resources/lang/de_de.lang +++ b/Moonlight/resources/lang/de_de.lang @@ -306,3 +306,20 @@ 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 diff --git a/Moonlight/resources/mail/register.html b/Moonlight/resources/mail/register.html new file mode 100644 index 00000000..3ffbc507 --- /dev/null +++ b/Moonlight/resources/mail/register.html @@ -0,0 +1,50 @@ + + + + + Welcome + + +
+ + + + + + + + + + + + +
+
+
+ + Logo + +
+
+

Hey {{FirstName}}, welcome to moonlight

+

We are happy to welcome you in ;)

+
+ Open Moonlight + +
+
+

You need help?

+

We are happy to help!

+

More information at + endelon.link/support. +

+
+

Copyright 2022 Endelon Hosting

+
+
+ + \ No newline at end of file