Files
mygo/internal/config/config.go
Huxley c0c34eb914 Change JWT TTL config from duration to string for flexibility
- The mapstructure library is no longer needed for direct duration
  parsing since we now store TTLs as string durations (e.g., "15m",
  "168h") and parse them on demand via helper methods.
- This allows more flexible duration formats in configuration and moves
  the parsing responsibility to the JWT config struct itself.
2026-04-27 17:15:16 +08:00

85 lines
2.0 KiB
Go

package config
import (
"errors"
"fmt"
"net"
"time"
)
type Config struct {
Server ServerConfig `mapstructure:"server"`
Database DatabaseConfig `mapstructure:"database"`
Storage StorageConfig `mapstructure:"storage"`
JWT JWTConfig `mapstructure:"jwt"`
}
type ServerConfig struct {
Host string `mapstructure:"host"`
Port int `mapstructure:"port"`
}
type DatabaseConfig struct {
Driver string `mapstructure:"driver"`
Path string `mapstructure:"path"`
}
type StorageConfig struct {
Driver string `mapstructure:"driver"`
Local LocalStorageConfig `mapstructure:"local"`
}
type LocalStorageConfig struct {
Path string `mapstructure:"path"`
}
type JWTConfig struct {
Secret string `mapstructure:"secret"`
AccessTTL string `mapstructure:"access_ttl"`
RefreshTTL string `mapstructure:"refresh_ttl"`
}
func (j JWTConfig) AccessDuration() time.Duration {
d, _ := time.ParseDuration(j.AccessTTL)
return d
}
func (j JWTConfig) RefreshDuration() time.Duration {
d, _ := time.ParseDuration(j.RefreshTTL)
return d
}
func (c *Config) Validate() error {
var errs []error
if c.Server.Port < 1 || c.Server.Port > 65535 {
errs = append(errs, fmt.Errorf("server.port: %d out of range [1, 65535]", c.Server.Port))
}
if addr := net.ParseIP(c.Server.Host); c.Server.Host != "" && addr == nil {
errs = append(errs, fmt.Errorf("server.host: %q is not a valid IP address", c.Server.Host))
}
if c.Database.Path == "" {
errs = append(errs, errors.New("database.path: must not be empty"))
}
if c.Storage.Local.Path == "" {
errs = append(errs, errors.New("storage.local.path: must not be empty"))
}
if c.JWT.Secret == "" {
errs = append(errs, errors.New("jwt.secret: must not be empty"))
}
if _, err := time.ParseDuration(c.JWT.AccessTTL); err != nil {
errs = append(errs, fmt.Errorf("jwt.access_ttl: %w", err))
}
if _, err := time.ParseDuration(c.JWT.RefreshTTL); err != nil {
errs = append(errs, fmt.Errorf("jwt.refresh_ttl: %w", err))
}
return errors.Join(errs...)
}