- fix: The AccessTTL and RefreshTTL fields in JWTConfig now use time.Duration type directly instead of string with ParseDuration methods. The config validation now checks for positive durations rather than parsing strings.
107 lines
2.9 KiB
Go
107 lines
2.9 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"`
|
|
SQLite SQLiteConfig `mapstructure:"sqlite"`
|
|
Postgres PostgresConfig `mapstructure:"postgres"`
|
|
}
|
|
|
|
type SQLiteConfig struct {
|
|
Path string `mapstructure:"path"`
|
|
}
|
|
|
|
type PostgresConfig struct {
|
|
Host string `mapstructure:"host"`
|
|
Port int `mapstructure:"port"`
|
|
User string `mapstructure:"user"`
|
|
Password string `mapstructure:"password"`
|
|
DBName string `mapstructure:"dbname"`
|
|
SSLMode string `mapstructure:"sslmode"`
|
|
}
|
|
|
|
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 time.Duration `mapstructure:"access_ttl"`
|
|
RefreshTTL time.Duration `mapstructure:"refresh_ttl"`
|
|
}
|
|
|
|
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))
|
|
}
|
|
|
|
switch c.Database.Driver {
|
|
case "sqlite3":
|
|
if c.Database.SQLite.Path == "" {
|
|
errs = append(errs, errors.New("database.sqlite.path: must not be empty"))
|
|
}
|
|
case "postgres":
|
|
if c.Database.Postgres.Host == "" {
|
|
errs = append(errs, errors.New("database.postgres.host: must not be empty"))
|
|
}
|
|
if c.Database.Postgres.Port < 1 || c.Database.Postgres.Port > 65535 {
|
|
errs = append(errs, fmt.Errorf("database.postgres.port: %d out of range [1, 65535]", c.Database.Postgres.Port))
|
|
}
|
|
if c.Database.Postgres.User == "" {
|
|
errs = append(errs, errors.New("database.postgres.user: must not be empty"))
|
|
}
|
|
if c.Database.Postgres.DBName == "" {
|
|
errs = append(errs, errors.New("database.postgres.dbname: must not be empty"))
|
|
}
|
|
default:
|
|
errs = append(errs, fmt.Errorf("database.driver: %q is not supported (use sqlite3 or postgres)", c.Database.Driver))
|
|
}
|
|
|
|
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 c.JWT.AccessTTL <= 0 {
|
|
errs = append(errs, errors.New("jwt.access_ttl: must be positive"))
|
|
}
|
|
|
|
if c.JWT.RefreshTTL <= 0 {
|
|
errs = append(errs, errors.New("jwt.refresh_ttl: must be positive"))
|
|
}
|
|
|
|
return errors.Join(errs...)
|
|
}
|