feat(regras): aplica as regras na entrega e envia a resposta de ausência
A metade que faltava. O motor já existia e nada o chamava; agora o caminho de entrega consulta as regras da caixa que está a receber, e a resposta de ausência é mesmo enviada. Cada destinatário tem as suas próprias regras, avaliadas sobre a sua própria cópia: duas caixas neste servidor que recebem a mesma mensagem podem arquivá-la em sítios diferentes. Nada disto pode impedir o correio de chegar. Um script que não faz parse, ou uma base de dados que não responde, deixa a mensagem ser entregue sem filtro em vez de a recusar - recusar diria ao remetente que a mensagem falhou, e o servidor dele voltaria a tentar para sempre. discard é aceitar e depois deitar fora, pela mesma razão: uma regra de arquivo não é uma rejeição. A resposta de ausência sai pela mesma fila, assinatura e limites de envio que qualquer outra mensagem deste servidor - não é um caminho especial - e só depois de a mensagem que a desencadeou estar guardada, para não responder a correio que a caixa afinal não recebeu. Leva Auto-Submitted: auto-replied, que é o que impede duas caixas ambas de férias de se responderem uma à outra até uma esgotar a quota. Pastas próprias. Só existiam as seis padrão, portanto uma regra que dizia "arquiva isto em Faturas" nomeava uma pasta que não havia como criar. Criar, renomear e apagar, com as reservadas protegidas: cada uma delas significa alguma coisa para o protocolo ou para este servidor, e deixar renomear a INBOX partia caminhos que nenhuma mensagem de erro explica. Renomear não mexe nas mensagens nem nos UIDs, senão um cliente IMAP perdia de vista tudo o que lá está dentro. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b9ebf606e1
commit
42420a7de2
14 files changed
+1082
-6
No files matched your search
@@ -131,6 +131,11 @@ func run(cfg config) {
|
||||
reportsUC := usecase.NewIngestReportsUseCase(reportRepo)
|
||||
inboundUC.SetReportIngestor(usecase.NewIngestDeliveredReportsUseCase(reportsUC))
|
||||
|
||||
// The mailbox's own filing rules, applied as mail arrives. Until this was
|
||||
// wired the scripts were stored and never read, so a vacation responder
|
||||
// that was switched on never replied and no filter ever filed anything.
|
||||
inboundUC.SetRules(usecase.NewApplyRulesUseCase(postgres.NewSieveRepository(pool)))
|
||||
|
||||
// ------------------------------------------------------------ outbound
|
||||
var signer port.DkimSigner
|
||||
if dkimRepo != nil {
|
||||
@@ -138,6 +143,12 @@ func run(cfg config) {
|
||||
}
|
||||
submissionUC := usecase.NewProcessOutboundEmailUseCase(authRepo, outboundRepo, blobs, signer)
|
||||
|
||||
// The vacation responder needs a way to actually send. Wired after the
|
||||
// submission use case exists, because an automatic reply goes out through
|
||||
// the same queue, signing and send limits as any other message this
|
||||
// server sends - it is not a special path.
|
||||
inboundUC.SetVacationSender(submissionUC, authRepo, cfg.PrimaryMailHost)
|
||||
|
||||
mxResolver := netdns.NewNetMXResolver()
|
||||
outboundWorker := usecase.NewOutboundWorkerUseCase(outboundRepo, mxResolver, blobReader, inboundUC, mailboxes, cfg.PrimaryMailHost)
|
||||
outboundWorker.SetPolicyResolver(buildPolicyResolver(cfg))
|
||||
@@ -191,6 +202,10 @@ func run(cfg config) {
|
||||
log.Printf("JWT_SECRET is not set: the webmail mail API stays disabled")
|
||||
}
|
||||
router.SetMailAPI(webmailUC, cfg.JwtSecret)
|
||||
// Folders the mailbox owner keeps for themselves, which the filing rules
|
||||
// can then name as a destination.
|
||||
router.SetFolderAdmin(usecase.NewManageFoldersUseCase(
|
||||
postgres.NewWebmailRepository(pool), postgres.NewWebmailRepository(pool)))
|
||||
if dkimRepo != nil {
|
||||
router.SetAdminDkimAPI(dkimRepo, generateDkimKey, cfg.JwtSecret)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user