mirror of
https://github.com/GRFreire/nthmail.git
synced 2026-01-09 21:09:39 +00:00
initial commit
This commit is contained in:
commit
369115d781
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
main
|
||||
*.db
|
||||
129
cmd/mail_server/main.go
Normal file
129
cmd/mail_server/main.go
Normal file
@ -0,0 +1,129 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"io"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/emersion/go-smtp"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
type Backend struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (backend *Backend) NewSession(c *smtp.Conn) (smtp.Session, error) {
|
||||
tx, err := backend.db.Begin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Session{
|
||||
tx: tx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
tx *sql.Tx
|
||||
from, rcpt string
|
||||
rcpt_addr_id int64
|
||||
}
|
||||
|
||||
func (session *Session) AuthPlain(username, password string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (session *Session) Mail(from string, opts *smtp.MailOptions) error {
|
||||
session.from = from
|
||||
return nil
|
||||
}
|
||||
|
||||
func (session *Session) Rcpt(to string, opts *smtp.RcptOptions) error {
|
||||
session.rcpt = to
|
||||
|
||||
stmt, err := session.tx.Prepare("INSERT OR IGNORE INTO inboxes (addr) VALUES (?) RETURNING id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
res, err := stmt.Exec(to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// sometimes does not work and returns 0
|
||||
// see https://github.com/mattn/go-sqlite3/issues/1140
|
||||
id, err := res.LastInsertId()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println("Last id: ", id)
|
||||
|
||||
session.rcpt_addr_id = id
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (session *Session) Data(reader io.Reader) error {
|
||||
if bytes, err := io.ReadAll(reader); err != nil {
|
||||
return err
|
||||
} else {
|
||||
|
||||
stmt, err := session.tx.Prepare("INSERT INTO mails (inbox_id, from_addr, data) VALUES (?, ?, ?)")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, err = stmt.Exec(session.rcpt_addr_id, session.from, bytes)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = session.tx.Commit()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Println("New mail from <", session.from, "> to <", session.rcpt, ">")
|
||||
log.Println("Data:", string(bytes))
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (session *Session) Reset() {}
|
||||
|
||||
func (session *Session) Logout() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
db, err := sql.Open("sqlite3", "./db.db")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
backend := &Backend{
|
||||
db: db,
|
||||
}
|
||||
|
||||
server := smtp.NewServer(backend)
|
||||
|
||||
server.Addr = "localhost:1025"
|
||||
server.Domain = "localhost"
|
||||
server.WriteTimeout = 60 * time.Second
|
||||
server.ReadTimeout = 60 * time.Second
|
||||
server.MaxMessageBytes = 1024 * 1024
|
||||
server.MaxRecipients = 50
|
||||
server.AllowInsecureAuth = true
|
||||
|
||||
log.Println("Starting server at", server.Addr)
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
9
go.mod
Normal file
9
go.mod
Normal file
@ -0,0 +1,9 @@
|
||||
module github.com/GRFreire/nthmail
|
||||
|
||||
go 1.21.6
|
||||
|
||||
require (
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
|
||||
github.com/emersion/go-smtp v0.20.2 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.22 // indirect
|
||||
)
|
||||
6
go.sum
Normal file
6
go.sum
Normal file
@ -0,0 +1,6 @@
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
|
||||
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
|
||||
github.com/emersion/go-smtp v0.20.2 h1:peX42Qnh5Q0q3vrAnRy43R/JwTnnv75AebxbkTL7Ia4=
|
||||
github.com/emersion/go-smtp v0.20.2/go.mod h1:qm27SGYgoIPRot6ubfQ/GpiPy/g3PaZAVRxiO/sDUgQ=
|
||||
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
|
||||
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
|
||||
12
migration.sql
Normal file
12
migration.sql
Normal file
@ -0,0 +1,12 @@
|
||||
CREATE TABLE inboxes (
|
||||
id integer not null primary key,
|
||||
addr text unique
|
||||
);
|
||||
|
||||
CREATE TABLE mails (
|
||||
id integer not null primary key,
|
||||
inbox_id id,
|
||||
from_addr text,
|
||||
data blob,
|
||||
FOREIGN KEY(inbox_id) REFERENCES inboxes(id)
|
||||
);
|
||||
Loading…
Reference in New Issue
Block a user