diff --git a/README.md b/README.md index 64e9fdba..2a253e58 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ This repository is the full **implementation** project for ScadaBridge — the C | Central Database | MS SQL Server, Entity Framework Core | | Site Storage | SQLite (deployed configs, S&F buffer, event logs) | | Authentication | Direct LDAP/AD bind (LDAPS/StartTLS), JWT sessions | -| Notifications | Delivered from the central cluster (Email via SMTP/OAuth2-M365; SMS via Twilio REST); store-and-forwarded from sites | +| Notifications | Delivered from the central cluster (Email via SMTP/OAuth2-M365 or on-prem Exchange EWS; SMS via Twilio REST); store-and-forwarded from sites | | Hosting | Windows Server, Windows Service | | Cluster | Akka.NET Cluster (active/standby, keep-oldest SBR) | | Logging | Serilog (structured) | diff --git a/docs/plans/2026-08-10-ews-email-transport-design.md b/docs/plans/2026-08-10-ews-email-transport-design.md index 4197c26e..cdd61fa5 100644 --- a/docs/plans/2026-08-10-ews-email-transport-design.md +++ b/docs/plans/2026-08-10-ews-email-transport-design.md @@ -137,7 +137,7 @@ call (~200 lines including classification). three fields are now pinned. ### 4.5 Testing (owner decision: fake stub + live gate) -- **Unit:** `EwsSoapMailSender` against an in-process fake EWS endpoint (Kestrel `TestServer`) +- **Unit:** `EwsSoapMailSender` against a stubbed `HttpMessageHandler` (in-process fake EWS endpoint) asserting the Basic header, envelope shape (BCC-only, SendOnly, escaping) and driving canned `CreateItemResponse` success / SOAP-fault / HTTP-error bodies through the sender's classification (see §4.3 — no standalone classifier type); @@ -184,3 +184,8 @@ Raised while implementing; none blocking, none scheduled here. scrubbed on its own; EWS messages are still covered by the packed `username:password` and base64 Basic-auth scrubs, which comfortably exceed the floor. Revisit if a code path ever surfaces a bare short password. +4. **Central UI SMTP page bypasses audit.** `SmtpConfiguration.razor` writes through + `INotificationRepository` directly (pre-existing pattern), so a UI change to `Transport` or the + EWS credential produces no audit row, while the same change via CLI/API is audited by + `ManagementActor`. Made more consequential by EWS; route the page through + `UpdateSmtpConfigCommand` (or add a direct audit call) in a follow-up.