Added user change status try catch, implement logout. password change admin
This commit is contained in:
@@ -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; }
|
||||
|
||||
@@ -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("/");
|
||||
|
||||
@@ -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<StatisticsData> 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()
|
||||
|
||||
@@ -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");
|
||||
|
||||
31
Moonlight/App/Services/DateTimeService.cs
Normal file
31
Moonlight/App/Services/DateTimeService.cs
Normal file
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
var iatD = DateTimeOffset.FromUnixTimeSeconds(iat).ToUniversalTime().DateTime;
|
||||
|
||||
if (issuedAt < user.TokenValidTime.ToUniversalTime())
|
||||
if (iatD < user.TokenValidTime)
|
||||
return null;
|
||||
|
||||
UserCache = user;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ namespace Moonlight
|
||||
builder.Services.AddScoped<SmartDeployService>();
|
||||
builder.Services.AddScoped<WebSpaceService>();
|
||||
builder.Services.AddScoped<StatisticsViewService>();
|
||||
builder.Services.AddSingleton<DateTimeService>();
|
||||
|
||||
builder.Services.AddScoped<GoogleOAuth2Service>();
|
||||
builder.Services.AddScoped<DiscordOAuth2Service>();
|
||||
|
||||
@@ -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 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 card card-body p-10">
|
||||
<div class="d-flex justify-content-end">
|
||||
<a href="/admin/users" class="btn btn-danger me-3">
|
||||
<TL>Cancel</TL>
|
||||
</a>
|
||||
<WButton Text="@(SmartTranslateService.Translate("Update"))"
|
||||
WorkingText="@(SmartTranslateService.Translate("Updating"))"
|
||||
CssClasses="btn-success"
|
||||
OnClick="Update">
|
||||
</WButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group">
|
||||
<input @bind="NewPassword" type="password" class="form-control" placeholder="@(SmartTranslateService.Translate("Password"))"/>
|
||||
<WButton Text="@(SmartTranslateService.Translate("Change"))"
|
||||
WorkingText="@(SmartTranslateService.Translate("Reloading"))"
|
||||
CssClasses="btn-primary"
|
||||
OnClick="ChangePassword">
|
||||
</WButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 card card-body p-10">
|
||||
<div class="d-flex justify-content-end">
|
||||
<a href="/admin/users" class="btn btn-danger me-3">
|
||||
<TL>Cancel</TL>
|
||||
</a>
|
||||
<WButton Text="@(SmartTranslateService.Translate("Update"))"
|
||||
WorkingText="@(SmartTranslateService.Translate("Updating"))"
|
||||
CssClasses="btn-success"
|
||||
OnClick="Update">
|
||||
</WButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-6 mb-5 mb-xl-10">
|
||||
<div class="card card-body p-10">
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
@@ -64,7 +64,7 @@
|
||||
<Column TableItem="Session" Title="@(SmartTranslateService.Translate("Time"))" Field="@(x => x.CreatedAt)" Sortable="true" Filterable="true" Width="10%">
|
||||
<Template>
|
||||
@{
|
||||
var time = Formatter.FormatUptime((DateTime.Now - context.CreatedAt).TotalMilliseconds);
|
||||
var time = Formatter.FormatUptime((DateTime.UtcNow - context.CreatedAt).TotalMilliseconds);
|
||||
}
|
||||
<span>@(time)</span>
|
||||
</Template>
|
||||
|
||||
Reference in New Issue
Block a user