Skip to content

Commit

Permalink
Merge branch 'release/v1.14.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
axllent committed Feb 24, 2024
2 parents e410fd4 + 7cb71ad commit 75a6cfb
Show file tree
Hide file tree
Showing 29 changed files with 2,248 additions and 1,353 deletions.
32 changes: 32 additions & 0 deletions .github/workflows/build-docker-edge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
on:
push:
branches: [ develop ]

name: Build docker edge images
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to DockerHub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}

- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/386,linux/amd64,linux/arm64
push: true
tags: |
axllent/mailpit:edge
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@

Notable changes to Mailpit will be documented in this file.

## [v1.14.0]

### Chore
- Update node dependencies
- Update Go dependencies
- Refactor storage library
- Security improvements (gosec)
- Switch to short uuid format for database IDs
- Better handling of automatic database compression (vacuuming) after deleting messages

### Docker
- Add edge Docker images for latest unreleased features

### Feature
- Optional POP3 server ([#249](https://github.com/axllent/mailpit/issues/249))


## [v1.13.3]

### API
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ COPY --from=builder /mailpit /mailpit

RUN apk add --no-cache tzdata

EXPOSE 1025/tcp 8025/tcp
EXPOSE 1025/tcp 1110/tcp 8025/tcp

ENTRYPOINT ["/mailpit"]
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ via either HTTPS or `localhost` only)
including an optional allowlist of accepted recipients
- Fast SMTP processing & storing - approximately 70-100 emails per second depending on CPU, network speed & email size,
easily handling tens of thousands of emails
- Optional [POP3 server](https://mailpit.axllent.org/docs/configuration/pop3/) to download captured message directly into your email client
- Configurable automatic email pruning (default keeps the most recent 500 emails)
- A simple [REST API](https://mailpit.axllent.org/docs/api-v1/) for integration testing
- Optional [webhook](https://mailpit.axllent.org/docs/integration/webhook/) for received messages
Expand Down
25 changes: 23 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ func init() {

rootCmd.Flags().StringVar(&config.SMTPRelayConfigFile, "smtp-relay-config", config.SMTPRelayConfigFile, "SMTP configuration file to allow releasing messages")
rootCmd.Flags().BoolVar(&config.SMTPRelayAllIncoming, "smtp-relay-all", config.SMTPRelayAllIncoming, "Relay all incoming messages via external SMTP server (caution!)")

rootCmd.Flags().StringVar(&config.POP3Listen, "pop3", config.POP3Listen, "POP3 server bind interface and port")
rootCmd.Flags().StringVar(&config.POP3AuthFile, "pop3-auth-file", config.POP3AuthFile, "A password file for POP3 server authentication (enables POP3 server)")
rootCmd.Flags().StringVar(&config.POP3TLSCert, "pop3-tls-cert", config.POP3TLSCert, "Optional TLS certificate for POP3 server - requires pop3-tls-key")
rootCmd.Flags().StringVar(&config.POP3TLSKey, "pop3-tls-key", config.POP3TLSKey, "Optional TLS key for POP3 server - requires pop3-tls-cert")

rootCmd.Flags().StringVar(&config.WebhookURL, "webhook-url", config.WebhookURL, "Send a webhook request for new messages")
rootCmd.Flags().IntVar(&webhook.RateLimit, "webhook-limit", webhook.RateLimit, "Limit webhook requests per second")

Expand Down Expand Up @@ -154,13 +160,17 @@ func initConfigFromEnv() {

// UI
config.UIAuthFile = os.Getenv("MP_UI_AUTH_FILE")
auth.SetUIAuth(os.Getenv("MP_UI_AUTH"))
if err := auth.SetUIAuth(os.Getenv("MP_UI_AUTH")); err != nil {
logger.Log().Errorf(err.Error())
}
config.UITLSCert = os.Getenv("MP_UI_TLS_CERT")
config.UITLSKey = os.Getenv("MP_UI_TLS_KEY")

// SMTP
config.SMTPAuthFile = os.Getenv("MP_SMTP_AUTH_FILE")
auth.SetSMTPAuth(os.Getenv("MP_SMTP_AUTH"))
if err := auth.SetSMTPAuth(os.Getenv("MP_SMTP_AUTH")); err != nil {
logger.Log().Errorf(err.Error())
}
config.SMTPTLSCert = os.Getenv("MP_SMTP_TLS_CERT")
config.SMTPTLSKey = os.Getenv("MP_SMTP_TLS_KEY")
if getEnabledFromEnv("MP_SMTP_TLS_REQUIRED") {
Expand Down Expand Up @@ -191,6 +201,17 @@ func initConfigFromEnv() {
config.SMTPRelayAllIncoming = true
}

// POP3
if len(os.Getenv("MP_POP3_BIND_ADDR")) > 0 {
config.POP3Listen = os.Getenv("MP_POP3_BIND_ADDR")
}
config.POP3AuthFile = os.Getenv("MP_POP3_AUTH_FILE")
if err := auth.SetPOP3Auth(os.Getenv("MP_POP3_AUTH")); err != nil {
logger.Log().Errorf(err.Error())
}
config.POP3TLSCert = os.Getenv("MP_POP3_TLS_CERT")
config.POP3TLSKey = os.Getenv("MP_POP3_TLS_KEY")

// Webhook
if len(os.Getenv("MP_WEBHOOK_URL")) > 0 {
config.WebhookURL = os.Getenv("MP_WEBHOOK_URL")
Expand Down
69 changes: 68 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package config
import (
"errors"
"fmt"
"net"
"net/url"
"os"
"path"
Expand Down Expand Up @@ -112,6 +113,18 @@ var (
// Use with extreme caution!
SMTPRelayAllIncoming = false

// POP3Listen address - if set then Mailpit will start the POP3 server and listen on this address
POP3Listen = "[::]:1110"

// POP3AuthFile for POP3 authentication
POP3AuthFile string

// POP3TLSCert TLS certificate
POP3TLSCert string

// POP3TLSKey TLS certificate key
POP3TLSKey string

// EnableSpamAssassin must be either <host>:<port> or "postmark"
EnableSpamAssassin string

Expand Down Expand Up @@ -179,13 +192,17 @@ func VerifyConfig() error {
}

if UIAuthFile != "" {
UIAuthFile = filepath.Clean(UIAuthFile)

if !isFile(UIAuthFile) {
return fmt.Errorf("[ui] HTTP password file not found: %s", UIAuthFile)
}

b, err := os.ReadFile(UIAuthFile)
if err != nil {
return err
}

if err := auth.SetUIAuth(string(b)); err != nil {
return err
}
Expand All @@ -196,6 +213,9 @@ func VerifyConfig() error {
}

if UITLSCert != "" {
UITLSCert = filepath.Clean(UITLSCert)
UITLSKey = filepath.Clean(UITLSKey)

if !isFile(UITLSCert) {
return fmt.Errorf("[ui] TLS certificate not found: %s", UITLSCert)
}
Expand All @@ -210,6 +230,9 @@ func VerifyConfig() error {
}

if SMTPTLSCert != "" {
SMTPTLSCert = filepath.Clean(SMTPTLSCert)
SMTPTLSKey = filepath.Clean(SMTPTLSKey)

if !isFile(SMTPTLSCert) {
return fmt.Errorf("[smtp] TLS certificate not found: %s", SMTPTLSCert)
}
Expand All @@ -226,6 +249,8 @@ func VerifyConfig() error {
}

if SMTPAuthFile != "" {
SMTPAuthFile = filepath.Clean(SMTPAuthFile)

if !isFile(SMTPAuthFile) {
return fmt.Errorf("[smtp] password file not found: %s", SMTPAuthFile)
}
Expand All @@ -248,6 +273,46 @@ func VerifyConfig() error {
return errors.New("[smtp] authentication requires TLS encryption, run with `--smtp-auth-allow-insecure` to allow insecure authentication")
}

// POP3 server
if POP3TLSCert != "" {
POP3TLSCert = filepath.Clean(POP3TLSCert)
POP3TLSKey = filepath.Clean(POP3TLSKey)

if !isFile(POP3TLSCert) {
return fmt.Errorf("[pop3] TLS certificate not found: %s", POP3TLSCert)
}

if !isFile(POP3TLSKey) {
return fmt.Errorf("[pop3] TLS key not found: %s", POP3TLSKey)
}
}
if POP3TLSCert != "" && POP3TLSKey == "" || POP3TLSCert == "" && POP3TLSKey != "" {
return errors.New("[pop3] You must provide both a POP3 TLS certificate and a key")
}
if POP3Listen != "" {
_, err := net.ResolveTCPAddr("tcp", POP3Listen)
if err != nil {
return fmt.Errorf("[pop3] %s", err.Error())
}
}
if POP3AuthFile != "" {
POP3AuthFile = filepath.Clean(POP3AuthFile)

if !isFile(POP3AuthFile) {
return fmt.Errorf("[pop3] password file not found: %s", POP3AuthFile)
}

b, err := os.ReadFile(POP3AuthFile)
if err != nil {
return err
}

if err := auth.SetPOP3Auth(string(b)); err != nil {
return err
}
}

// Web root
validWebrootRe := regexp.MustCompile(`[^0-9a-zA-Z\/\-\_\.@]`)
if validWebrootRe.MatchString(Webroot) {
return fmt.Errorf("invalid characters in Webroot (%s). Valid chars include: [a-z A-Z 0-9 _ . - / @]", Webroot)
Expand Down Expand Up @@ -324,8 +389,10 @@ func parseRelayConfig(c string) error {
return nil
}

c = filepath.Clean(c)

if !isFile(c) {
return fmt.Errorf("[smtp] relay configuration not found: %s", SMTPRelayConfigFile)
return fmt.Errorf("[smtp] relay configuration not found: %s", c)
}

data, err := os.ReadFile(c)
Expand Down
21 changes: 9 additions & 12 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@ go 1.20

require (
github.com/GuiaBolso/darwin v0.0.0-20191218124601-fd6d2aa3d244
github.com/PuerkitoBio/goquery v1.8.1
github.com/PuerkitoBio/goquery v1.9.0
github.com/axllent/semver v0.0.1
github.com/disintegration/imaging v1.6.2
github.com/gomarkdown/markdown v0.0.0-20231222211730-1d6d20845b47
github.com/google/uuid v1.6.0
github.com/gorilla/mux v1.8.1
github.com/gorilla/websocket v1.5.1
github.com/jhillyerd/enmime v1.1.0
github.com/klauspost/compress v1.17.6
github.com/jhillyerd/enmime v1.2.0
github.com/klauspost/compress v1.17.7
github.com/leporo/sqlf v1.4.0
github.com/lithammer/shortuuid/v4 v4.0.0
github.com/mhale/smtpd v0.8.2
github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e
github.com/sirupsen/logrus v1.9.3
Expand All @@ -25,7 +25,7 @@ require (
golang.org/x/text v0.14.0
golang.org/x/time v0.5.0
gopkg.in/yaml.v3 v3.0.1
modernc.org/sqlite v1.28.0
modernc.org/sqlite v1.29.1
)

require (
Expand All @@ -36,10 +36,11 @@ require (
github.com/cznic/ql v1.2.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/css v1.0.1 // indirect
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
Expand All @@ -54,17 +55,13 @@ require (
github.com/vanng822/css v1.0.1 // indirect
golang.org/x/crypto v0.19.0 // indirect
golang.org/x/image v0.15.0 // indirect
golang.org/x/mod v0.15.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/tools v0.17.0 // indirect
golang.org/x/tools v0.18.0 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
lukechampine.com/uint128 v1.3.0 // indirect
modernc.org/cc/v3 v3.41.0 // indirect
modernc.org/ccgo/v3 v3.16.15 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
modernc.org/libc v1.41.0 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
modernc.org/opt v0.1.3 // indirect
modernc.org/strutil v1.2.0 // indirect
modernc.org/token v1.1.0 // indirect
)
Loading

0 comments on commit 75a6cfb

Please sign in to comment.