Added session system
This commit is contained in:
parent
e6ac19c4ec
commit
a480b35fe6
8 changed files with 248 additions and 13 deletions
|
@ -1,14 +1,15 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using Moonlight.App.Database.Entities;
|
||||
using Moonlight.App.Services.Interop;
|
||||
|
||||
namespace Moonlight.App.Models.Misc;
|
||||
|
||||
public class Session
|
||||
{
|
||||
public string Ip { get; set; }
|
||||
public string Url { get; set; }
|
||||
public string Device { get; set; }
|
||||
public int UserId { get; set; }
|
||||
public string Ip { get; set; } = "N/A";
|
||||
public string Url { get; set; } = "N/A";
|
||||
public string Device { get; set; } = "N/A";
|
||||
public User? User { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public NavigationManager Navigation { get; set; }
|
||||
public AlertService AlertService { get; set; }
|
||||
|
|
|
@ -67,7 +67,7 @@ public class AlertService
|
|||
return result.IsConfirmed;
|
||||
}
|
||||
|
||||
public async Task<string> Text(string title, string desciption, string setValue)
|
||||
public async Task<string?> Text(string title, string desciption, string setValue)
|
||||
{
|
||||
var result = await SweetAlertService.FireAsync(new SweetAlertOptions()
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ public class SessionService
|
|||
private readonly NavigationManager NavigationManager;
|
||||
private readonly AlertService AlertService;
|
||||
|
||||
private Session OwnSession;
|
||||
private Session? OwnSession;
|
||||
|
||||
public SessionService(
|
||||
SessionRepository sessionRepository,
|
||||
|
@ -30,18 +30,14 @@ public class SessionService
|
|||
public async Task Register()
|
||||
{
|
||||
var user = await IdentityService.Get();
|
||||
var userId = -1;
|
||||
|
||||
if (user != null)
|
||||
userId = user.Id;
|
||||
|
||||
|
||||
OwnSession = new Session()
|
||||
{
|
||||
Ip = IdentityService.GetIp(),
|
||||
Url = NavigationManager.Uri,
|
||||
Device = IdentityService.GetDevice(),
|
||||
CreatedAt = DateTime.Now,
|
||||
UserId = userId,
|
||||
User = user,
|
||||
Navigation = NavigationManager,
|
||||
AlertService = AlertService
|
||||
};
|
||||
|
@ -68,7 +64,7 @@ public class SessionService
|
|||
{
|
||||
foreach (var session in SessionRepository.Get())
|
||||
{
|
||||
if (session.UserId == user.Id)
|
||||
if (session.User.Id == user.Id)
|
||||
{
|
||||
session.Navigation.NavigateTo(session.Navigation.Uri, true);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<div class="card mb-5 mb-xl-10">
|
||||
<div class="card-body pt-0 pb-0">
|
||||
<ul class="nav nav-stretch nav-line-tabs nav-line-tabs-2x border-transparent fs-5 fw-bold">
|
||||
<li class="nav-item mt-2">
|
||||
<a class="nav-link text-active-primary ms-0 me-10 py-5 @(Index == 0 ? "active" : "")" href="/admin/users">
|
||||
Users
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item mt-2">
|
||||
<a class="nav-link text-active-primary ms-0 me-10 py-5 @(Index == 1 ? "active" : "")" href="/admin/users/sessions">
|
||||
Sessions
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@code
|
||||
{
|
||||
[Parameter]
|
||||
public int Index { get; set; } = 0;
|
||||
}
|
7
Moonlight/Shared/Views/Admin/Users/Index.razor
Normal file
7
Moonlight/Shared/Views/Admin/Users/Index.razor
Normal file
|
@ -0,0 +1,7 @@
|
|||
@page "/admin/users"
|
||||
|
||||
@using Moonlight.Shared.Components.Navigations
|
||||
|
||||
<OnlyAdmin>
|
||||
<AdminSessionNavigation Index="0" />
|
||||
</OnlyAdmin>
|
185
Moonlight/Shared/Views/Admin/Users/Sessions.razor
Normal file
185
Moonlight/Shared/Views/Admin/Users/Sessions.razor
Normal file
|
@ -0,0 +1,185 @@
|
|||
@page "/admin/users/sessions"
|
||||
|
||||
@using Moonlight.Shared.Components.Navigations
|
||||
@using Moonlight.App.Services.Sessions
|
||||
@using BlazorTable
|
||||
@using Logging.Net
|
||||
@using Moonlight.App.Helpers
|
||||
@using Moonlight.App.Models.Misc
|
||||
@using Moonlight.App.Services
|
||||
@using Moonlight.App.Services.Interop
|
||||
|
||||
@inject SessionService SessionService
|
||||
@inject SmartTranslateService SmartTranslateService
|
||||
@inject AlertService AlertService
|
||||
|
||||
<OnlyAdmin>
|
||||
<AdminSessionNavigation Index="1"/>
|
||||
|
||||
<div class="card card-body">
|
||||
<LazyLoader Load="Load">
|
||||
<button class="btn btn-primary mb-3" @onclick="Refresh">
|
||||
<TL>Refresh</TL>
|
||||
</button>
|
||||
<button class="btn btn-warning mb-3" @onclick="MessageAll">
|
||||
<TL>Send a message to all users</TL>
|
||||
</button>
|
||||
|
||||
@if (AllSessions == null)
|
||||
{
|
||||
<div class="alert alert-info">
|
||||
<span class="spinner-border spinner-border-sm align-middle me-2"></span>
|
||||
<TL>Loading sessions</TL>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<Table TableItem="Session" Items="AllSessions" PageSize="25" TableHeadClass="border-bottom border-gray-200 fs-6 text-gray-600 fw-bold bg-light bg-opacity-75">
|
||||
<Column TableItem="Session" Title="@(SmartTranslateService.Translate("Email"))" Field="@(x => x.User.Id)" Sortable="true" Filterable="true" Width="20%">
|
||||
<Template>
|
||||
<span>@(context.User == null ? "" : context.User.Email)</span>
|
||||
</Template>
|
||||
</Column>
|
||||
<Column TableItem="Session" Title="@(SmartTranslateService.Translate("IP"))" Field="@(x => x.Ip)" Sortable="true" Filterable="true" Width="10%"/>
|
||||
<Column TableItem="Session" Title="@(SmartTranslateService.Translate("URL"))" Field="@(x => x.Url)" Sortable="true" Filterable="true" Width="10%"/>
|
||||
<Column TableItem="Session" Title="@(SmartTranslateService.Translate("Device"))" Field="@(x => x.Device)" Sortable="true" Filterable="true" Width="10%"/>
|
||||
<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);
|
||||
}
|
||||
<span>@(time)</span>
|
||||
</Template>
|
||||
</Column>
|
||||
<Column TableItem="Session" Title="@(SmartTranslateService.Translate("Actions"))" Field="@(x => x.Ip)" Sortable="false" Filterable="false" Width="10%">
|
||||
<Template>
|
||||
<button @onclick="() => Navigate(context)" class="btn btn-primary">
|
||||
<TL>Change url</TL>
|
||||
</button>
|
||||
</Template>
|
||||
</Column>
|
||||
<Column TableItem="Session" Title="" Field="@(x => x.Ip)" Sortable="false" Filterable="false" Width="10%">
|
||||
<Template>
|
||||
<button @onclick="() => Message(context)" class="btn btn-warning">
|
||||
<TL>Message</TL>
|
||||
</button>
|
||||
</Template>
|
||||
</Column>
|
||||
<Pager ShowPageNumber="true" ShowTotalCount="true"/>
|
||||
</Table>
|
||||
}
|
||||
</LazyLoader>
|
||||
</div>
|
||||
</OnlyAdmin>
|
||||
|
||||
@code
|
||||
{
|
||||
private Session[]? AllSessions;
|
||||
|
||||
private Task Load(LazyLoader arg)
|
||||
{
|
||||
AllSessions = SessionService.GetAll();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
await Refresh();
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("Error autorefreshing sessions");
|
||||
Logger.Warn(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task Refresh()
|
||||
{
|
||||
AllSessions = SessionService.GetAll();
|
||||
await InvokeAsync(StateHasChanged);
|
||||
}
|
||||
|
||||
private async Task Navigate(Session session)
|
||||
{
|
||||
var url = await AlertService.Text("URL", SmartTranslateService.Translate("Enter url"), "");
|
||||
|
||||
if(url == null)
|
||||
return;
|
||||
|
||||
if (url == "")
|
||||
return;
|
||||
|
||||
if (url == "null")
|
||||
return;
|
||||
|
||||
session.Navigation.NavigateTo(url, true);
|
||||
}
|
||||
|
||||
private async Task MessageAll()
|
||||
{
|
||||
var message = await AlertService.Text(
|
||||
SmartTranslateService.Translate("Enter message"),
|
||||
SmartTranslateService.Translate("Enter the message to send"),
|
||||
""
|
||||
);
|
||||
|
||||
var b = await AlertService.YesNo(
|
||||
SmartTranslateService.Translate("Confirm"),
|
||||
SmartTranslateService.Translate("Are you sure?"),
|
||||
SmartTranslateService.Translate("Yes"),
|
||||
SmartTranslateService.Translate("No")
|
||||
);
|
||||
|
||||
if (b)
|
||||
{
|
||||
foreach (var session in SessionService.GetAll())
|
||||
{
|
||||
try
|
||||
{
|
||||
await session.AlertService.Warning("Admin Message", message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("Error sending user a alert");
|
||||
Logger.Warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task Message(Session session)
|
||||
{
|
||||
var message = await AlertService.Text(
|
||||
SmartTranslateService.Translate("Enter message"),
|
||||
SmartTranslateService.Translate("Enter the message to send"),
|
||||
""
|
||||
);
|
||||
|
||||
var b = await AlertService.YesNo(
|
||||
SmartTranslateService.Translate("Confirm"),
|
||||
SmartTranslateService.Translate("Are you sure?"),
|
||||
SmartTranslateService.Translate("Yes"),
|
||||
SmartTranslateService.Translate("No")
|
||||
);
|
||||
|
||||
if (b)
|
||||
{
|
||||
try
|
||||
{
|
||||
await session.AlertService.Warning("Admin Message", message);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.Warn("Error sending user a alert");
|
||||
Logger.Warn(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -83,6 +83,10 @@ build_metadata.AdditionalFiles.CssScope =
|
|||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcRm9ybXNcV0J1dHRvbi5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/GitHub/Moonlight-Panel/Moonlight/Moonlight/Shared/Components/Navigations/AdminSessionNavigation.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcTmF2aWdhdGlvbnNcQWRtaW5TZXNzaW9uTmF2aWdhdGlvbi5yYXpvcg==
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/GitHub/Moonlight-Panel/Moonlight/Moonlight/Shared/Components/Navigations/AdminSystemNavigation.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXENvbXBvbmVudHNcTmF2aWdhdGlvbnNcQWRtaW5TeXN0ZW1OYXZpZ2F0aW9uLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
@ -259,6 +263,14 @@ build_metadata.AdditionalFiles.CssScope =
|
|||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEFkbWluXFN5c1xMb2dzLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/GitHub/Moonlight-Panel/Moonlight/Moonlight/Shared/Views/Admin/Users/Index.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEFkbWluXFVzZXJzXEluZGV4LnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/GitHub/Moonlight-Panel/Moonlight/Moonlight/Shared/Views/Admin/Users/Sessions.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXEFkbWluXFVzZXJzXFNlc3Npb25zLnJhem9y
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
||||
[C:/Users/marce/GitHub/Moonlight-Panel/Moonlight/Moonlight/Shared/Views/Domains.razor]
|
||||
build_metadata.AdditionalFiles.TargetPath = U2hhcmVkXFZpZXdzXERvbWFpbnMucmF6b3I=
|
||||
build_metadata.AdditionalFiles.CssScope =
|
||||
|
|
|
@ -278,3 +278,15 @@ 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
|
||||
|
|
Loading…
Reference in a new issue