Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
0bd3890
feat(model): create domain.go
jurajhilje Feb 25, 2026
107ce04
feat(repository): create domain.go
jurajhilje Feb 25, 2026
7a6df1d
feat(service): create domain.go
jurajhilje Feb 25, 2026
a8f8640
feat(service): update domain.go
jurajhilje Feb 25, 2026
dd805b7
feat(api): update config.go
jurajhilje Feb 25, 2026
e84c9c6
feat(service): update domain.go
jurajhilje Feb 25, 2026
5755022
feat(api): create domain.go
jurajhilje Feb 25, 2026
2e71da9
feat(repository): update domain.go
jurajhilje Feb 26, 2026
5d716c2
feat(api): update domain.go
jurajhilje Feb 26, 2026
816dcaf
feat(api): update domain.go
jurajhilje Feb 26, 2026
bd1cac7
feat(utils): create dns.go
jurajhilje Feb 26, 2026
a5525c3
feat(service): update domain.go
jurajhilje Feb 27, 2026
d5ed995
feat(service): update domain.go
jurajhilje Feb 27, 2026
8681cc4
feat(api): update domain.go
jurajhilje Feb 27, 2026
4723dbc
feat(service): update domain.go
jurajhilje Feb 27, 2026
88713da
feat(api): update routes.go
jurajhilje Feb 27, 2026
4d8b8f3
feat(repository): update alias.go
jurajhilje Feb 27, 2026
626eacf
docs: update docs.go
jurajhilje Feb 27, 2026
59ee9c0
Merge branch 'main' into feature/custom-domains
jurajhilje Mar 2, 2026
5e4d27a
Merge branch 'main' into feature/custom-domains
jurajhilje Mar 5, 2026
6c7487d
Merge branch 'main' into feature/custom-domains
jurajhilje Mar 5, 2026
381aabe
feat(service): update domain.go
jurajhilje Mar 8, 2026
a9aaaab
feat(app): create Domains.vue
jurajhilje Mar 9, 2026
007b827
feat(app): create api/domain.ts
jurajhilje Mar 9, 2026
b867ac1
feat(app): create DomainCreate.vue
jurajhilje Mar 9, 2026
bc4d2e9
feat(app): update DomainCreate.vue
jurajhilje Mar 9, 2026
67a2f92
feat(app): update DomainCreate.vue
jurajhilje Mar 9, 2026
e7c116e
feat(app): update Domains.vue
jurajhilje Mar 10, 2026
659e8a6
feat(app): create DomainRow.vue
jurajhilje Mar 10, 2026
ebb3112
feat(app): update DomainRow.vue
jurajhilje Mar 10, 2026
cacd631
feat(api): update domain.go
jurajhilje Mar 10, 2026
cccec48
feat(api): update req.go
jurajhilje Mar 10, 2026
b90dcc5
build(api): update compose.yml
jurajhilje Mar 10, 2026
3c333c4
feat(app): create DomainDelete.vue
jurajhilje Mar 10, 2026
742e6d9
feat(app): create DomainEdit.vue
jurajhilje Mar 10, 2026
14e949b
feat(app): update DomainEdit.vue
jurajhilje Mar 10, 2026
fed564b
feat(app): update DomainRow.vue
jurajhilje Mar 10, 2026
f26923d
feat(app): create DomainVerify.vue
jurajhilje Mar 11, 2026
ce1458f
feat(app): update DomainVerify.vue
jurajhilje Mar 11, 2026
8120651
feat(app): update DomainRow.vue
jurajhilje Mar 11, 2026
5b6a387
feat(service): update domain.go
jurajhilje Mar 11, 2026
70e64b6
build: update compose.yml
jurajhilje Mar 11, 2026
65d1421
feat(service): update domain.go
jurajhilje Mar 11, 2026
73f5197
feat(api): update access_key.go
jurajhilje Mar 11, 2026
8c8769e
feat(app): update Aliases.vue
jurajhilje Mar 11, 2026
7fa4053
feat(app): update AliasCreate.vue
jurajhilje Mar 11, 2026
7d0e96c
feat(api): update alias.go
jurajhilje Mar 11, 2026
111c682
feat(service): update domain.go
jurajhilje Mar 11, 2026
5bcad8d
feat(app): update AliasCreate.vue
jurajhilje Mar 11, 2026
ba55199
feat(app): update api/domain.ts
jurajhilje Mar 11, 2026
97aab4e
feat(api): update alias.go
jurajhilje Mar 23, 2026
c6e6a4a
feat(api): update config.go
jurajhilje Mar 24, 2026
1a58489
feat(middleware): update auth.go
jurajhilje Mar 24, 2026
a2a9702
refactor(middleware): update auth.go
jurajhilje Mar 25, 2026
0fc7d65
Merge branch 'task/ip-filter' into feature/custom-domains
jurajhilje Mar 25, 2026
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
101 changes: 52 additions & 49 deletions api/.env.sample
Original file line number Diff line number Diff line change
@@ -1,54 +1,57 @@
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=""
API_DNS_RESOLVER=
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_DKIM_SELECTOR=
SMTP_CLIENT_REPORT=

OTP_EXPIRATION=15m
SUBSCRIPTION_TYPE=""
SUBSCRIPTION_TYPE=
MAX_CREDENTIALS=10
MAX_RECIPIENTS=10
MAX_DAILY_ALIASES=100
Expand All @@ -59,10 +62,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=
2 changes: 2 additions & 0 deletions api/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ services:
- api:/var/log
networks:
net:
dns:
- ${API_DNS_RESOLVER}

app:
build: ../app
Expand Down
42 changes: 24 additions & 18 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 @@ -49,14 +50,15 @@ type RedisConfig struct {
}

type SMTPClientConfig struct {
Host string
Port string
User string
Password string
Sender string
SenderName string
Report string
TokenSecret string
Host string
Port string
User string
Password string
Sender string
SenderName string
DkimSelector string
Report string
TokenSecret string
}

type ServiceConfig struct {
Expand Down Expand Up @@ -147,18 +149,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 Expand Up @@ -188,14 +193,15 @@ func New() (Config, error) {
TLSInsecureSkipVerify: os.Getenv("REDIS_TLS_INSECURE_SKIP_VERIFY") == "true",
},
SMTPClient: SMTPClientConfig{
Host: os.Getenv("SMTP_CLIENT_HOST"),
Port: os.Getenv("SMTP_CLIENT_PORT"),
User: os.Getenv("SMTP_CLIENT_USER"),
Password: os.Getenv("SMTP_CLIENT_PASSWORD"),
Sender: os.Getenv("SMTP_CLIENT_SENDER"),
SenderName: os.Getenv("SMTP_CLIENT_SENDER_NAME"),
Report: os.Getenv("SMTP_CLIENT_REPORT"),
TokenSecret: os.Getenv("TOKEN_SECRET"),
Host: os.Getenv("SMTP_CLIENT_HOST"),
Port: os.Getenv("SMTP_CLIENT_PORT"),
User: os.Getenv("SMTP_CLIENT_USER"),
Password: os.Getenv("SMTP_CLIENT_PASSWORD"),
Sender: os.Getenv("SMTP_CLIENT_SENDER"),
SenderName: os.Getenv("SMTP_CLIENT_SENDER_NAME"),
DkimSelector: os.Getenv("SMTP_CLIENT_DKIM_SELECTOR"),
Report: os.Getenv("SMTP_CLIENT_REPORT"),
TokenSecret: os.Getenv("TOKEN_SECRET"),
},

Service: ServiceConfig{
Expand Down
Loading
Loading