fix(notification): enable web smtp test with saved password

Allow Web SMTP egress on TCP 587 and reuse the saved channel password only when connection settings match.

Ref: IT-1601
This commit is contained in:
2026-10-18 00:17:25 +03:00
parent 121ebbfbcd
commit 2dd5e318d7
9 changed files with 260 additions and 5 deletions
@@ -138,8 +138,21 @@ public class AdminChannelsController(IMediator mediator) : Controller
[HttpPost("test-smtp")]
public async Task<IActionResult> TestSmtp([FromBody] TestSmtpRequest request, CancellationToken ct)
{
var password = request.Password;
if (string.IsNullOrEmpty(password) && request.ChannelId is Guid channelId)
{
var channelResult = await mediator.Send(new GetEmailChannelQuery(channelId), ct);
if (!channelResult.IsSuccess || channelResult.Result?.Settings is not SmtpChannelSettings saved)
return Ok(new { success = false, message = "SMTP channel not found." });
if (!MatchesSavedSmtpConnection(request, saved))
return Ok(new { success = false, message = "Enter the password to test changed SMTP connection settings." });
password = saved.Password;
}
var result = await mediator.Send(new TestSmtpCommand(
request.Host, request.Port, request.Username, request.Password,
request.Host, request.Port, request.Username, password ?? string.Empty,
request.UseSsl, request.FromEmail, request.FromName, request.ToEmail), ct);
if (!result.IsSuccess)
@@ -148,6 +161,12 @@ public class AdminChannelsController(IMediator mediator) : Controller
return Ok(new { success = true, message = $"Test email sent to {request.ToEmail}." });
}
private static bool MatchesSavedSmtpConnection(TestSmtpRequest request, SmtpChannelSettings saved) =>
string.Equals(request.Host, saved.Host, StringComparison.OrdinalIgnoreCase)
&& request.Port == saved.Port
&& string.Equals(request.Username, saved.Username, StringComparison.Ordinal)
&& request.UseSsl == saved.UseSsl;
// POST /admin/channels/{id}/test
[HttpPost("{id:guid}/test")]
public async Task<IActionResult> Test(Guid id, [FromBody] TestChannelRequest request, CancellationToken ct)
@@ -180,6 +199,3 @@ public class AdminChannelsController(IMediator mediator) : Controller
}
public record TestChannelRequest(string ToEmail);
public record TestSmtpRequest(
string Host, int Port, string Username, string Password,
bool UseSsl, string FromEmail, string FromName, string ToEmail);
@@ -0,0 +1,6 @@
namespace HrynCo.NotificationService.Web.Controllers.Admin;
public record TestSmtpRequest(
string Host, int Port, string Username, string Password,
bool UseSsl, string FromEmail, string FromName, string ToEmail,
Guid? ChannelId = null);
@@ -138,7 +138,7 @@
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p class="text-muted small">Tests the current form settings — no need to save first.</p>
<p class="text-muted small">Tests the current form settings — no need to save first. For an existing channel, a blank password uses the saved password only when the SMTP connection settings are unchanged.</p>
<label for="testToEmail" class="form-label fw-semibold">Recipient Email</label>
<input type="email" id="testToEmail" class="form-control" placeholder="you@example.com" />
<div id="testResult" class="mt-3" style="display:none"></div>
@@ -173,7 +173,9 @@
}
const form = document.getElementById('channelForm');
const channelId = form.querySelector('[name="Id"]').value;
const payload = {
channelId: channelId === '00000000-0000-0000-0000-000000000000' ? null : channelId,
host: form.querySelector('[name="Host"]').value,
port: parseInt(form.querySelector('[name="Port"]').value, 10),
username: form.querySelector('[name="Username"]').value,