fix(central-ui): resolve CentralUI-007..014 — nav authz, UTC date filters, disposal guards, N+1 fix, async script analysis

This commit is contained in:
Joseph Doherty
2026-05-16 20:58:03 -04:00
parent 738e67acc5
commit 71b90ba499
21 changed files with 976 additions and 81 deletions

View File

@@ -1,5 +1,6 @@
@page "/monitoring/audit-log"
@using ScadaLink.Security
@using ScadaLink.CentralUI.Components
@using ScadaLink.Commons.Entities.Audit
@using ScadaLink.Commons.Interfaces.Repositories
@attribute [Authorize(Policy = AuthorizationPolicies.RequireAdmin)]
@@ -195,6 +196,12 @@
private DateTime? _filterFrom;
private DateTime? _filterTo;
// The datetime-local filter inputs are in the browser's local time zone.
// This holds new Date().getTimezoneOffset() so the values are converted to
// UTC (CentralUI-008) rather than relabelled. Until JS interop runs it is 0
// (UTC), which is a safe default for a UTC server/browser.
private int _browserUtcOffsetMinutes;
private List<AuditLogEntry>? _entries;
private int _totalCount;
private int _page = 1;
@@ -209,6 +216,23 @@
private int TotalPages => _pageSize > 0 ? Math.Max(1, (_totalCount + _pageSize - 1) / _pageSize) : 1;
private bool HasMore => _page * _pageSize < _totalCount;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (!firstRender) return;
try
{
// Date.getTimezoneOffset() returns (UTC - local) in minutes.
_browserUtcOffsetMinutes = await JS.InvokeAsync<int>(
"eval", "new Date().getTimezoneOffset()");
}
catch (Exception ex) when (ex is JSException or JSDisconnectedException
or InvalidOperationException or TaskCanceledException)
{
// Prerender or a disconnected circuit: fall back to UTC (offset 0).
_browserUtcOffsetMinutes = 0;
}
}
private async Task Search()
{
_page = 1;
@@ -239,8 +263,8 @@
user: string.IsNullOrWhiteSpace(_filterUser) ? null : _filterUser.Trim(),
entityType: string.IsNullOrWhiteSpace(_filterEntityType) ? null : _filterEntityType.Trim(),
action: string.IsNullOrWhiteSpace(_filterAction) ? null : _filterAction.Trim(),
from: _filterFrom.HasValue ? new DateTimeOffset(_filterFrom.Value, TimeSpan.Zero) : null,
to: _filterTo.HasValue ? new DateTimeOffset(_filterTo.Value, TimeSpan.Zero) : null,
from: BrowserTime.LocalInputToUtc(_filterFrom, _browserUtcOffsetMinutes),
to: BrowserTime.LocalInputToUtc(_filterTo, _browserUtcOffsetMinutes),
page: _page,
pageSize: _pageSize);

View File

@@ -1,5 +1,5 @@
@page "/monitoring/event-logs"
@attribute [Authorize]
@attribute [Authorize(Policy = ScadaLink.Security.AuthorizationPolicies.RequireDeployment)]
@using ScadaLink.Commons.Entities.Sites
@using ScadaLink.Commons.Interfaces.Repositories
@using ScadaLink.Commons.Messages.RemoteQuery

View File

@@ -1,5 +1,5 @@
@page "/monitoring/parked-messages"
@attribute [Authorize]
@attribute [Authorize(Policy = ScadaLink.Security.AuthorizationPolicies.RequireDeployment)]
@using ScadaLink.Commons.Entities.Sites
@using ScadaLink.Commons.Interfaces.Repositories
@using ScadaLink.Commons.Messages.RemoteQuery