package config import ( "encoding/json" "fmt" "os" ) type ServerConfig struct { AppName string `json:"app_name"` ReadTimeoutSeconds int `json:"read_timeout_seconds"` WriteTimeoutSeconds int `json:"write_timeout_seconds"` IdleTimeoutSeconds int `json:"idle_timeout_seconds"` DisableStartupMessage bool `json:"disable_startup_message"` Auth AuthConfig `json:"auth"` Mail MailConfig `json:"mail"` RolesConfigPath string `json:"roles_config_path"` } type AuthConfig struct { Secret string `json:"secret"` Issuer string `json:"issuer"` AccessTokenExpiryMinutes int `json:"access_token_expiry_minutes"` RefreshTokenExpiryMinutes int `json:"refresh_token_expiry_minutes"` } type MailConfig struct { Mode string `json:"mode"` From string `json:"from"` DebugDir string `json:"debug_dir"` TemplatesDir string `json:"templates_dir"` FrontendBaseURL string `json:"frontend_base_url"` ResetPasswordPath string `json:"reset_password_path"` SMTP SMTPMailConfig `json:"smtp"` } type SMTPMailConfig struct { Host string `json:"host"` Port int `json:"port"` Username string `json:"username"` Password string `json:"password"` } func LoadConfig(path string) (ServerConfig, error) { data, err := os.ReadFile(path) if err != nil { return ServerConfig{}, fmt.Errorf("read config: %w", err) } var cfg ServerConfig if err := json.Unmarshal(data, &cfg); err != nil { return ServerConfig{}, fmt.Errorf("parse config: %w", err) } if cfg.Auth.Secret == "" { return ServerConfig{}, fmt.Errorf("auth.secret must be set") } if cfg.Auth.AccessTokenExpiryMinutes <= 0 { return ServerConfig{}, fmt.Errorf("auth.access_token_expiry_minutes must be greater than zero") } if cfg.Auth.RefreshTokenExpiryMinutes <= 0 { return ServerConfig{}, fmt.Errorf("auth.refresh_token_expiry_minutes must be greater than zero") } if cfg.Mail.Mode == "" { cfg.Mail.Mode = "file" } if cfg.Mail.TemplatesDir == "" { cfg.Mail.TemplatesDir = "internal/http/templates" } if cfg.Mail.ResetPasswordPath == "" { cfg.Mail.ResetPasswordPath = "/#reset-password" } if cfg.Mail.Mode != "smtp" && cfg.Mail.Mode != "file" { return ServerConfig{}, fmt.Errorf("mail.mode must be either smtp or file") } if cfg.Mail.From == "" { return ServerConfig{}, fmt.Errorf("mail.from must be set") } if cfg.Mail.Mode == "smtp" { if cfg.Mail.SMTP.Host == "" { return ServerConfig{}, fmt.Errorf("mail.smtp.host must be set when mail.mode=smtp") } if cfg.Mail.SMTP.Port <= 0 { return ServerConfig{}, fmt.Errorf("mail.smtp.port must be greater than zero when mail.mode=smtp") } } else if cfg.Mail.DebugDir == "" { cfg.Mail.DebugDir = "data/mail-debug" } return cfg, nil }