Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 50 additions & 49 deletions api/.env.sample
Original file line number Diff line number Diff line change
@@ -1,54 +1,55 @@
FQDN="localhost"
API_NAME="Service Name"
API_PORT="3000"
API_ALLOW_ORIGIN="http://localhost:3001"
TOKEN_SECRET="secret"
FQDN=localhost
API_NAME=Service Name
API_PORT=3000
API_ALLOW_ORIGIN=http://localhost:3001
API_TRUSTED_PROXIES=127.0.0.1,10.0.0.0/8,172.16.0.0/12
API_ALLOW_IPS=127.0.0.1
TOKEN_SECRET=secret
TOKEN_EXPIRATION=168h
API_TOKEN_EXPIRATION=8760h
PSK=""
PSK_ALLOW_ORIGIN="http://localhost:3001"
DOMAINS="example1.net,example2.com"
LOG_FILE="/var/log/api.log"
BASIC_AUTH_USER=""
BASIC_AUTH_PASSWORD=""
NET_SUBNET=""
NET_GATEWAY=""
SIGNUP_WEBHOOK_URL=""
SIGNUP_WEBHOOK_PSK=""
PSK=
DOMAINS=example1.net,example2.com
LOG_FILE=/var/log/api.log
BASIC_AUTH_USER=
BASIC_AUTH_PASSWORD=
NET_SUBNET=
NET_GATEWAY=
SIGNUP_WEBHOOK_URL=
SIGNUP_WEBHOOK_PSK=

APP_PORT="3001"
APP_PORT=3001

DB_HOSTS="db"
DB_PORT="3306"
DB_NAME="email"
DB_USER="email"
DB_PASSWORD="email"
DB_ROOT_USER="root"
DB_ROOT_PASSWORD="root"
DB_HOSTS=db
DB_PORT=3306
DB_NAME=email
DB_USER=email
DB_PASSWORD=email
DB_ROOT_USER=root
DB_ROOT_PASSWORD=root

REDIS_ADDR="redis:6379"
REDIS_ADDRS=""
REDIS_MASTER_NAME=""
REDIS_USERNAME=""
REDIS_PASSWORD=""
REDIS_FAILOVER_USERNAME=""
REDIS_FAILOVER_PASSWORD=""
REDIS_TLS_ENABLED="false"
REDIS_CERT_FILE=""
REDIS_KEY_FILE=""
REDIS_CA_CERT_FILE=""
REDIS_TLS_INSECURE_SKIP_VERIFY="false"
REDIS_ADDR=redis:6379
REDIS_ADDRS=
REDIS_MASTER_NAME=
REDIS_USERNAME=
REDIS_PASSWORD=
REDIS_FAILOVER_USERNAME=
REDIS_FAILOVER_PASSWORD=
REDIS_TLS_ENABLED=false
REDIS_CERT_FILE=
REDIS_KEY_FILE=
REDIS_CA_CERT_FILE=
REDIS_TLS_INSECURE_SKIP_VERIFY=false

SMTP_CLIENT_HOST="smtp.example.net"
SMTP_CLIENT_PORT="2525"
SMTP_CLIENT_USER=""
SMTP_CLIENT_PASSWORD=""
SMTP_CLIENT_SENDER="from@example.net"
SMTP_CLIENT_SENDER_NAME="From Name"
SMTP_CLIENT_REPORT=""
SMTP_CLIENT_HOST=smtp.example.net
SMTP_CLIENT_PORT=2525
SMTP_CLIENT_USER=
SMTP_CLIENT_PASSWORD=
SMTP_CLIENT_SENDER=from@example.net
SMTP_CLIENT_SENDER_NAME=From Name
SMTP_CLIENT_REPORT=

OTP_EXPIRATION=15m
SUBSCRIPTION_TYPE=""
SUBSCRIPTION_TYPE=
MAX_CREDENTIALS=10
MAX_RECIPIENTS=10
MAX_DAILY_ALIASES=100
Expand All @@ -59,10 +60,10 @@ ACCOUNT_GRACE_PERIOD_DAYS=194
ID_LIMITER_MAX=5
ID_LIMITER_EXPIRATION=60m

BACKUP_FILENAME="backup"
BACKUP_CRON_EXPRESSION="0 0 29 2 1"
BACKUP_FILENAME=backup
BACKUP_CRON_EXPRESSION=0 0 29 2 1
BACKUP_RETENTION_DAYS=7
GPG_PASSPHRASE=""
AWS_S3_BUCKET_NAME=""
AWS_ACCESS_KEY_ID=""
AWS_SECRET_ACCESS_KEY=""
GPG_PASSPHRASE=
AWS_S3_BUCKET_NAME=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
8 changes: 6 additions & 2 deletions api/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@ type APIConfig struct {
Name string
Port string
ApiAllowOrigin string
ApiTrustedProxies []string
ApiAllowIPs []string
TokenSecret string
TokenExpiration time.Duration
ApiTokenExpiration time.Duration
PSK string
PSKAllowOrigin string
Domains string
LogFile string
BasicAuthUser string
Expand Down Expand Up @@ -147,18 +148,21 @@ func New() (Config, error) {

dbHosts := strings.Split(os.Getenv("DB_HOSTS"), ",")
redisAddrs := strings.Split(os.Getenv("REDIS_ADDRESSES"), ",")
apiTrustedProxies := strings.Split(os.Getenv("API_TRUSTED_PROXIES"), ",")
apiAllowIPs := strings.Split(os.Getenv("API_ALLOW_IPS"), ",")

return Config{
API: APIConfig{
FQDN: os.Getenv("FQDN"),
Name: os.Getenv("API_NAME"),
Port: os.Getenv("API_PORT"),
ApiAllowOrigin: os.Getenv("API_ALLOW_ORIGIN"),
ApiTrustedProxies: apiTrustedProxies,
ApiAllowIPs: apiAllowIPs,
TokenSecret: os.Getenv("TOKEN_SECRET"),
TokenExpiration: tokenExp,
ApiTokenExpiration: apiTokenExp,
PSK: os.Getenv("PSK"),
PSKAllowOrigin: os.Getenv("PSK_ALLOW_ORIGIN"),
Domains: os.Getenv("DOMAINS"),
LogFile: os.Getenv("LOG_FILE"),
BasicAuthUser: os.Getenv("BASIC_AUTH_USER"),
Expand Down
21 changes: 17 additions & 4 deletions api/internal/middleware/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package auth
import (
"context"
"fmt"
"slices"
"strings"
"time"

Expand Down Expand Up @@ -54,14 +55,26 @@ func New(cfg config.APIConfig, cache Cache, service Service) fiber.Handler {
}
}

func NewPSK(cfg config.APIConfig) fiber.Handler {
func NewIPFilter(allowedIPs []string) fiber.Handler {

return func(c *fiber.Ctx) error {
if GetAuthToken(c) != cfg.PSK {
return c.SendStatus(fiber.StatusUnauthorized)
clientIP := c.IP()
if slices.Contains(allowedIPs, clientIP) {
return c.Next()
}

return c.Next()
return c.SendStatus(fiber.StatusForbidden)
}
}

func NewPSK(psk string) fiber.Handler {

return func(c *fiber.Ctx) error {
if GetAuthToken(c) == psk {
return c.Next()
}

return c.SendStatus(fiber.StatusUnauthorized)
}
}

Expand Down
6 changes: 4 additions & 2 deletions api/internal/transport/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import (

func (h *Handler) SetupRoutes(cfg config.APIConfig) {
email := h.Server.Group("/v1/email")
email.Use(auth.NewPSK(cfg))
email.Use(auth.NewIPFilter(cfg.ApiAllowIPs))
email.Use(auth.NewPSK(cfg.PSK))
email.Post("", h.HandleEmail)

h.Server.Use(auth.NewAPICORS(cfg))
Expand All @@ -34,7 +35,8 @@ func (h *Handler) SetupRoutes(cfg config.APIConfig) {
h.Server.Post("/v1/login/finish", limiter.New(), h.FinishLogin)

sub := h.Server.Group("/v1/subscription")
sub.Use(auth.NewPSK(cfg))
sub.Use(auth.NewIPFilter(cfg.ApiAllowIPs))
sub.Use(auth.NewPSK(cfg.PSK))
sub.Post("/add", h.AddSubscription)

api := h.Server.Group("/v1/api")
Expand Down
6 changes: 5 additions & 1 deletion api/internal/transport/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ type Cache interface {
func Start(cfg config.APIConfig, service Service, cache Cache) error {
log.Printf("API server starting on :%s", cfg.Port)

app := fiber.New()
app := fiber.New(fiber.Config{
EnableTrustedProxyCheck: true,
TrustedProxies: cfg.ApiTrustedProxies,
ProxyHeader: fiber.HeaderXForwardedFor,
})

h := &Handler{
Cfg: cfg,
Expand Down
2 changes: 1 addition & 1 deletion mailserver/.env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ ENABLE_RSPAMD=1
ENABLE_FAIL2BAN=1
ENABLE_CLAMAV=0
LOG_LEVEL=info
PSK=""
PSK=
Loading