diff --git a/Moonlight/App/Database/Entities/User.cs b/Moonlight/App/Database/Entities/User.cs index 790d4e20..254ca5d6 100644 --- a/Moonlight/App/Database/Entities/User.cs +++ b/Moonlight/App/Database/Entities/User.cs @@ -1,5 +1,4 @@ -using System.ComponentModel.DataAnnotations; -using Moonlight.App.Models.Misc; +using Moonlight.App.Models.Misc; namespace Moonlight.App.Database.Entities; @@ -34,7 +33,7 @@ public class User // Security public bool TotpEnabled { get; set; } = false; public string TotpSecret { get; set; } = ""; - public DateTime TokenValidTime { get; set; } = DateTime.Now; + public DateTime TokenValidTime { get; set; } = DateTime.UtcNow; // Discord public ulong DiscordId { get; set; } diff --git a/Moonlight/App/Http/Controllers/Api/Moonlight/OAuth2Controller.cs b/Moonlight/App/Http/Controllers/Api/Moonlight/OAuth2Controller.cs index 3d1abb4c..aa6c9fe5 100644 --- a/Moonlight/App/Http/Controllers/Api/Moonlight/OAuth2Controller.cs +++ b/Moonlight/App/Http/Controllers/Api/Moonlight/OAuth2Controller.cs @@ -18,17 +18,19 @@ public class OAuth2Controller : Controller private readonly DiscordOAuth2Service DiscordOAuth2Service; private readonly UserRepository UserRepository; private readonly UserService UserService; + private readonly DateTimeService DateTimeService; public OAuth2Controller( GoogleOAuth2Service googleOAuth2Service, UserRepository userRepository, UserService userService, - DiscordOAuth2Service discordOAuth2Service) + DiscordOAuth2Service discordOAuth2Service, DateTimeService dateTimeService) { GoogleOAuth2Service = googleOAuth2Service; UserRepository = userRepository; UserService = userService; DiscordOAuth2Service = discordOAuth2Service; + DateTimeService = dateTimeService; } [HttpGet("google")] @@ -63,7 +65,7 @@ public class OAuth2Controller : Controller Response.Cookies.Append("token", token, new () { - Expires = new DateTimeOffset(DateTime.UtcNow.AddDays(10)) + Expires = new DateTimeOffset(DateTimeService.GetCurrent().AddDays(10)) }); return Redirect("/"); @@ -121,7 +123,7 @@ public class OAuth2Controller : Controller Response.Cookies.Append("token", token, new () { - Expires = new DateTimeOffset(DateTime.UtcNow.AddDays(10)) + Expires = new DateTimeOffset(DateTimeService.GetCurrent().AddDays(10)) }); return Redirect("/"); diff --git a/Moonlight/App/Repositories/StatisticsRepository.cs b/Moonlight/App/Repositories/StatisticsRepository.cs index f33751b7..69630abe 100644 --- a/Moonlight/App/Repositories/StatisticsRepository.cs +++ b/Moonlight/App/Repositories/StatisticsRepository.cs @@ -1,16 +1,19 @@ using Microsoft.EntityFrameworkCore; using Moonlight.App.Database; using Moonlight.App.Database.Entities; +using Moonlight.App.Services; namespace Moonlight.App.Repositories; public class StatisticsRepository : IDisposable { private readonly DataContext DataContext; + private readonly DateTimeService DateTimeService; - public StatisticsRepository(DataContext dataContext) + public StatisticsRepository(DataContext dataContext, DateTimeService dateTimeService) { DataContext = dataContext; + DateTimeService = dateTimeService; } public DbSet Get() @@ -27,7 +30,7 @@ public class StatisticsRepository : IDisposable public StatisticsData Add(string chart, double value) { - return Add(new StatisticsData() {Chart = chart, Value = value, Date = DateTime.Now}); + return Add(new StatisticsData() {Chart = chart, Value = value, Date = DateTimeService.GetCurrent()}); } public void Dispose() diff --git a/Moonlight/App/Services/CleanupService.cs b/Moonlight/App/Services/CleanupService.cs index 42e046ce..c5fac29a 100644 --- a/Moonlight/App/Services/CleanupService.cs +++ b/Moonlight/App/Services/CleanupService.cs @@ -24,20 +24,23 @@ public class CleanupService private readonly ConfigService ConfigService; private readonly MessageService MessageService; + private readonly DateTimeService DateTimeService; private readonly IServiceScopeFactory ServiceScopeFactory; private readonly PeriodicTimer Timer; public CleanupService( ConfigService configService, IServiceScopeFactory serviceScopeFactory, - MessageService messageService) + MessageService messageService, + DateTimeService dateTimeService) { ServiceScopeFactory = serviceScopeFactory; MessageService = messageService; + DateTimeService = dateTimeService; ConfigService = configService; - StartedAt = DateTime.Now; - CompletedAt = DateTime.Now; + StartedAt = DateTimeService.GetCurrent(); + CompletedAt = DateTimeService.GetCurrent(); IsRunning = false; var config = ConfigService.GetSection("Moonlight").GetSection("Cleanup"); diff --git a/Moonlight/App/Services/DateTimeService.cs b/Moonlight/App/Services/DateTimeService.cs new file mode 100644 index 00000000..40b0231e --- /dev/null +++ b/Moonlight/App/Services/DateTimeService.cs @@ -0,0 +1,31 @@ +using Moonlight.App.Helpers; + +namespace Moonlight.App.Services; + +public class DateTimeService +{ + public long GetCurrentUnix() + { + return new DateTimeOffset(GetCurrent()).ToUnixTimeMilliseconds(); + } + + public long GetCurrentUnixSeconds() + { + return new DateTimeOffset(GetCurrent()).ToUnixTimeSeconds(); + } + + public DateTime GetCurrent() + { + return DateTime.UtcNow; + } + + public string GetDate() + { + return Formatter.FormatDateOnly(GetCurrent()); + } + + public string GetDateTime() + { + return Formatter.FormatDate(GetCurrent()); + } +} \ No newline at end of file diff --git a/Moonlight/App/Services/ServerService.cs b/Moonlight/App/Services/ServerService.cs index ae724ac9..ebf8b836 100644 --- a/Moonlight/App/Services/ServerService.cs +++ b/Moonlight/App/Services/ServerService.cs @@ -31,6 +31,7 @@ public class ServerService private readonly AuditLogService AuditLogService; private readonly ErrorLogService ErrorLogService; private readonly NodeService NodeService; + private readonly DateTimeService DateTimeService; public ServerService( ServerRepository serverRepository, @@ -46,7 +47,8 @@ public class ServerService AuditLogService auditLogService, ErrorLogService errorLogService, NodeService nodeService, - NodeAllocationRepository nodeAllocationRepository) + NodeAllocationRepository nodeAllocationRepository, + DateTimeService dateTimeService) { ServerRepository = serverRepository; WingsApiHelper = wingsApiHelper; @@ -62,6 +64,7 @@ public class ServerService ErrorLogService = errorLogService; NodeService = nodeService; NodeAllocationRepository = nodeAllocationRepository; + DateTimeService = dateTimeService; } private Server EnsureNodeData(Server s) @@ -115,9 +118,9 @@ public class ServerService var backup = new ServerBackup() { - Name = $"Created at {DateTime.Now.ToShortDateString()} {DateTime.Now.ToShortTimeString()}", + Name = $"Created at {DateTimeService.GetCurrent().ToShortDateString()} {DateTimeService.GetCurrent().ToShortTimeString()}", Uuid = Guid.NewGuid(), - CreatedAt = DateTime.Now, + CreatedAt = DateTimeService.GetCurrent(), Created = false }; diff --git a/Moonlight/App/Services/Sessions/IdentityService.cs b/Moonlight/App/Services/Sessions/IdentityService.cs index f35519e1..ef98937f 100644 --- a/Moonlight/App/Services/Sessions/IdentityService.cs +++ b/Moonlight/App/Services/Sessions/IdentityService.cs @@ -4,6 +4,7 @@ using JWT.Builder; using JWT.Exceptions; using Logging.Net; using Moonlight.App.Database.Entities; +using Moonlight.App.Helpers; using Moonlight.App.Models.Misc; using Moonlight.App.Repositories; using Moonlight.App.Services.LogServices; @@ -123,9 +124,9 @@ public class IdentityService return null; } - var issuedAt = DateTimeOffset.FromUnixTimeSeconds(iat).DateTime; - - if (issuedAt < user.TokenValidTime.ToUniversalTime()) + var iatD = DateTimeOffset.FromUnixTimeSeconds(iat).ToUniversalTime().DateTime; + + if (iatD < user.TokenValidTime) return null; UserCache = user; diff --git a/Moonlight/App/Services/Sessions/SessionService.cs b/Moonlight/App/Services/Sessions/SessionService.cs index 1ecbd67d..f7b97cef 100644 --- a/Moonlight/App/Services/Sessions/SessionService.cs +++ b/Moonlight/App/Services/Sessions/SessionService.cs @@ -12,6 +12,7 @@ public class SessionService private readonly IdentityService IdentityService; private readonly NavigationManager NavigationManager; private readonly AlertService AlertService; + private readonly DateTimeService DateTimeService; private Session? OwnSession; @@ -19,12 +20,14 @@ public class SessionService SessionRepository sessionRepository, IdentityService identityService, NavigationManager navigationManager, - AlertService alertService) + AlertService alertService, + DateTimeService dateTimeService) { SessionRepository = sessionRepository; IdentityService = identityService; NavigationManager = navigationManager; AlertService = alertService; + DateTimeService = dateTimeService; } public async Task Register() @@ -36,7 +39,7 @@ public class SessionService Ip = IdentityService.GetIp(), Url = NavigationManager.Uri, Device = IdentityService.GetDevice(), - CreatedAt = DateTime.Now, + CreatedAt = DateTimeService.GetCurrent(), User = user, Navigation = NavigationManager, AlertService = AlertService @@ -64,10 +67,8 @@ public class SessionService { foreach (var session in SessionRepository.Get()) { - if (session.User.Id == user.Id) - { + if(session.User != null && session.User.Id == user.Id) session.Navigation.NavigateTo(session.Navigation.Uri, true); - } } } } \ No newline at end of file diff --git a/Moonlight/App/Services/Statistics/StatisticsViewService.cs b/Moonlight/App/Services/Statistics/StatisticsViewService.cs index 329445fe..dfb68f01 100644 --- a/Moonlight/App/Services/Statistics/StatisticsViewService.cs +++ b/Moonlight/App/Services/Statistics/StatisticsViewService.cs @@ -7,15 +7,17 @@ namespace Moonlight.App.Services.Statistics; public class StatisticsViewService { private readonly StatisticsRepository StatisticsRepository; + private readonly DateTimeService DateTimeService; - public StatisticsViewService(StatisticsRepository statisticsRepository) + public StatisticsViewService(StatisticsRepository statisticsRepository, DateTimeService dateTimeService) { StatisticsRepository = statisticsRepository; + DateTimeService = dateTimeService; } public StatisticsData[] GetData(string chart, StatisticsTimeSpan timeSpan) { - var startDate = DateTime.Now - TimeSpan.FromHours((int)timeSpan); + var startDate = DateTimeService.GetCurrent() - TimeSpan.FromHours((int)timeSpan); var objs = StatisticsRepository.Get().Where(x => x.Date > startDate && x.Chart == chart); diff --git a/Moonlight/App/Services/UserService.cs b/Moonlight/App/Services/UserService.cs index 6a6fe022..81633b14 100644 --- a/Moonlight/App/Services/UserService.cs +++ b/Moonlight/App/Services/UserService.cs @@ -19,6 +19,7 @@ public class UserService private readonly MailService MailService; private readonly IdentityService IdentityService; private readonly IpLocateService IpLocateService; + private readonly DateTimeService DateTimeService; private readonly string JwtSecret; @@ -29,7 +30,9 @@ public class UserService SecurityLogService securityLogService, AuditLogService auditLogService, MailService mailService, - IdentityService identityService, IpLocateService ipLocateService) + IdentityService identityService, + IpLocateService ipLocateService, + DateTimeService dateTimeService) { UserRepository = userRepository; TotpService = totpService; @@ -38,6 +41,7 @@ public class UserService MailService = mailService; IdentityService = identityService; IpLocateService = ipLocateService; + DateTimeService = dateTimeService; JwtSecret = configService .GetSection("Moonlight") @@ -70,12 +74,12 @@ public class UserService LastName = lastname, State = "", Status = UserStatus.Unverified, - CreatedAt = DateTime.UtcNow, + CreatedAt = DateTimeService.GetCurrent(), DiscordId = 0, TotpEnabled = false, TotpSecret = "", - UpdatedAt = DateTime.UtcNow, - TokenValidTime = DateTime.Now.AddDays(-5) + UpdatedAt = DateTimeService.GetCurrent(), + TokenValidTime = DateTimeService.GetCurrent().AddDays(-5) }); await MailService.SendMail(user!, "register", values => {}); @@ -168,7 +172,7 @@ public class UserService public async Task ChangePassword(User user, string password, bool isSystemAction = false) { user.Password = BCrypt.Net.BCrypt.HashPassword(password); - user.TokenValidTime = DateTime.Now; + user.TokenValidTime = DateTimeService.GetCurrent(); UserRepository.Update(user); if (isSystemAction) @@ -244,8 +248,8 @@ public class UserService var token = JwtBuilder.Create() .WithAlgorithm(new HMACSHA256Algorithm()) .WithSecret(JwtSecret) - .AddClaim("exp", DateTimeOffset.UtcNow.AddDays(10).ToUnixTimeSeconds()) - .AddClaim("iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds()) + .AddClaim("exp", new DateTimeOffset(DateTimeService.GetCurrent().AddDays(10)).ToUnixTimeSeconds()) + .AddClaim("iat", DateTimeService.GetCurrentUnixSeconds()) .AddClaim("userid", user.Id) .Encode(); diff --git a/Moonlight/Program.cs b/Moonlight/Program.cs index 9d0664d6..33c9acc5 100644 --- a/Moonlight/Program.cs +++ b/Moonlight/Program.cs @@ -104,6 +104,7 @@ namespace Moonlight builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); + builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/Moonlight/Shared/Views/Admin/Users/Edit.razor b/Moonlight/Shared/Views/Admin/Users/Edit.razor index 665bac1f..846af806 100644 --- a/Moonlight/Shared/Views/Admin/Users/Edit.razor +++ b/Moonlight/Shared/Views/Admin/Users/Edit.razor @@ -7,6 +7,7 @@ @using Moonlight.App.Services.Sessions @inject UserRepository UserRepository +@inject UserService UserService @inject SessionService SessionService @inject ToastService ToastService @inject SmartTranslateService SmartTranslateService @@ -76,17 +77,27 @@
-
- - Cancel - - - -
-
+
+ + + +
+ +
+
+ + Cancel + + + +
+
@@ -148,6 +159,8 @@ private User? User; + private string NewPassword = ""; + private Task Load(LazyLoader arg) { User = UserRepository.Get().FirstOrDefault(x => x.Id == Id); @@ -172,4 +185,14 @@ await ToastService.Success(SmartTranslateService.Translate("Successfully updated user")); } + + private async Task ChangePassword() + { + await UserService.ChangePassword(User!, NewPassword, true); + NewPassword = ""; + + SessionService.ReloadUserSessions(User); + + await ToastService.Success(SmartTranslateService.Translate("Successfully updated password")); + } } \ 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 80cca6ce..4db31131 100644 --- a/Moonlight/Shared/Views/Admin/Users/Sessions.razor +++ b/Moonlight/Shared/Views/Admin/Users/Sessions.razor @@ -64,7 +64,7 @@