139 lines
3.8 KiB
Go
139 lines
3.8 KiB
Go
package app
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/b1tsblog/license-platform/pkg/licensekit"
|
|
)
|
|
|
|
type Config struct {
|
|
ListenAddress string
|
|
BaseURL string
|
|
OutputBaseURL string
|
|
PublicName string
|
|
ContactURL string
|
|
DefaultLanguage string
|
|
TrustProxy bool
|
|
ServiceMode string
|
|
BulkMaxItems int
|
|
BulkMaxBodyBytes int64
|
|
BulkRequireAPIKey bool
|
|
BulkAPIKey string
|
|
APIAllowedOrigin string
|
|
RequireLicense bool
|
|
WhiteLabel bool
|
|
|
|
LicenseToken string
|
|
LicenseMode licensekit.VerificationMode
|
|
LicenseServerURL string
|
|
LicenseInstanceID string
|
|
LicenseCacheFile string
|
|
LicenseRefreshEvery time.Duration
|
|
LicenseTimeout time.Duration
|
|
}
|
|
|
|
func ConfigFromEnv() Config {
|
|
contactURL := env("CONTACT_URL", "https://b1tsblog.org/page/ai")
|
|
baseURL := strings.TrimRight(env("BASE_URL", "http://localhost:8080"), "/")
|
|
mode, err := licensekit.ParseMode(env("LICENSE_MODE", "offline"))
|
|
if err != nil {
|
|
mode = licensekit.ModeOffline
|
|
}
|
|
return Config{
|
|
ListenAddress: env("LISTEN_ADDRESS", ":8080"),
|
|
BaseURL: baseURL,
|
|
OutputBaseURL: strings.TrimRight(env("OUTPUT_BASE_URL", baseURL), "/"),
|
|
PublicName: env("PUBLIC_NAME", "AI Usage Disclosure"),
|
|
ContactURL: contactURL,
|
|
DefaultLanguage: env("DEFAULT_LANGUAGE", "de"),
|
|
TrustProxy: strings.EqualFold(env("TRUST_PROXY", "false"), "true"),
|
|
ServiceMode: serviceModeEnv("SERVICE_MODE", "full"),
|
|
BulkMaxItems: intEnv("BULK_MAX_ITEMS", 500),
|
|
BulkMaxBodyBytes: int64(intEnv("BULK_MAX_BODY_BYTES", 4<<20)),
|
|
BulkRequireAPIKey: strings.EqualFold(env("BULK_REQUIRE_API_KEY", "false"), "true"),
|
|
BulkAPIKey: secretEnv("BULK_API_KEY"),
|
|
APIAllowedOrigin: envAllowEmpty("API_ALLOWED_ORIGIN", "*"),
|
|
RequireLicense: strings.EqualFold(env("REQUIRE_LICENSE", "false"), "true"),
|
|
WhiteLabel: strings.EqualFold(env("WHITE_LABEL", "false"), "true"),
|
|
|
|
LicenseToken: secretEnv("LICENSE_TOKEN"),
|
|
LicenseMode: mode,
|
|
LicenseServerURL: strings.TrimRight(env("LICENSE_SERVER_URL", ""), "/"),
|
|
LicenseInstanceID: env("LICENSE_INSTANCE_ID", ""),
|
|
LicenseCacheFile: env("LICENSE_CACHE_FILE", "./data/license-lease.json"),
|
|
LicenseRefreshEvery: durationEnv("LICENSE_REFRESH_INTERVAL", 15*time.Minute),
|
|
LicenseTimeout: durationEnv("LICENSE_REQUEST_TIMEOUT", 5*time.Second),
|
|
}
|
|
}
|
|
|
|
func env(key, fallback string) string {
|
|
if value := strings.TrimSpace(os.Getenv(key)); value != "" {
|
|
return value
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func envAllowEmpty(key, fallback string) string {
|
|
value, ok := os.LookupEnv(key)
|
|
if !ok {
|
|
return fallback
|
|
}
|
|
return strings.TrimSpace(value)
|
|
}
|
|
|
|
func secretEnv(key string) string {
|
|
if value := strings.TrimSpace(os.Getenv(key)); value != "" {
|
|
return value
|
|
}
|
|
path := strings.TrimSpace(os.Getenv(key + "_FILE"))
|
|
if path == "" {
|
|
return ""
|
|
}
|
|
data, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return strings.TrimSpace(string(data))
|
|
}
|
|
|
|
func durationEnv(key string, fallback time.Duration) time.Duration {
|
|
value := strings.TrimSpace(os.Getenv(key))
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
if duration, err := time.ParseDuration(value); err == nil {
|
|
return duration
|
|
}
|
|
if seconds, err := strconv.ParseInt(value, 10, 64); err == nil {
|
|
return time.Duration(seconds) * time.Second
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func intEnv(key string, fallback int) int {
|
|
value := strings.TrimSpace(os.Getenv(key))
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
n, err := strconv.Atoi(value)
|
|
if err != nil || n <= 0 {
|
|
return fallback
|
|
}
|
|
return n
|
|
}
|
|
|
|
func serviceModeEnv(key, fallback string) string {
|
|
value := strings.ToLower(strings.TrimSpace(os.Getenv(key)))
|
|
switch value {
|
|
case "full", "api", "bulk":
|
|
return value
|
|
case "":
|
|
return fallback
|
|
default:
|
|
return fallback
|
|
}
|
|
}
|