imc-vibe/backend/internal/config/config.go

145 lines
5.2 KiB
Go

// Package config handles loading configuration from environment variables.
// Configuration is loaded from .env files (for development) and environment variables (for production).
package config
import (
"fmt" // formatted error messages
"os" // Standard library for reading environment variables
"strings"
"github.com/joho/godotenv" // Third-party library for loading .env files
)
// Config holds all configuration options for the application.
// Each field corresponds to either an environment variable or a default value.
type Config struct {
// Database connection settings
DBHost string // Database server hostname or IP address
DBPort string // Database server port (usually 3306 for MySQL/MariaDB)
DBUser string // Database username
DBPassword string // Database password (keep this secret!)
DBName string // Database name (e.g., "mailserver")
// Network settings for the web server
Bind string // IP address to bind to (0.0.0.0 = all interfaces, 127.0.0.1 = localhost only)
Port string // TCP port to listen on
// Security settings
JWTSecret string // Secret key for signing JWT tokens (keep this secret!)
TrustedProxies []string // IPs of trusted reverse proxies (for X-Forwarded-For)
// Mail server paths and settings
MailDataDir string // Directory where mail is stored (e.g., /var/vmail)
PostqueuePath string // Path to postqueue command (for mail queue operations)
PostsuperPath string // Path to postsuper command (for mail queue operations)
DovecotQuotaCmd string // Path to doveadm command (for quota operations)
// System integration
JournalctlPath string // Path to journalctl command (for reading system logs)
// Rspamd settings (spam filter)
RspamdAPI string // URL of the Rspamd web interface
// SMTP settings (for sending password reset emails)
SMTPHost string // SMTP server hostname
SMTPPort string // SMTP server port (587 for submission, 465 for SMTPS)
SMTPUser string // SMTP username
SMTPPassword string // SMTP password
SMTPFrom string // From address in outgoing emails
// Application settings
BaseURL string // Base URL of this application (used for generating links in emails)
}
// Load reads configuration from environment variables and .env files.
// It returns a Config struct with all settings.
//
// Environment variables take precedence over .env file values.
// .env file values take precedence over code defaults.
//
// The function looks for a .env file in the current directory.
func Load() *Config {
// Load .env file if it exists.
// This is for local development convenience.
// In production, use environment variables directly.
godotenv.Load(".env")
// Return a new Config struct with all values.
// getEnv(key, default) returns the environment variable value,
// or the default if the environment variable is not set.
return &Config{
// Database settings
// Default: localhost:3306 with mailadmin user
DBHost: getEnv("DB_HOST", "localhost"),
DBPort: getEnv("DB_PORT", "3306"),
DBUser: getEnv("DB_USER", "mailadmin"),
DBPassword: getEnv("DB_PASSWORD", ""), // No default - must be set!
DBName: getEnv("DB_NAME", "mailserver"),
// Server settings
// Default: bind to all interfaces on port 8080
Bind: getEnv("BIND", "0.0.0.0"),
Port: getEnv("PORT", "8080"),
// Security
// Default JWT secret is insecure - must be changed in production!
JWTSecret: getEnv("JWT_SECRET", "change-this-secret-in-production"),
// Mail server paths
MailDataDir: getEnv("MAIL_DATA_DIR", "/var/vmail"),
PostqueuePath: getEnv("POSTQUEUE_PATH", "/usr/sbin/postqueue"),
PostsuperPath: getEnv("POSTSUPER_PATH", "/usr/sbin/postsuper"),
DovecotQuotaCmd: getEnv("DOVECOT_QUOTA_CMD", "/usr/bin/doveadm"),
JournalctlPath: getEnv("JOURNALCTL_PATH", "/usr/bin/journalctl"),
// External services
RspamdAPI: getEnv("RSPAMD_API", "http://127.0.0.1:11334"),
// SMTP settings (for password reset emails)
SMTPHost: getEnv("SMTP_HOST", "localhost"),
SMTPPort: getEnv("SMTP_PORT", "587"),
SMTPUser: getEnv("SMTP_USER", ""),
SMTPPassword: getEnv("SMTP_PASSWORD", ""),
SMTPFrom: getEnv("SMTP_FROM", "noreply@localhost"),
// Application URL (for generating links in emails)
BaseURL: getEnv("BASE_URL", "http://localhost:8080"),
// Trusted proxies (comma-separated IPs)
TrustedProxies: parseTrustedProxies(getEnv("TRUSTED_PROXIES", "")),
}
}
func parseTrustedProxies(s string) []string {
if s == "" {
return nil
}
parts := strings.Split(s, ",")
result := make([]string, 0, len(parts))
for _, p := range parts {
p = strings.TrimSpace(p)
if p != "" {
result = append(result, p)
}
}
return result
}
func (c *Config) Validate() error {
if len(c.JWTSecret) < 32 {
return fmt.Errorf("JWT_SECRET must be at least 32 characters long")
}
return nil
}
// getEnv reads an environment variable or returns a default value.
// key: the name of the environment variable.
// defaultValue: the value to return if the environment variable is not set.
func getEnv(key, defaultValue string) string {
// Check if the environment variable is set and not empty.
if value := os.Getenv(key); value != "" {
return value
}
// Return the default value.
return defaultValue
}