From 25b908e311a611d00fe5cbc79a4416a35e02c031 Mon Sep 17 00:00:00 2001 From: Leendert de Borst Date: Sat, 31 Aug 2024 15:28:32 +0200 Subject: [PATCH] Update admin logs path as /logs folder doesn't work correctly due to .gitignore (#80) --- src/AliasVault.Admin/AliasVault.Admin.csproj | 5 - .../Main/Pages/Logging/Auth.razor | 149 ++++++++++++++++ .../Main/Pages/Logging/General.razor | 168 ++++++++++++++++++ 3 files changed, 317 insertions(+), 5 deletions(-) create mode 100644 src/AliasVault.Admin/Main/Pages/Logging/Auth.razor create mode 100644 src/AliasVault.Admin/Main/Pages/Logging/General.razor diff --git a/src/AliasVault.Admin/AliasVault.Admin.csproj b/src/AliasVault.Admin/AliasVault.Admin.csproj index 167c0d25d..e83a10531 100644 --- a/src/AliasVault.Admin/AliasVault.Admin.csproj +++ b/src/AliasVault.Admin/AliasVault.Admin.csproj @@ -48,9 +48,4 @@ - - - <_ContentIncludedByDefault Remove="Main\Components\Refresh\RefreshButton.razor" /> - - diff --git a/src/AliasVault.Admin/Main/Pages/Logging/Auth.razor b/src/AliasVault.Admin/Main/Pages/Logging/Auth.razor new file mode 100644 index 000000000..9dff19894 --- /dev/null +++ b/src/AliasVault.Admin/Main/Pages/Logging/Auth.razor @@ -0,0 +1,149 @@ +@page "/logging/auth" +@using AliasVault.Shared.Models.Enums +@inherits MainBase + +Auth logs + +
+
+ +
+

Auth logs

+ +
+

This page gives an overview of recent auth attempts.

+
+
+ +@if (IsLoading) +{ + +} +else +{ +
+ + +
+
+
+ +
+
+ +
+
+
+ + + + + + + + + + + + + @foreach (var log in LogList) + { + + + + + + + + + } + +
IDTimeUsernameEventSuccessIP
@log.Id@log.Timestamp.ToString("yyyy-MM-dd HH:mm")@log.Username@log.EventType@log.IpAddress
+
+} + +@code { + private List LogList { get; set; } = []; + private bool IsLoading { get; set; } = true; + private int CurrentPage { get; set; } = 1; + private int PageSize { get; set; } = 50; + private int TotalRecords { get; set; } + + private string _searchTerm = string.Empty; + private string SearchTerm + { + get => _searchTerm; + set + { + if (_searchTerm != value) + { + _searchTerm = value; + _ = RefreshData(); + } + } + } + + private string _selectedEventType = string.Empty; + private string SelectedEventType + { + get => _selectedEventType; + set + { + if (_selectedEventType != value) + { + _selectedEventType = value; + _ = RefreshData(); + } + } + } + + /// + protected override async Task OnInitializedAsync() + { + await RefreshData(); + } + + private void HandlePageChanged(int newPage) + { + CurrentPage = newPage; + _ = RefreshData(); + } + + private async Task RefreshData() + { + IsLoading = true; + StateHasChanged(); + + var query = DbContext.AuthLogs.AsQueryable(); + + if (!string.IsNullOrEmpty(SearchTerm)) + { + query = query.Where(x => EF.Functions.Like(x.Username.ToLower(), "%" + SearchTerm.ToLower() + "%")); + } + + if (!string.IsNullOrEmpty(SelectedEventType)) + { + var success = Enum.TryParse(SelectedEventType, out var eventType); + if (success) + { + query = query.Where(x => x.EventType == eventType); + } + } + + TotalRecords = await query.CountAsync(); + LogList = await query + .OrderByDescending(x => x.Timestamp) + .Skip((CurrentPage - 1) * PageSize) + .Take(PageSize) + .ToListAsync(); + + IsLoading = false; + StateHasChanged(); + } +} diff --git a/src/AliasVault.Admin/Main/Pages/Logging/General.razor b/src/AliasVault.Admin/Main/Pages/Logging/General.razor new file mode 100644 index 000000000..07d9ad972 --- /dev/null +++ b/src/AliasVault.Admin/Main/Pages/Logging/General.razor @@ -0,0 +1,168 @@ +@page "/logging/general" +@inherits MainBase + +System logs + +
+
+ +
+

General logs

+ +
+

This page gives an overview of recent system logs.

+
+
+ +@if (IsLoading) +{ + +} +else +{ +
+ + +
+
+
+ +
+
+ +
+
+
+ + + + + + + + + + + + @foreach (var log in LogList) + { + + + + + + @{ + string bgColor = log.Level switch + { + "Information" => "bg-blue-500", + "Error" => "bg-red-500", + "Warning" => "bg-yellow-500", + "Debug" => "bg-green-500", + _ => "bg-gray-500" + }; + } + + + + } + +
IDTimeApplicationLevelMessage
@log.Id@log.TimeStamp.ToString("yyyy-MM-dd HH:mm")@log.Application + + @log.Level + + + @if (log.SourceContext.Length > 0) + { + @log.SourceContext: + } + @log.Message +
+
+} + +@code { + private List LogList { get; set; } = []; + private bool IsLoading { get; set; } = true; + private int CurrentPage { get; set; } = 1; + private int PageSize { get; set; } = 50; + private int TotalRecords { get; set; } + + private string _searchTerm = string.Empty; + private string SearchTerm + { + get => _searchTerm; + set + { + if (_searchTerm != value) + { + _searchTerm = value; + _ = RefreshData(); + } + } + } + + private string _selectedServiceName = string.Empty; + private string SelectedServiceName + { + get => _selectedServiceName; + set + { + if (_selectedServiceName != value) + { + _selectedServiceName = value; + _ = RefreshData(); + } + } + } + + private List ServiceNames { get; set; } = []; + + /// + protected override async Task OnInitializedAsync() + { + ServiceNames = await DbContext.Logs.Select(l => l.Application).Distinct().ToListAsync(); + await RefreshData(); + } + + private void HandlePageChanged(int newPage) + { + CurrentPage = newPage; + _ = RefreshData(); + } + + private async Task RefreshData() + { + IsLoading = true; + StateHasChanged(); + + var query = DbContext.Logs.AsQueryable(); + + if (!string.IsNullOrEmpty(SearchTerm)) + { + query = query.Where(x => EF.Functions.Like(x.Application.ToLower(), "%" + SearchTerm.ToLower() + "%") || + EF.Functions.Like(x.Message.ToLower(), "%" + SearchTerm.ToLower() + "%") || + EF.Functions.Like(x.Level.ToLower(), "%" + SearchTerm.ToLower() + "%")); + } + + if (!string.IsNullOrEmpty(SelectedServiceName)) + { + query = query.Where(x => x.Application == SelectedServiceName); + } + + TotalRecords = await query.CountAsync(); + LogList = await query + .OrderByDescending(x => x.Id) + .Skip((CurrentPage - 1) * PageSize) + .Take(PageSize) + .ToListAsync(); + + IsLoading = false; + StateHasChanged(); + } +}