INBOX-3: SMTP send + Gmail threading (POST /api/requests/{id}/send)
- IGmailMailSender (mockable) + MailKit GmailMailSender (smtp.gmail.com:587 STARTTLS, App
Password). SendReplyService builds a threaded reply: In-Reply-To = original Message-Id,
References = stored chain + original (deduped), Subject = 'Re: ' (no double-prefix); sends,
then sets Status=Answered + AnsweredAt + stores sent body in DraftReply. Never auto-sends.
- POST /api/requests/{id}/send {body}: 200 updated RequestDto; 404 unknown; 503 MailNotConfigured;
502 MailAuthFailed (UI hint: re-enter App Password). No entity change (no migration).
- Tests (fake SMTP): threading headers, Answered transition, no-double-Re, not-configured +
auth-failure keep status; BuildMimeMessage header mapping. Live send gated on App Password.
This commit is contained in:
@@ -51,6 +51,25 @@ namespace GerbilManagerWebAPI.Endpoints
|
||||
return TypedResults.NoContent();
|
||||
});
|
||||
|
||||
// POST /api/requests/{id}/send — send the (edited) reply, threaded, mark Answered
|
||||
api.MapPost("/requests/{id:guid}/send", async Task<Results<Ok<RequestDto>, NotFound, ProblemHttpResult>> (
|
||||
Guid id, SendReplyInput input, SendReplyService sender, ApplicationContext db) =>
|
||||
{
|
||||
var r = await db.Requests.FirstOrDefaultAsync(x => x.Id == id);
|
||||
if (r is null) return TypedResults.NotFound();
|
||||
|
||||
var outcome = await sender.SendAsync(r, input.Body ?? "");
|
||||
return outcome.Error switch
|
||||
{
|
||||
null => TypedResults.Ok(ToDto(r)),
|
||||
"MailNotConfigured" => TypedResults.Problem(
|
||||
"Gmail ist noch nicht konfiguriert.", statusCode: 503, title: "MailNotConfigured"),
|
||||
"MailAuthFailed" => TypedResults.Problem(
|
||||
"Gmail-Anmeldung fehlgeschlagen — App-Passwort erneut eingeben.", statusCode: 502, title: "MailAuthFailed"),
|
||||
var code => TypedResults.Problem(code, statusCode: 500, title: code),
|
||||
};
|
||||
});
|
||||
|
||||
// GET/PUT /api/mail-settings — App Password never leaves the server
|
||||
api.MapGet("/mail-settings", async (MailSettingsService svc) =>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user