From d5ea2aa824eee4b7e2d169d21da0107d057e7bc6 Mon Sep 17 00:00:00 2001 From: Bobby <30593201+luciferreeves@users.noreply.github.com> Date: Wed, 24 Dec 2025 17:17:15 +0530 Subject: feat: Implement API endpoints for email details and actions, and refactor email preview for client-side rendering with Shadow DOM. --- services/emails.go | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) (limited to 'services') diff --git a/services/emails.go b/services/emails.go index e007f87..4b440f4 100644 --- a/services/emails.go +++ b/services/emails.go @@ -4,6 +4,8 @@ import ( "lain/jobs" "lain/models" "lain/repository" + "lain/utils/crypto" + "lain/utils/email" "lain/utils/format" "net/url" "strings" @@ -56,3 +58,111 @@ func GetEmails(userEmail, folderPath string, prefs *models.Preferences, page int return emails, nil } + +func GetEmailDetails(userEmail string, emailID uint) (fiber.Map, error) { + message, err := repository.GetEmailByID(userEmail, emailID) + if err != nil { + return nil, err + } + + // Get attachments + attachments, _ := repository.GetAttachmentsByEmailID(emailID) + + var attachmentMaps []fiber.Map + for _, att := range attachments { + attachmentMaps = append(attachmentMaps, fiber.Map{ + "ID": att.ID, + "Filename": att.Filename, + "ContentType": att.ContentType, + "Size": format.FormatFileSize(att.Size), + }) + } + + // Sanitize HTML body + body := message.BodyHTML + if body == "" { + body = "
" + format.DecodeHTML(message.BodyText) + "
" + } else { + body = format.SanitizeHTML(body) + } + + return fiber.Map{ + "ID": message.ID, + "Subject": format.DecodeHTML(message.Subject), + "From": format.DecodeHTML(message.From), + "FromName": format.DecodeHTML(message.FromName), + "To": format.DecodeHTML(message.To), + "CC": format.DecodeHTML(message.CC), + "Date": message.Date, + "Body": body, + "IsRead": message.IsRead, + "IsFlagged": message.IsFlagged, + "Attachments": attachmentMaps, + }, nil +} + +func ToggleEmailFlag(userEmail string, emailID uint) (bool, error) { + message, err := repository.GetEmailByID(userEmail, emailID) + if err != nil { + return false, err + } + + prefs, err := repository.GetPreferencesByEmail(userEmail) + if err != nil { + return false, err + } + + password, err := crypto.Decrypt(prefs.Authorization) + if err != nil { + return false, err + } + + client, err := email.ConnectIMAP(userEmail, password) + if err != nil { + return false, err + } + defer email.DisconnectIMAP(client) + + if err := email.ToggleFlag(client, message.Folder.IMAPName, message.UID, message.IsFlagged); err != nil { + return false, err + } + + message.IsFlagged = !message.IsFlagged + repository.UpdateEmail(message) + + return message.IsFlagged, nil +} + +func MarkEmailAsRead(userEmail string, emailID uint) error { + message, err := repository.GetEmailByID(userEmail, emailID) + if err != nil { + return err + } + + if message.IsRead { + return nil + } + + prefs, err := repository.GetPreferencesByEmail(userEmail) + if err != nil { + return err + } + + password, err := crypto.Decrypt(prefs.Authorization) + if err != nil { + return err + } + + client, err := email.ConnectIMAP(userEmail, password) + if err != nil { + return err + } + defer email.DisconnectIMAP(client) + + if err := email.MarkAsRead(client, message.Folder.IMAPName, message.UID); err != nil { + return err + } + + message.IsRead = true + return repository.UpdateEmail(message) +} -- cgit v1.2.3