aboutsummaryrefslogtreecommitdiff
path: root/utils/smtp/session.go
diff options
context:
space:
mode:
authorBobby <[email protected]>2026-03-08 17:00:49 +0530
committerBobby <[email protected]>2026-03-08 17:00:49 +0530
commit2d5fb5e2078e92e7ec19582c3954409dd93f89fd (patch)
tree932f96385d56c94596cb2bb073f0f72b13d3eee4 /utils/smtp/session.go
parent0f254730178c9b0d9b171fef49993071a4b6a0f1 (diff)
downloaddove-2d5fb5e2078e92e7ec19582c3954409dd93f89fd.tar.xz
dove-2d5fb5e2078e92e7ec19582c3954409dd93f89fd.zip
feat(dns): Implement DNS record management and query handling
- Added models for various DNS record types: A, AAAA, CNAME, MX, SRV, and TXT. - Created repository functions for CRUD operations on DNS records. - Developed DNS server functionality to handle incoming queries and forward them to upstream servers. - Implemented local resolution for DNS queries, including support for A, AAAA, CNAME, MX, TXT, and SRV records. - Enhanced SMTP server to support TLS and STARTTLS configurations. - Improved email session handling with local delivery and error logging. - Added new log messages for better traceability of DNS operations and SMTP actions.
Diffstat (limited to 'utils/smtp/session.go')
-rw-r--r--utils/smtp/session.go108
1 files changed, 106 insertions, 2 deletions
diff --git a/utils/smtp/session.go b/utils/smtp/session.go
index 73fc4e1..ef5ddc7 100644
--- a/utils/smtp/session.go
+++ b/utils/smtp/session.go
@@ -2,9 +2,16 @@ package smtp
import (
"dove/config"
+ mailModel "dove/models/mail"
+ mailRepo "dove/repositories/mail"
+ "dove/utils/email"
"dove/utils/errors"
"dove/utils/logger"
+ "dove/utils/storage"
+ "fmt"
"io"
+ "strings"
+ "time"
gosmtp "github.com/emersion/go-smtp"
)
@@ -45,9 +52,41 @@ func (self *Session) Data(messageReader io.Reader) error {
return readError
}
- logger.Infof(LogPrefix, MessageReceived, len(rawMessage))
+ logger.Infof(LogPrefix, MessageReceived, len(rawMessage), self.fromAddress, self.toAddresses)
- _ = rawMessage
+ parsedEmail, parseError := email.Parse(rawMessage)
+ if parseError != nil {
+ logger.Errorf(LogPrefix, MessageParseFailed, parseError)
+ return parseError
+ }
+
+ deliveredToLocal := false
+
+ for _, recipientAddress := range self.toAddresses {
+ recipientMailbox := mailRepo.FindMailboxByAddress(recipientAddress)
+ if recipientMailbox == nil {
+ aliasMailbox := mailRepo.FindMailboxByAlias(recipientAddress)
+ if aliasMailbox != nil {
+ recipientMailbox = aliasMailbox
+ }
+ }
+
+ if recipientMailbox != nil {
+ deliverError := deliverToLocalMailbox(recipientMailbox, parsedEmail, rawMessage)
+ if deliverError != nil {
+ logger.Errorf(LogPrefix, DeliveryFailed, recipientAddress, deliverError)
+ continue
+ }
+ logger.Infof(LogPrefix, DeliverySuccess, recipientAddress)
+ deliveredToLocal = true
+ } else {
+ logger.Debugf(LogPrefix, RecipientNotLocal, recipientAddress)
+ }
+ }
+
+ if !deliveredToLocal {
+ logger.Warnf(LogPrefix, NoLocalRecipients, self.fromAddress)
+ }
return nil
}
@@ -60,3 +99,68 @@ func (self *Session) Reset() {
func (self *Session) Logout() error {
return nil
}
+
+func deliverToLocalMailbox(mailbox *mailModel.Mailbox, parsedEmail *email.ParsedEmail, rawMessage []byte) error {
+ inboxFolder := mailRepo.FindFolderBySlug(mailbox.ID, "inbox")
+ if inboxFolder == nil {
+ return errors.Error("Inbox folder not found for mailbox %s.", mailbox.Address)
+ }
+
+ filename := fmt.Sprintf("%d", time.Now().UnixNano())
+
+ toAddressesJoined := strings.Join(parsedEmail.ToAddresses, ", ")
+ ccAddressesJoined := strings.Join(parsedEmail.CcAddresses, ", ")
+ bccAddressesJoined := strings.Join(parsedEmail.BccAddresses, ", ")
+
+ attachmentCount := 0
+ inlineCount := 0
+ for _, attachment := range parsedEmail.Attachments {
+ if attachment.IsInline {
+ inlineCount++
+ } else {
+ attachmentCount++
+ }
+ }
+
+ emailRecord := &mailModel.Email{
+ MailboxID: mailbox.ID,
+ FolderID: inboxFolder.ID,
+ MessageID: parsedEmail.MessageID,
+ Filename: filename,
+ FromAddress: parsedEmail.FromAddress,
+ FromName: parsedEmail.FromName,
+ ToAddresses: toAddressesJoined,
+ CcAddresses: ccAddressesJoined,
+ BccAddresses: bccAddressesJoined,
+ ReplyToAddress: parsedEmail.ReplyToAddress,
+ ReturnPath: parsedEmail.ReturnPath,
+ Subject: parsedEmail.Subject,
+ Snippet: parsedEmail.Snippet,
+ Size: parsedEmail.Size,
+ IsRead: false,
+ AttachmentCount: attachmentCount,
+ InlineCount: inlineCount,
+ }
+
+ if createError := mailRepo.CreateEmail(emailRecord); createError != nil {
+ return createError
+ }
+
+ for _, parsedAttachment := range parsedEmail.Attachments {
+ attachmentRecord := &mailModel.Attachment{
+ EmailID: emailRecord.ID,
+ Filename: parsedAttachment.Filename,
+ ContentType: parsedAttachment.ContentType,
+ ContentID: parsedAttachment.ContentID,
+ Size: parsedAttachment.Size,
+ IsInline: parsedAttachment.IsInline,
+ }
+ mailRepo.CreateAttachment(attachmentRecord)
+ }
+
+ if writeError := storage.WriteMailFile(mailbox.Address, "inbox", filename, rawMessage); writeError != nil {
+ logger.Warnf(LogPrefix, MessageStoreFailed, writeError)
+ }
+
+ return nil
+}