Files
SocialPub/PrivaPub/Services/Mailer.cs
T
thepraandClaude Opus 5.5 70d1ffe9a2
Build / Build (push) Successful in 1m3s
R5 the server's own settings: instance, rules, announcements, relays, media limits, the staff's log
A singleton ServerSettings (title, descriptions, contact, thumbnail, privacy policy, terms, rules, relays, media
overrides, PublishActivity), cached by InstanceSettings and read by the instance API, NodeInfo, the instance actor, the
web pages and the mailer; its defaults are the old literals, so nothing changes until an administrator edits.
/clientapi/admin/settings (and /thumbnail), /announcements, /relays for administrators; /clientapi/moderator/log, the
staff's log (AdminAction, written by domain blocks, backups, settings and the CLI; no IP, never a root paired with its
personas). The Mastodon API's rules, extended description, privacy policy, terms of service, domain blocks (Published,
Obfuscate), announcements (dismiss, reactions, streaming) and activity (only when published). Reports carry rule ids.
Media overrides clamped to hard caps. Relays named by the settings reconcile next to the configured ones.

Verified: interop.sh instance accounts relay with mastodon, relay, aoderelay and mailpit, 119 passed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WpVCoDeM1qUTRp4fXQdfof
2026-10-17 04:02:47 +02:00

47 lines
1.6 KiB
C#

using MailKit.Net.Smtp;
using Microsoft.Extensions.Options;
using MimeKit;
using PrivaPub.Models;
namespace PrivaPub.Services
{
public interface IMailer
{
/// <summary>Sends a plain-text email; throws when SMTP fails, so the job that sends it retries.</summary>
Task Send(string to, string subject, string body, CancellationToken token);
}
// The server's one way to send an email: through the SMTP account in appsettings (AppConfiguration:EmailConfiguration),
// read as it is now. Only jobs call it, so nobody waits on SMTP.
public class Mailer : IMailer
{
readonly IOptionsMonitor<AppConfiguration> _app;
readonly Domain.Instance.IInstanceSettings _settings;
public Mailer(IOptionsMonitor<AppConfiguration> app, Domain.Instance.IInstanceSettings settings)
{
_app = app;
_settings = settings;
}
public async Task Send(string to, string subject, string body, CancellationToken token)
{
var email = _app.CurrentValue.EmailConfiguration;
var message = new MimeMessage();
message.From.Add(new MailboxAddress(_settings.Current.Title, email.SmtpUsername));//the server's name, as its administrator set it
message.To.Add(MailboxAddress.Parse(to));
message.Subject = subject;
message.Body = new TextPart("plain") { Text = body };
using var smtp = new SmtpClient();
await smtp.ConnectAsync(email.SmtpServer, email.SmtpPort, email.UseSSL, token);
if (!string.IsNullOrEmpty(email.SmtpPassword))
await smtp.AuthenticateAsync(email.SmtpUsername, email.SmtpPassword, token);
await smtp.SendAsync(message, token);
await smtp.DisconnectAsync(quit: true, token);
}
}
}