Resolve all high-severity architecture review findings

This commit is contained in:
Joseph Doherty
2026-09-09 16:13:58 -04:00
parent 8bfe65512e
commit 146a13238f
192 changed files with 3160 additions and 753 deletions
@@ -1,7 +1,9 @@
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management
@inject IServiceProvider MutationServices
@page "/notifications/lists/create"
@page "/notifications/lists/{Id:int}/edit"
@using ZB.MOM.WW.ScadaBridge.Security
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Notifications
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Enums
@@ -185,20 +187,9 @@
try
{
if (_existing != null)
{
_existing.Name = _name.Trim();
await NotificationRepository.UpdateNotificationListAsync(_existing);
}
else
{
// Type is set at create time and never changes thereafter (the selector
// is disabled on edit) so a list's recipients always carry the matching
// contact field.
var nl = new NotificationList(_name.Trim()) { Type = _type };
await NotificationRepository.AddNotificationListAsync(nl);
}
await NotificationRepository.SaveChangesAsync();
await MutationServices.ExecuteConfigurationAsync(_existing is not null
? new RenameNotificationListCommand(_existing.Id, _name.Trim())
: new CreateNotificationListCommand(_name.Trim(), [], _type));
NavigationManager.NavigateTo("/notifications/lists");
}
catch (Exception ex) { _formError = ex.Message; }
@@ -238,8 +229,7 @@
try
{
await NotificationRepository.AddRecipientAsync(r);
await NotificationRepository.SaveChangesAsync();
await MutationServices.ExecuteConfigurationAsync(new AddNotificationRecipientCommand(r.NotificationListId, r.Name, r.EmailAddress, r.PhoneNumber));
_recipientName = _recipientEmail = _recipientPhone = string.Empty;
_recipients = (await NotificationRepository.GetRecipientsByListIdAsync(Id.Value)).ToList();
}
@@ -264,8 +254,7 @@
{
try
{
await NotificationRepository.DeleteRecipientAsync(r.Id);
await NotificationRepository.SaveChangesAsync();
await MutationServices.ExecuteConfigurationAsync(new DeleteNotificationRecipientCommand(r.Id));
_recipients = (await NotificationRepository.GetRecipientsByListIdAsync(Id!.Value)).ToList();
}
catch (Exception ex) { _recipientFormError = ex.Message; }
@@ -1,3 +1,6 @@
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management
@inject IServiceProvider MutationServices
@page "/notifications/lists"
@using ZB.MOM.WW.ScadaBridge.Security
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Notifications
@@ -165,8 +168,7 @@
}
try
{
await NotificationRepository.DeleteNotificationListAsync(list.Id);
await NotificationRepository.SaveChangesAsync();
await MutationServices.ExecuteConfigurationAsync(new DeleteNotificationListCommand(list.Id));
_toast.ShowSuccess("Deleted.");
await LoadAsync();
}
@@ -604,7 +604,8 @@
_actionInProgress = true;
try
{
var requestedBy = await AuthStateProvider.GetCurrentUsernameAsync();
if (!await IsRowSiteAllowedAsync(n.SourceSiteId)) throw new UnauthorizedAccessException("Site access was revoked.");
var requestedBy = await AuthStateProvider.RequireRoleAsync(ZB.MOM.WW.ScadaBridge.Security.Roles.Deployer);
var response = await CommunicationService.RetryNotificationAsync(
new RetryNotificationRequest(Guid.NewGuid().ToString("N"), n.NotificationId, requestedBy));
if (response.Success)
@@ -642,7 +643,8 @@
_actionInProgress = true;
try
{
var requestedBy = await AuthStateProvider.GetCurrentUsernameAsync();
if (!await IsRowSiteAllowedAsync(n.SourceSiteId)) throw new UnauthorizedAccessException("Site access was revoked.");
var requestedBy = await AuthStateProvider.RequireRoleAsync(ZB.MOM.WW.ScadaBridge.Security.Roles.Deployer);
var response = await CommunicationService.DiscardNotificationAsync(
new DiscardNotificationRequest(Guid.NewGuid().ToString("N"), n.NotificationId, requestedBy));
if (response.Success)
@@ -848,6 +850,9 @@
return _permittedSiteIds.Contains(resolved.Id);
}
private Task<bool> IsRowSiteAllowedAsync(string sourceSiteId)
=> Task.FromResult(IsRowSiteAllowedSync(sourceSiteId));
private async Task<bool> IsRowSiteAllowedAsync(string sourceSiteId)
{
var resolved = (await SiteRepository.GetAllSitesAsync()).FirstOrDefault(s => s.SiteIdentifier == sourceSiteId);
return resolved is not null && await SiteScope.IsSiteAllowedAsync(resolved.Id);
}
}
@@ -1,3 +1,6 @@
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management
@inject IServiceProvider MutationServices
@page "/notifications/sms"
@using ZB.MOM.WW.ScadaBridge.Security
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories
@@ -245,48 +248,18 @@
try
{
if (_editingSms != null)
if (_editingSms is null && typedAuthToken is null)
{
_editingSms.AccountSid = _accountSid.Trim();
_editingSms.FromNumber = string.IsNullOrWhiteSpace(_fromNumber) ? null : _fromNumber.Trim();
_editingSms.MessagingServiceSid = string.IsNullOrWhiteSpace(_messagingServiceSid)
? null
: _messagingServiceSid.Trim();
_editingSms.ApiBaseUrl = string.IsNullOrWhiteSpace(_apiBaseUrl) ? null : _apiBaseUrl.Trim();
// Preserve-if-blank: only overwrite the stored token when a new value was typed.
if (typedAuthToken != null)
{
_editingSms.AuthToken = typedAuthToken;
}
_editingSms.ConnectionTimeoutSeconds = _connectionTimeoutSeconds;
_editingSms.MaxRetries = _maxRetries;
_editingSms.RetryDelay = TimeSpan.FromSeconds(_retryDelaySeconds);
await NotificationRepository.UpdateSmsConfigurationAsync(_editingSms);
_formError = "Auth Token is required.";
return;
}
else
{
if (typedAuthToken == null)
{
_formError = "Auth Token is required.";
return;
}
var sms = new SmsConfigurationEntity(
_accountSid.Trim(),
string.IsNullOrWhiteSpace(_fromNumber) ? null : _fromNumber.Trim())
{
MessagingServiceSid = string.IsNullOrWhiteSpace(_messagingServiceSid)
? null
: _messagingServiceSid.Trim(),
ApiBaseUrl = string.IsNullOrWhiteSpace(_apiBaseUrl) ? null : _apiBaseUrl.Trim(),
AuthToken = typedAuthToken,
ConnectionTimeoutSeconds = _connectionTimeoutSeconds,
MaxRetries = _maxRetries,
RetryDelay = TimeSpan.FromSeconds(_retryDelaySeconds),
};
await NotificationRepository.AddSmsConfigurationAsync(sms);
}
await NotificationRepository.SaveChangesAsync();
var from = string.IsNullOrWhiteSpace(_fromNumber) ? null : _fromNumber.Trim();
var messaging = string.IsNullOrWhiteSpace(_messagingServiceSid) ? null : _messagingServiceSid.Trim();
await MutationServices.ExecuteConfigurationAsync(_editingSms is not null
? new UpdateSmsConfigCommand(_editingSms.Id, _accountSid.Trim(), from, messaging, _apiBaseUrl?.Trim() ?? "", typedAuthToken,
_connectionTimeoutSeconds, _maxRetries, TimeSpan.FromSeconds(_retryDelaySeconds))
: new CreateSmsConfigCommand(_accountSid.Trim(), from, messaging, _apiBaseUrl?.Trim(), typedAuthToken,
_connectionTimeoutSeconds, _maxRetries, TimeSpan.FromSeconds(_retryDelaySeconds)));
_showForm = false;
_toast.ShowSuccess("SMS configuration saved.");
await LoadAsync();
@@ -1,3 +1,6 @@
@using ZB.MOM.WW.ScadaBridge.CentralUI.Services
@using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management
@inject IServiceProvider MutationServices
@page "/notifications/smtp"
@using ZB.MOM.WW.ScadaBridge.Security
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories
@@ -345,33 +348,11 @@
try
{
if (_editingSmtp != null)
{
_editingSmtp.Host = _host.Trim();
_editingSmtp.Port = _port;
_editingSmtp.Transport = _transport;
_editingSmtp.AuthType = _authType;
_editingSmtp.TlsMode = _tlsMode;
_editingSmtp.Credentials = _credentials?.Trim();
_editingSmtp.FromAddress = _fromAddress.Trim();
_editingSmtp.OAuth2Authority = NormalizeOptional(_oauth2Authority);
_editingSmtp.OAuth2Scope = NormalizeOptional(_oauth2Scope);
await NotificationRepository.UpdateSmtpConfigurationAsync(_editingSmtp);
}
else
{
var smtp = new SmtpConfigurationEntity(_host.Trim(), _authType, _fromAddress.Trim())
{
Port = _port,
Transport = _transport,
TlsMode = _tlsMode,
Credentials = _credentials?.Trim(),
OAuth2Authority = NormalizeOptional(_oauth2Authority),
OAuth2Scope = NormalizeOptional(_oauth2Scope)
};
await NotificationRepository.AddSmtpConfigurationAsync(smtp);
}
await NotificationRepository.SaveChangesAsync();
await MutationServices.ExecuteConfigurationAsync(_editingSmtp is not null
? new UpdateSmtpConfigCommand(_editingSmtp.Id, _host.Trim(), _port, _authType, _fromAddress.Trim(), _tlsMode,
_credentials?.Trim() ?? "", NormalizeOptional(_oauth2Authority) ?? "", NormalizeOptional(_oauth2Scope) ?? "", _transport)
: new CreateSmtpConfigCommand(_host.Trim(), _port, _authType, _fromAddress.Trim(), _tlsMode,
_credentials?.Trim(), NormalizeOptional(_oauth2Authority), NormalizeOptional(_oauth2Scope), _transport));
_showForm = false;
_toast.ShowSuccess("SMTP configuration saved.");
await LoadAsync();