Files
plane/email/pkg/services/session.go
Henit Chobisa c27e7ce03e feat: email service (#1541)
* feat: migrated email service to plane-ee

* feat: added build files

* fix: goreleaser for naming the binary

* fix: github CI

* feat: added certification generation

* fix: github CI

* feat: changed name for email service

* minor fixes to docker file and cert gen process. Added k8s manifest for testing

* removed build-email action

* added eks-cloudflare-setup instructions

* added support to gke

* modfied container ports from 25 465 587 to 10025 10465 10587

* cleanup yml files

* email docs cleanup

* added email service build action in plane cloud github action file

* fix: typo fix of email service image name

* fix: replaced base action for email service

* fix: registry name

* fix: uses in email service

* feat:modified-k8s-proxy

* updated k8s manifest

* updated k8s template

* fix: email build action

* fix image name

* fixed the spam detection mechanism

* upated k8s manifest

---------

Co-authored-by: Manish Gupta <manish@plane.so>
Co-authored-by: akshat5302 <akshatjain9782@gmail.com>
Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com>
Co-authored-by: Manish Gupta <59428681+mguptahub@users.noreply.github.com>
2025-02-14 17:47:09 +05:30

109 lines
2.2 KiB
Go

package services
import (
"bytes"
"errors"
"io"
"log"
"plane/email/pkg/utils/parser"
"strings"
"github.com/emersion/go-message/mail"
"github.com/emersion/go-smtp"
)
type Session struct {
From string
To []string
}
func (s *Session) AuthPlain(username, password string) error {
// log.Println("Authenticating user", username)
if AuthenticateUser(username, password) {
return nil
}
return errors.New("invalid username or password")
}
func (s *Session) Mail(from string, opts *smtp.MailOptions) error {
s.From = from
// log.Printf("Mail from: %s", from)
return nil
}
func (s *Session) Rcpt(to string, opts *smtp.RcptOptions) error {
// log.Printf("Rcpt to: %s", to)
s.To = append(s.To, to)
return nil
}
func (s *Session) Data(r io.Reader) error {
// log.Println("Receiving message")
if s.From == "" || len(s.To) == 0 {
return errors.New("missing from or to address")
}
// Read email data
var buf bytes.Buffer
if _, err := io.Copy(&buf, r); err != nil {
return err
}
data := buf.Bytes()
// Basic spam check
if parser.IsBacklistedDomain(string(s.From)) {
log.Printf("Detected spam domain from %s", s.From)
return errors.New("message rejected")
}
if parser.IsSpam(string(data)) {
log.Printf("Detected spam from %s", s.From)
return errors.New("message rejected")
}
// Parse the email
mr, err := mail.CreateReader(bytes.NewReader(data))
if err != nil {
return err
}
header := mr.Header
subject, _ := header.Subject()
// log.Printf("Subject: %v", subject)
var body string
for {
p, err := mr.NextPart()
if err == io.EOF {
break
} else if err != nil {
return err
}
switch h := p.Header.(type) {
case *mail.InlineHeader:
// This is the message's text (can be plain-text or HTML)
b, _ := io.ReadAll(p.Body)
body += string(b)
case *mail.AttachmentHeader:
// This is an attachment
filename, _ := h.Filename()
log.Printf("Got attachment: %v", filename)
}
}
// Store the email
if err := SaveEmail(s.From, strings.Join(s.To, ", "), subject, body); err != nil {
return err
}
log.Printf("Email processed successfully: %s", s.From)
return nil
}
func (s *Session) Reset() {
s.From = ""
s.To = nil
}
func (s *Session) Logout() error {
return nil
}