This commit is contained in:
@@ -0,0 +1 @@
|
||||
global using Microsoft.Extensions.Logging;
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Net.Mail;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace plushealthtech.Mail
|
||||
{
|
||||
/// <summary>
|
||||
/// Sends outbound email through the configured SMTP server (MailPit in local
|
||||
/// development). No authentication is used.
|
||||
/// </summary>
|
||||
public class MailSender
|
||||
{
|
||||
private readonly SmtpOptions _options;
|
||||
private readonly ILogger<MailSender> _logger;
|
||||
|
||||
public MailSender(IOptions<SmtpOptions> options, ILogger<MailSender> logger)
|
||||
{
|
||||
_options = options.Value;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public async Task SendAsync(string subject, string body)
|
||||
{
|
||||
using var client = new SmtpClient(_options.Host, _options.Port)
|
||||
{
|
||||
EnableSsl = false
|
||||
};
|
||||
|
||||
var message = new MailMessage(_options.From, _options.To)
|
||||
{
|
||||
Subject = subject,
|
||||
Body = body,
|
||||
IsBodyHtml = false
|
||||
};
|
||||
|
||||
await client.SendMailAsync(message);
|
||||
_logger.LogInformation("Mail sent to {To} (subject: {Subject})", _options.To, subject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using plushealthtech.Mail;
|
||||
|
||||
var options = Options.Create(new SmtpOptions
|
||||
{
|
||||
Host = "127.0.0.1",
|
||||
Port = 2525,
|
||||
From = "[email protected]",
|
||||
To = "[email protected]"
|
||||
});
|
||||
|
||||
var sender = new MailSender(options, NullLogger<MailSender>.Instance);
|
||||
|
||||
// Same shape as ContactModel.OnPostAsync: em dash in the subject, ASCII body
|
||||
// plus one em dash in the message, as a user might type.
|
||||
var subject = "New contact form message — Dr. Vera Test";
|
||||
var body = string.Join("\n", new[]
|
||||
{
|
||||
"Name: Dr. José Ñ test",
|
||||
"Email: [email protected]",
|
||||
"",
|
||||
"Task 13 e2e verification message — please ignore."
|
||||
});
|
||||
|
||||
await sender.SendAsync(subject, body);
|
||||
Console.WriteLine("sent");
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace plushealthtech.Mail
|
||||
{
|
||||
/// <summary>
|
||||
/// SMTP settings bound from the "Smtp" section of appsettings.json.
|
||||
/// </summary>
|
||||
public class SmtpOptions
|
||||
{
|
||||
public string Host { get; set; } = "localhost";
|
||||
public int Port { get; set; } = 1025;
|
||||
public string From { get; set; } = string.Empty;
|
||||
public string To { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="10.0.11" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.11" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.11" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,27 @@
|
||||
import socket, sys, threading
|
||||
|
||||
def handle(conn):
|
||||
conn.sendall(b"220 sink ready\r\n")
|
||||
buf = b""
|
||||
while True:
|
||||
data = conn.recv(65536)
|
||||
if not data:
|
||||
break
|
||||
buf += data
|
||||
if b"QUIT" in data:
|
||||
break
|
||||
open(r"C:\Code\Plushealthtech\tmp-mailtest\raw_capture.bin", "wb").write(buf)
|
||||
try:
|
||||
conn.sendall(b"221 bye\r\n")
|
||||
except Exception:
|
||||
pass
|
||||
conn.close()
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
s.bind(("127.0.0.1", 2525))
|
||||
s.listen(1)
|
||||
print("listening on 127.0.0.1:2525", flush=True)
|
||||
c, _ = s.accept()
|
||||
handle(c)
|
||||
print("done", flush=True)
|
||||
Reference in New Issue
Block a user