diff --git a/app/attachment.go b/app/attachment.go index 97948e01..70ac451d 100644 --- a/app/attachment.go +++ b/app/attachment.go @@ -3,6 +3,7 @@ package app import ( "fmt" "net/http" + "path" "github.com/google/uuid" ) @@ -57,6 +58,10 @@ func (a *Attachment) EXT() string { } } +func (a *Attachment) Path(directory string) string { + return path.Join(directory, a.UUID+a.EXT()) +} + type EndpointAttachment struct { Name string Type AttachmentType diff --git a/app/config.go b/app/config.go index db4603e2..b7130a0c 100644 --- a/app/config.go +++ b/app/config.go @@ -8,12 +8,12 @@ import ( ) type Config struct { - AttachmentsPath string `json:"attachments" mapstructure:"attachments"` - DBPath string `json:"db" mapstructure:"db"` - SMTP ConfigSMTP `json:"smtp" mapstructure:"smtp"` - HTTP ConfigHTTP `json:"http" mapstructure:"http"` - Bridges []Bridge `json:"bridges" mapstructure:"bridges"` - Endpoints []ConfigEndpoint `json:"endpoints" mapstructure:"endpoints"` + AttDir string `json:"attachments" mapstructure:"attachments"` + DBFile string `json:"db" mapstructure:"db"` + SMTP ConfigSMTP `json:"smtp" mapstructure:"smtp"` + HTTP ConfigHTTP `json:"http" mapstructure:"http"` + Bridges []Bridge `json:"bridges" mapstructure:"bridges"` + Endpoints []ConfigEndpoint `json:"endpoints" mapstructure:"endpoints"` } type ConfigHTTP struct { diff --git a/app/port.go b/app/port.go index acb37dca..dd7441f9 100644 --- a/app/port.go +++ b/app/port.go @@ -28,13 +28,15 @@ type MessageServicePort interface { type MessageRepositoryPort interface { CreateMessage(msg *Message) error GetMessage(uuid string) (*Message, error) + GetMessages(limit, offset int) ([]Message, error) UpdateMessage(msg *Message, updateFN func(msg *Message) (*Message, error)) error } type AttachmentRepositoryPort interface { CreateAttachment(att *Attachment) error GetAttachment(uuid string) (*Attachment, error) - LoadAttachment(msg *Message) error + GetAttachmentData(att *Attachment) ([]byte, error) + GetAttachments(msg *Message) ([]Attachment, error) } // EndpointPort handles sending messages to an endpoint. diff --git a/cmd/server.go b/cmd/server.go index 26f4c123..6b4d1986 100644 --- a/cmd/server.go +++ b/cmd/server.go @@ -46,7 +46,7 @@ var serverCmd = &cobra.Command{ // Init repositories endpointREPO := endpoint.NewRepository(config.Endpoints) - databaseREPO := database.NewDB(config.DBPath, config.AttachmentsPath) + databaseREPO := database.NewDB(config.DBFile, config.AttDir) // Init services authSVC := service.NewMockAuth() @@ -58,7 +58,7 @@ var serverCmd = &cobra.Command{ // Init router if config.HTTP.Enable { - httpServer := router.New(config.AttachmentsPath) + httpServer := router.New(config.AttDir, databaseREPO, databaseREPO) go httpServer.Start(config.HTTP.Address) } diff --git a/left/router/handlers.go b/left/router/handlers.go new file mode 100644 index 00000000..ba57afe9 --- /dev/null +++ b/left/router/handlers.go @@ -0,0 +1,50 @@ +package router + +import ( + "embed" + "html/template" + "log" + "net/http" + + "github.com/ItsNotGoodName/smtpbridge/app" +) + +func (s *Router) GetAttachments(prefix string) http.HandlerFunc { + return func(rw http.ResponseWriter, r *http.Request) { + http.StripPrefix(prefix, http.FileServer(http.Dir(s.attDir))).ServeHTTP(rw, r) + } +} + +//go:embed template +var templateFS embed.FS + +func (s *Router) GetIndex() http.HandlerFunc { + type Data struct { + Messages []app.Message + } + + index, err := template.ParseFS(templateFS, "template/index.html") + if err != nil { + log.Fatal("router.Router.GetIndex", err) + } + + return func(rw http.ResponseWriter, r *http.Request) { + msg, err := s.messageREPO.GetMessages(10, 0) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + + for i := range msg { + msg[i].Attachments, err = s.attachmentREPO.GetAttachments(&msg[i]) + if err != nil { + http.Error(rw, err.Error(), http.StatusInternalServerError) + } + } + + data := Data{ + Messages: msg, + } + + index.Execute(rw, data) + } +} diff --git a/left/router/route.go b/left/router/route.go index 7ca1eed1..f774ac29 100644 --- a/left/router/route.go +++ b/left/router/route.go @@ -1,9 +1,6 @@ package router -import "net/http" - func (s *Router) route() { - s.r.Get("/attachments/*", func(w http.ResponseWriter, r *http.Request) { - http.StripPrefix("/attachments/", http.FileServer(http.Dir(s.AttachmentsPath))).ServeHTTP(w, r) - }) + s.r.Get("/attachments/*", s.GetAttachments("/attachments/")) + s.r.Get("/", s.GetIndex()) } diff --git a/left/router/router.go b/left/router/router.go index db077349..76cbf362 100644 --- a/left/router/router.go +++ b/left/router/router.go @@ -5,19 +5,24 @@ import ( "net/http" "time" + "github.com/ItsNotGoodName/smtpbridge/app" "github.com/go-chi/chi/middleware" "github.com/go-chi/chi/v5" ) type Router struct { - r *chi.Mux - AttachmentsPath string + r *chi.Mux + attDir string + messageREPO app.MessageRepositoryPort + attachmentREPO app.AttachmentRepositoryPort } -func New(AttachmentsPath string) *Router { +func New(attDir string, messageREPO app.MessageRepositoryPort, attachmentREPO app.AttachmentRepositoryPort) *Router { s := Router{ - r: chi.NewRouter(), - AttachmentsPath: AttachmentsPath, + r: chi.NewRouter(), + attDir: attDir, + messageREPO: messageREPO, + attachmentREPO: attachmentREPO, } // A good base middleware stack diff --git a/left/router/template/index.html b/left/router/template/index.html new file mode 100644 index 00000000..30480b77 --- /dev/null +++ b/left/router/template/index.html @@ -0,0 +1,27 @@ + + + + + + + Document + + +

Messages

+ {{range $msg := .Messages}} +
+

{{ $msg.Subject }}

+
Status: {{ $msg.Status }}
+
+ +
{{ $msg.Text }}
+
+
+ + {{ range $att := $msg.Attachments }} + {{ $att.UUID }} + {{ end }} +
+ {{ end }} + + diff --git a/right/database/database.go b/right/database/database.go index b8df789b..54f40708 100644 --- a/right/database/database.go +++ b/right/database/database.go @@ -3,7 +3,6 @@ package database import ( "log" "os" - "path" "github.com/ItsNotGoodName/smtpbridge/app" "github.com/asdine/storm" @@ -15,20 +14,20 @@ type DB struct { attPath string } -func NewDB(dbPath, attPath string) *DB { - db, err := storm.Open(dbPath) +func NewDB(dbFile, attDir string) *DB { + db, err := storm.Open(dbFile) if err != nil { log.Fatal("database.NewDB:", err) } - err = os.MkdirAll(attPath, 0755) + err = os.MkdirAll(attDir, 0755) if err != nil { log.Fatal("database.NewDB:", err) } return &DB{ db: db, - attPath: attPath, + attPath: attDir, } } @@ -71,15 +70,23 @@ func (db *DB) UpdateMessage(msg *app.Message, updateFN func(msg *app.Message) (* return tx.Commit() } +func (db *DB) GetMessages(limit, offset int) ([]app.Message, error) { + var msgs []app.Message + err := db.db.All(&msgs, storm.Limit(limit), storm.Skip(offset), storm.Reverse()) + if err != nil { + return nil, err + } + + return msgs, nil +} + func (db *DB) CreateAttachment(att *app.Attachment) error { err := db.db.Save(att) if err != nil { return err } - file := path.Join(db.attPath, att.UUID+att.EXT()) - - return os.WriteFile(file, att.Data, 0644) + return os.WriteFile(att.Path(db.attPath), att.Data, 0644) } func (db *DB) GetAttachment(uuid string) (*app.Attachment, error) { @@ -89,24 +96,24 @@ func (db *DB) GetAttachment(uuid string) (*app.Attachment, error) { return nil, err } - data, err := os.ReadFile(path.Join(db.attPath, att.UUID+att.EXT())) + return &att, nil +} + +func (db *DB) GetAttachmentData(att *app.Attachment) ([]byte, error) { + data, err := os.ReadFile(att.Path(db.attPath)) if err != nil { return nil, err } - att.Data = data - - return &att, nil + return data, nil } -func (db *DB) LoadAttachment(msg *app.Message) error { +func (db *DB) GetAttachments(msg *app.Message) ([]app.Attachment, error) { var atts []app.Attachment err := db.db.Select(q.Eq("MessageUUID", msg.UUID)).Find(&atts) if err != nil { - return err + return nil, err } - msg.Attachments = atts - - return nil + return atts, nil }