-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
140 lines (117 loc) · 3.85 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package main
import (
"embed"
"flag"
"io"
"log"
"net/http"
"os"
"path"
"time"
"github.com/emersion/go-smtp"
"github.com/gin-gonic/gin"
"github.com/restsend/carrot"
)
const key_WRITE_TIMEOUT = "WRITE_TIMEOUT"
const key_READ_TIMEOUT = "READ_TIMEOUT"
const key_DOMAIN = "DOMAIN"
const key_MAX_MESSAGE_BYTES = "MAX_MESSAGE_BYTES"
const key_MAX_RECIPIENTS = "MAX_RECIPIENTS"
const key_AUTH_STRICT = "AUTH_STRICT"
const key_MAIL_DIR = "MAIL_DIR"
const key_MAIL_UUID_SIZE = "MAIL_UUID_SIZE"
const fileMode os.FileMode = 0666
func checkValue(key, defaultVal string) string {
v := carrot.GetEnv(key)
if v == "" {
return defaultVal
}
return v
}
//go:embed ui/dist/index.html ui/dist/assets/*
var assets embed.FS
//go:embed ui/dist/index.html
var indexHTML string
func main() {
log.Default().SetFlags(logFlags)
var smtpServerAddr string
var httpServerAddr string
var logFile string
var dbName string
defaultSMTPAddr := checkValue("SMTP_ADDR", "0.0.0.0") + ":" + checkValue("SMTP_PORT", "9025")
defaultHTTPAddr := checkValue("HTTP_ADDR", "0.0.0.0") + ":" + checkValue("HTTP_PORT", "8000")
defaultDb := checkValue("DB_NAME", "preview.db")
flag.StringVar(&smtpServerAddr, "smtp", defaultSMTPAddr, "SMTP listen addr, default: "+defaultSMTPAddr)
flag.StringVar(&httpServerAddr, "http", defaultHTTPAddr, "HTTP listen addr, default: "+defaultHTTPAddr)
flag.StringVar(&logFile, "log", "", "log file")
flag.StringVar(&dbName, "db", defaultDb, "DB file, default: "+defaultDb)
flag.Parse()
var lw io.Writer = os.Stdout
var err error
if logFile != "" {
lw, err = os.OpenFile(logFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, fileMode)
if err != nil {
log.Printf("open %s fail, %v\n", logFile, err)
}
}
db, err := carrot.InitDatabase(lw, "", dbName)
if err != nil {
panic(err)
}
err = carrot.InitMigrate(db)
if err != nil {
log.Panic("init carrot migrate fail", err)
}
carrot.CheckValue(db, key_MAIL_DIR, "./mails/")
carrot.CheckValue(db, key_DOMAIN, "localhost")
carrot.CheckValue(db, key_AUTH_STRICT, "false")
carrot.CheckValue(db, key_MAIL_UUID_SIZE, "10")
be := &Backend{
db: db,
MailDir: carrot.GetValue(db, key_MAIL_DIR),
AuthStrict: carrot.GetBoolValue(db, key_AUTH_STRICT),
FilePerm: fileMode,
Logout: lw,
}
err = be.Prepare()
if err != nil {
log.Panic("Backend prepare fail", err)
}
s := smtp.NewServer(be)
s.Addr = smtpServerAddr
s.Domain = carrot.GetValue(db, key_DOMAIN)
s.WriteTimeout = time.Duration(carrot.GetIntValue(db, key_WRITE_TIMEOUT, 10)) * time.Second
s.ReadTimeout = time.Duration(carrot.GetIntValue(db, key_READ_TIMEOUT, 10)) * time.Second
s.MaxMessageBytes = carrot.GetIntValue(db, key_MAX_MESSAGE_BYTES, 1024*1024*10)
s.MaxRecipients = carrot.GetIntValue(db, key_MAX_RECIPIENTS, 50)
s.AllowInsecureAuth = true
s.AuthDisabled = false
log.Println("Starting SMTP server at", s.Addr)
log.Println("Domain:", s.Domain)
log.Println("MailDir:", be.MailDir)
log.Println("AuthStrict:", be.AuthStrict, "AuthDisabled:", s.AuthDisabled, "AllowInsecureAuth:", s.AllowInsecureAuth)
log.Println("WriteTimeout:", s.WriteTimeout, "ReadTimeout:", s.ReadTimeout)
log.Println("MaxMessageBytes:", s.MaxMessageBytes, "MaxRecipients:", s.MaxRecipients)
go func() {
if err := s.ListenAndServe(); err != nil {
log.Fatal(err)
}
}()
//gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {}
gin.SetMode(gin.ReleaseMode)
r := gin.Default()
if err := carrot.InitCarrot(db, r); err != nil {
panic(err)
}
// Embed static file
r.GET("/assets/*filepath", func(ctx *gin.Context) {
p := path.Join("ui/dist/", ctx.Request.RequestURI)
ctx.FileFromFS(p, http.FS(assets))
})
r.GET("/", func(ctx *gin.Context) {
ctx.Data(http.StatusOK, "text/html", []byte(indexHTML))
})
RegisterHandlers(r.Group("/api/"), be)
log.Println("Starting HTTP Server at", httpServerAddr)
r.Run(httpServerAddr)
}