From 6f8b9c755de07a80254129298dc47c4e7b7453ad Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 10 Aug 2026 06:38:46 -0400 Subject: [PATCH] feat(ui): EWS transport selector on /notifications/smtp --- .../Notifications/SmtpConfiguration.razor | 134 ++++++++++++++---- 1 file changed, 108 insertions(+), 26 deletions(-) diff --git a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Notifications/SmtpConfiguration.razor b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Notifications/SmtpConfiguration.razor index c50ad77b..5d9092da 100644 --- a/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Notifications/SmtpConfiguration.razor +++ b/src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Notifications/SmtpConfiguration.razor @@ -46,12 +46,25 @@
-
Host
-
@smtp.Host:@smtp.Port
+
Transport
+
@(smtp.Transport ?? "Smtp")
+ @if (IsEws(smtp.Transport)) + { +
EWS URL
+
@smtp.Host
+ } + else + { +
Host
+
@smtp.Host:@smtp.Port
+ }
Auth Type
@smtp.AuthType
-
TLS Mode
-
@(string.IsNullOrWhiteSpace(smtp.TlsMode) ? "(not set)" : smtp.TlsMode)
+ @if (!IsEws(smtp.Transport)) + { +
TLS Mode
+
@(string.IsNullOrWhiteSpace(smtp.TlsMode) ? "(not set)" : smtp.TlsMode)
+ }
From Address
@smtp.FromAddress
Credentials
@@ -74,33 +87,44 @@
@(_editingSmtp != null ? "Edit SMTP Configuration" : "Add SMTP Configuration")
+
+ + +
- - -
-
- - -
-
- - -
-
- - + +
+ @if (!IsEwsForm) + { +
+ + +
+
+ + +
+
+ + +
+ }
+ placeholder="@(IsEwsForm ? @"domain\username:password" : "OAuth2 client secret or SMTP password")" />
Treat as sensitive — visible to admins only.
@@ -153,6 +177,10 @@ private string _host = string.Empty; private int _port = 587; + private string _transport = "Smtp"; + // AuthType as it was before the operator switched to Ews, so switching back to Smtp + // restores their choice rather than leaving the forced "Basic" behind. + private string _authTypeBeforeEws = "OAuth2"; private string _authType = "OAuth2"; private string? _tlsMode; private string? _credentials; @@ -163,6 +191,42 @@ private ToastNotification _toast = default!; + /// + /// Bound by the Transport select. The setter is where the transport's shape rules are + /// applied: EWS authenticates with HTTP Basic only, so selecting it forces the auth type + /// (which also hides the OAuth2 inputs, gated on AuthType as before). Switching back to + /// Smtp restores the auth type the operator had chosen. + /// + private string Transport + { + get => _transport; + set + { + if (string.Equals(_transport, value, StringComparison.Ordinal)) + { + return; + } + + if (IsEws(value)) + { + _authTypeBeforeEws = _authType; + _authType = "Basic"; + } + else + { + _authType = _authTypeBeforeEws; + } + _transport = value; + } + } + + /// Gets a value indicating whether the edit form is currently in EWS mode. + private bool IsEwsForm => IsEws(_transport); + + /// Null-safe, case-insensitive test for the EWS transport; null/blank means Smtp. + private static bool IsEws(string? transport) + => string.Equals(transport?.Trim(), "Ews", StringComparison.OrdinalIgnoreCase); + protected override async Task OnInitializedAsync() { await LoadAsync(); @@ -188,6 +252,8 @@ _editingSmtp = null; _host = string.Empty; _port = 587; + _transport = "Smtp"; + _authTypeBeforeEws = "OAuth2"; _authType = "OAuth2"; _tlsMode = "None"; _credentials = null; @@ -203,6 +269,8 @@ _editingSmtp = smtp; _host = smtp.Host; _port = smtp.Port; + _transport = smtp.Transport ?? "Smtp"; + _authTypeBeforeEws = smtp.AuthType; _authType = smtp.AuthType; _tlsMode = smtp.TlsMode; _credentials = smtp.Credentials; @@ -228,12 +296,25 @@ return; } + // This page writes through the repository, so the ManagementActor's EWS shape gate + // is not on this path — mirror its Host rule here (auth type is already forced to + // Basic by the Transport setter) so an unusable row cannot be saved from the UI. + if (IsEwsForm + && (!Uri.TryCreate(_host.Trim(), UriKind.Absolute, out var ewsEndpoint) + || !string.Equals(ewsEndpoint.Scheme, Uri.UriSchemeHttps, StringComparison.Ordinal))) + { + _formError = "EWS transport requires an absolute https:// EWS endpoint URL " + + "(e.g. https://mail.example.com/ews/exchange.asmx)."; + return; + } + try { if (_editingSmtp != null) { _editingSmtp.Host = _host.Trim(); _editingSmtp.Port = _port; + _editingSmtp.Transport = _transport; _editingSmtp.AuthType = _authType; _editingSmtp.TlsMode = _tlsMode; _editingSmtp.Credentials = _credentials?.Trim(); @@ -247,6 +328,7 @@ var smtp = new SmtpConfigurationEntity(_host.Trim(), _authType, _fromAddress.Trim()) { Port = _port, + Transport = _transport, TlsMode = _tlsMode, Credentials = _credentials?.Trim(), OAuth2Authority = NormalizeOptional(_oauth2Authority),