package webui import ( "net/http" "os" "strings" "mailgoserver/internal/db" ) // emailLogAccessible checks a scoped admin's domain assignment against the sender // domain of an email log's MAIL FROM address — these logs predate per-domain admin // scoping and have no domain_id column, so this is the same text-domain heuristic as // accessibleDomainNames/emailDomain, not a foreign key. func (a *App) emailLogAccessible(r *http.Request, mailFrom string) (bool, error) { names, isGlobal, err := a.accessibleDomainNames(r) if err != nil { return false, err } return isGlobal || names[emailDomain(mailFrom)], nil } // viewMessageContent mirrors view_message.py's view_message_content(). func (a *App) viewMessageContent(w http.ResponseWriter, r *http.Request) { log, err := a.DB.GetEmailLogByID(pathID(r)) if err != nil || log == nil { http.NotFound(w, r) return } if ok, err := a.emailLogAccessible(r, log.MailFrom); err != nil || !ok { http.NotFound(w, r) return } attachments, _ := a.DB.ListAttachmentsForEmail(log.ID) a.render(w, r, "view_message_content.html", M{"active": "logs", "log": M{ "id": log.ID, "mail_from": log.MailFrom, "to_address": log.ToAddress, "cc_addresses": log.CcAddresses, "bcc_addresses": log.BccAddresses, "subject": log.Subject, "created_at": log.CreatedAt, "message_body": log.MessageBody, "email_headers": log.EmailHeaders, "attachments": attachments, }}) } var extContentType = map[string]string{ ".txt": "text/plain", ".csv": "text/csv", ".pdf": "application/pdf", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png", ".gif": "image/gif", ".svg": "image/svg+xml", ".html": "text/html", ".htm": "text/html", ".json": "application/json", ".xml": "application/xml", ".md": "text/markdown", } // downloadAttachment mirrors view_message.py's download_attachment(), including its // CSV-to-HTML-table inline preview special case. func (a *App) downloadAttachment(w http.ResponseWriter, r *http.Request) { att, err := a.DB.GetAttachmentByID(pathID(r)) if err != nil || att == nil { http.NotFound(w, r) return } if !a.attachmentAccessible(w, r, att) { return } if _, err := os.Stat(att.FilePath); err != nil { setFlash(w, "error", "Attachment file not found on disk") http.Redirect(w, r, Prefix+"/logs?type=emails", http.StatusFound) return } contentType := att.ContentType if contentType == "" || contentType == "application/octet-stream" { if ext := extOfName(att.Filename); ext != "" { if ct, ok := extContentType[ext]; ok { contentType = ct } } } asAttachment := r.URL.Query().Get("download") == "true" if contentType == "text/csv" && !asAttachment { data, err := os.ReadFile(att.FilePath) if err != nil { http.Error(w, "read error", http.StatusInternalServerError) return } w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Write([]byte("
| " + template_htmlEscape(cell) + " | ")) } w.Write([]byte("