91 lines
2.1 KiB
Go
91 lines
2.1 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"log/slog"
|
|
"net"
|
|
"net/mail"
|
|
"strings"
|
|
)
|
|
|
|
// Validate reports whether cfg stores a usable Mail Service process
|
|
// configuration.
|
|
func (cfg Config) Validate() error {
|
|
switch {
|
|
case cfg.ShutdownTimeout <= 0:
|
|
return fmt.Errorf("%s must be positive", shutdownTimeoutEnvVar)
|
|
case cfg.AttemptWorkerConcurrency <= 0:
|
|
return fmt.Errorf("%s must be positive", attemptWorkerConcurrencyEnvVar)
|
|
case cfg.StreamBlockTimeout <= 0:
|
|
return fmt.Errorf("%s must be positive", streamBlockTimeoutEnvVar)
|
|
case cfg.OperatorRequestTimeout <= 0:
|
|
return fmt.Errorf("%s must be positive", operatorRequestTimeoutEnvVar)
|
|
case cfg.IdempotencyTTL <= 0:
|
|
return fmt.Errorf("%s must be positive", idempotencyTTLEnvVar)
|
|
}
|
|
|
|
if err := cfg.InternalHTTP.Validate(); err != nil {
|
|
return err
|
|
}
|
|
if err := cfg.Redis.Validate(); err != nil {
|
|
return err
|
|
}
|
|
if err := cfg.Postgres.Validate(); err != nil {
|
|
return fmt.Errorf("postgres: %w", err)
|
|
}
|
|
if err := cfg.Retention.Validate(); err != nil {
|
|
return err
|
|
}
|
|
if err := cfg.SMTP.Validate(); err != nil {
|
|
return err
|
|
}
|
|
if err := cfg.Templates.Validate(); err != nil {
|
|
return err
|
|
}
|
|
if err := cfg.Telemetry.Validate(); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func validateSlogLevel(level string) error {
|
|
var slogLevel slog.Level
|
|
if err := slogLevel.UnmarshalText([]byte(strings.TrimSpace(level))); err != nil {
|
|
return fmt.Errorf("invalid slog level %q: %w", level, err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func isTCPAddr(value string) bool {
|
|
host, port, err := net.SplitHostPort(strings.TrimSpace(value))
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
if port == "" {
|
|
return false
|
|
}
|
|
|
|
if host == "" {
|
|
return true
|
|
}
|
|
|
|
return !strings.Contains(host, " ")
|
|
}
|
|
|
|
func validateMailbox(name string, value string) error {
|
|
trimmed := strings.TrimSpace(value)
|
|
if trimmed == "" {
|
|
return fmt.Errorf("%s must not be empty", name)
|
|
}
|
|
|
|
parsed, err := mail.ParseAddress(trimmed)
|
|
if err != nil || parsed == nil || parsed.Name != "" || parsed.Address != trimmed {
|
|
return fmt.Errorf("%s %q must be a single valid email address", name, value)
|
|
}
|
|
|
|
return nil
|
|
}
|